加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

flash – As3用于在样条曲线或Hermite曲线上外推点的函数,类似于

发布时间:2020-12-15 19:48:13 所属栏目:百科 来源:网络整理
导读:我希望有人可以帮我制作一些高级数据重新格式化.我希望的是一个函数,我可以输入一个值以及一系列关键位置,如下所示: function remap(percentage:Number,keypoints:Array) { ... 数组以最小值开始,以最大点结束,沿途有嵌套关键点.例如,我会输入像重映射(0.25
我希望有人可以帮我制作一些高级数据重新格式化.我希望的是一个函数,我可以输入一个值以及一系列关键位置,如下所示:

function remap(percentage:Number,keypoints:Array) { ...

数组以最小值开始,以最大点结束,沿途有嵌套关键点.例如,我会输入像重映射(0.25,[0:0,80:50,100:100])这样的函数,并且该函数将“想象”来自(0,0) – (100,100)的样条曲线图,其关键点为(80,50),然后返回该图表中25%的y值.

希望这很明确……任何想法?

解决方法

Hermite曲线的等式是这样的:

(通过Wikipedia)

其中p(t)是t处曲线上的点(百分比0.0到1.0)

> p0是第一个控制点
> m0是第一个锚点
> p1是第二个控制点
> m1是第二个控制点

因此,actionscript中的等式将是这样的:

/*
         * Computes x,y values for a given traversal of a Hermite Curve
         * @param t:Number - a normalized value (0.0 to 1.0) describing path traversal
         * @param points:Array - an array contining the 4 points describing the curve (P0,T0,P1,T1 - always in this order)
         * Anchor points are relative to they're control points
         */
        private function hermite(t:Number,points:Array):Point{
            var result:Point = new Point();
            result.x = (2 * Math.pow(t,3) - 3 * t * t + 1) * points[0].x+
                        (Math.pow(t,3) - 2 * t * t + t) * points[1].x + 
                        (- 2 * Math.pow(t,3) + 3*t*t) * points[2].x +
                        ( Math.pow(t,3) - t*t) * points[3].x;
            result.y = (2 * Math.pow(t,3) - 3 * t * t + 1) * points[0].y+
                        (Math.pow(t,3) - 2 * t * t + t) * points[1].y + 
                        (- 2 * Math.pow(t,3) + 3*t*t) * points[2].y +
                        ( Math.pow(t,3) - t*t) * points[3].y;
            return result;
        }

你可以看到一个基本的演示here

不过,我有点担心,因为你的例子提到3分(2个控制点和一个锚点).

立方曲线(Hermite / Catmull-Rom /等)有2个控制点和2个锚点(功率为3的方程式 – 立方)

如果您只需要一个控制点,则需要使用Quadratic Curve:

(来自Adobe Actionscript 3文档的图像)

立方曲线:

二次曲线:

(来自维基百科的动画)

二次方程是这样的:

哪个会转换为:

private function quad(t:Number,p:Array):Point{
            var result:Point = new Point();
            var oneMinusTSq:Number = (1-t) * (1-t);
            var TSq:Number = t*t;
            result.x = oneMinusTSq*p[0].x+2*(1-t)*t*p[1].x+TSq*p[2].x;
            result.y = oneMinusTSq*p[0].y+2*(1-t)*t*p[1].y+TSq*p[2].y;
            return result;
        }

还有一些测试代码:

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;

    /**
     * @author george
     */
    public class BasicQuad extends Sprite {
        private var p0:Point = new Point(0,0);
        private var p1:Point = new Point(80,50);
        private var p2:Point = new Point(100,100);
        private var pts:Array = [p0,p1,p2];
        private var t:Number = 0;
        private var pt : Point;

        public function BasicQuad() {
            init();
        }
        private function init():void{
            stage.doubleClickEnabled = true;
            stage.addEventListener(MouseEvent.DOUBLE_CLICK,reset);
            reset();
        }
        private function reset(event : MouseEvent = null) : void {
            graphics.clear();
            graphics.lineStyle(3,0x009900,.5);
            t = 0;
            this.addEventListener(Event.ENTER_FRAME,draw);
        }
        private function draw(event : Event) : void {
            trace(t,pt);
            pt = quad(t,pts);
            if(t == 0) graphics.moveTo(pt.x,pt.y);//draw
            graphics.lineTo(pt.x,pt.y);
            t+= 0.015;
            if(t >= 1) removeEventListener(Event.ENTER_FRAME,draw);//done
        }
        private function quad(t:Number,p:Array):Point{
            var result:Point = new Point();
            var oneMinusTSq:Number = (1-t) * (1-t);
            var TSq:Number = t*t;
            result.x = oneMinusTSq*p[0].x+2*(1-t)*t*p[1].x+TSq*p[2].x;
            result.y = oneMinusTSq*p[0].y+2*(1-t)*t*p[1].y+TSq*p[2].y;
            return result;
        }
    }
}

另外,我不清楚你的意思

advanced data reformatting

代码片段是作为代码编写的公式,但还有其他方法可以计算它.

A quadratic Bézier curve is the path traced by the function B(t),
given points P0,and P2,

我们需要从P0到P1,从P1到P2.
由于您正在寻找Flash / ActionScript解决方案,我们可以利用Point的interpolate()方法.
所以我们在P0和P1之间进行插值,让我们说P01
然后从P1到P2得到P12,通过所有3个点进行插值
P01和P12之间的插值:

function quadLerp(t:Number,p:Array):Point {
            var p1:Point = Point.interpolate(p[1],p[0],t);
            var p2:Point = Point.interpolate(p[2],p[1],t);
            return Point.interpolate(p2,t);
        }

由于动作脚本插值的实现方式,代码看起来有点倒退了:“两点之间的插值水平.指示新点的位置,沿着pt1和pt2之间的线.如果f = 1,返回pt1;如果f = 0,则返回pt2.“

UPDATE

进一步困惑:

In reference to your question: my example actually mentions 3 control
points and 0 anchor points

你试图简单地沿着一系列线(多个点,0个锚点……直线)得到当前x的y值?

Remember I dont need the graph itself – I just need a point on it
Simply walk on a straight line graph/jagged line(no curves whatsoever) ?

如果,那么,您可以这样做:

>遍历路径的所有点并找到当前x值的行(这将是起始x位置小于给定x的行,并且行的结束x位置大于给定的x位置)
>计算从行首开始到给定x的x距离与整行(end.x-start.x)之间的比率
>使用此比率划分当前行’height'(end.y和start.y之间的差异)并将其偏移start.y,利用similar triangles,according to Thales’ Theorem

这是一个快速草图来说明这个想法:

想象一个直角三角形,其中当前行是连字符(ABC).现在想象一下你的鼠标光标的垂直线将该三角形分成两个相似的三角形(OO’).小三角形与大角形具有相同的角度,并且它的边是成比例的.使用AO和AB之间的比率来划分AC,并获得OO’的长度(该x的线上的y位置).

这是功能:

private function getYforX(x:Number,pts:Vector.<Point>):Number{
            var numPts:int = pts.length;
            for (var i : int = 1; i < numPts; i++) {
                if(x > pts[i-1].x && x < pts[i].x) {//find the line on which the cursor lies
                    t = (x-pts[i-1].x)/(pts[i].x-pts[i-1].x);//ratio between the x distance from the start of the line to mouseX and the whole line (end.x-start.x)
                    return pts[i-1].y + ((pts[i].y-pts[i-1].y) * t);//Thales similar triangles version,cheaper version of Point.interpolate(pts[i],pts[i-1],t).y; 
                }
            }
            return -1;
        }

并快速演示:

package {
    import flash.events.*;
    import flash.display.*;
    import flash.geom.Point;

    public class LerpPoints extends Sprite {

        private var path:Shape = new Shape();
        private var cursor:Shape = new Shape();
        private var numPts:int = 11;
        private var pts:Vector.<Point> = new Vector.<Point>(numPts,true);
        private var t:Number = 0;

        public function LerpPoints() {
            init();
        }
        private function init():void{
            cursor.graphics.lineStyle(10,0x009900);
            cursor.graphics.drawCircle(-3,-3,3);
            cursor.graphics.lineStyle(1,0x000099);
            cursor.graphics.moveTo(0,-stage.stageHeight);
            cursor.graphics.lineTo(0,stage.stageHeight);
            reset();
            addChild(path);addChild(cursor);
            addEventListener(Event.ENTER_FRAME,update);
            stage.addEventListener(MouseEvent.MOUSE_DOWN,reset);
        }
        private function reset(event:Event = null):void{
            path.graphics.clear();
            for (var i : int = 0; i < numPts; i++) {
                pts[i] = new Point(i*55,Math.random() * 200);//generate points
                path.graphics.lineStyle(3,0);
                if(i == 0) path.graphics.moveTo(pts[0].x,pts[0].y);//draw path
                path.graphics.lineTo(pts[i].x,pts[i].y);
                if(i > 0){//right angled triangles
                    path.graphics.lineStyle(1,0x990000);
                    path.graphics.lineTo(pts[i-1].x,pts[i].y);
                    path.graphics.lineTo(pts[i-1].x,pts[i-1].y);
                    path.graphics.moveTo(pts[i].x,pts[i].y);
                }
            }
        }
        private function update(event:Event):void{
            cursor.x = mouseX;
            cursor.y = getYforX(mouseX,pts);
        }
        private function getYforX(x:Number,t).y; 
                }
            }
            return -1;
        }
    }
}

请注意,如果点数组中的x值按升序排序(例如,您的路径仅从左到右),则此方法有效

想到的一个肮脏的黑客是循环遍历点对并将Y值存储在查找表中.循环次数应该是’线条细节’

然后,这让我感到困惑:

just need to to asses an array of points (not just 2) and ideally
spline curve them rather than simply joining the dots
So you have multiple points,but where does the spline come in,since you mentioned 0 anchor points ?

HTH

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读