AS3-在3D空间中创建可循环的随机路径

时间:2013-09-30 14:34:41

标签: actionscript-3 3d lookup bezier

我正在尝试通过使用3d点(Vector 3D http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Vector3D.html)填充查找表来优化3D演示,稍后我将访问该表。

这些3D点将在3D空间中定义随机且可循环的路径。

有谁知道实现这一目标的方法?

我正在考虑修改Greensock Bezier补间以在3d空间中创建一个bezier,然后以某种方式获取生成的补间的xyz值。

1 个答案:

答案 0 :(得分:3)

好的,你需要做两件事:

  1. 从多个片段

  2. 创建一个循环的3D立方贝塞尔曲线
  3. 创建一个自定义补间函数,将您的对象作为目标,将bezier循环作为路径和总循环时间。

  4. 立方贝塞尔曲线的一个片段总是需要4个顶点,一个完整的循环必须包含至少2个段,因此您需要随机创建至少7个顶点。顶点的数量始终为3 * NumberOfSegments + 1,但我们将仅存储3 * NumberOfSegments,因为第一个顶点将等于最后一个顶点

    最简单的情况(2个段,6个顶点):

    ...
    private function generateRandomPoints():Vector<Vector3D>
    {
        var resultingVector:Vector<Vector3D> = new Vector<Vector3D>();
        for(var i:int = 0; i < 6; i++)
        {
            var x:Number = Math.random() * 10;
            var y:Number = Math.random() * 10;
            var z:Number = Math.random() * 10;
            var currentPoint3D:Vector3D = new Vector3D(x, y, z);
            resultingVector.push(currentPoint3D);
        }
        return resultingVector;
    }
    ...
    

    现在,当我们有了路径时,我们可以解析它以获得这种补间效果。您可以在每次需要新坐标时调用此函数(但您需要将初始时间存储在某处),或者创建一个可以为您处理所有内容的tweener对象。我将展示最基本的例子 - 自主功能:

    public static function getNextCoordinates(loopStartTime:int, totalLoopTime:int, path:Vector.<Vector3D>):Vector3D
        {
            var resultingPoint:Vector3D = new Vector3D();
            var passedTime:int = getTimer() - loopStartTime;
    
            //Total passed ratio
            var passedRatio:Number = passedTime / totalLoopTime;
            var totalSegments:int = path.length / 3;
    
            var totalTimePerSegment:Number = totalLoopTime / totalSegments;
    
            //So it can loop forever
            while (passedRatio > 1)
            {
                passedRatio -= 1;
            }
            //Let's find our current bezier curve segment number
            var currentSegment:int = Math.floor( passedRatio * totalSegments);
            var currentSegmentRatio:Number = (passedTime - currentSegment * totalTimePerSegment) / totalTimePerSegment;
            //It can be optimized here
            while (currentSegmentRatio > 1)
            {
                currentSegmentRatio -= 1;
            }
    
            var startingIndex:int = currentSegment * 3;
            //our four path vertices
            var point0:Vector3D = path[startingIndex];
            var point1:Vector3D = path[startingIndex + 1];
            var point2:Vector3D = path[startingIndex + 2];
    
            //if it's a last segment, we need to "connect" to the first vertex
            if (startingIndex + 3 >= path.length)
            {
                var point3:Vector3D = path[0];
            }
            else
            {
                point3 = path[startingIndex + 3];
            }
            //At last, we find our coordinates
            var tempRatio:Number = 1 - currentSegmentRatio;
            resultingPoint.x = tempRatio * tempRatio * tempRatio * point0.x + 3 * tempRatio * tempRatio * currentSegmentRatio * point1.x + 3 * tempRatio * currentSegmentRatio * currentSegmentRatio * point2.x + currentSegmentRatio * currentSegmentRatio * currentSegmentRatio * point3.x;
            resultingPoint.y = tempRatio * tempRatio * tempRatio * point0.y + 3 * tempRatio * tempRatio * currentSegmentRatio * point1.y + 3 * tempRatio * currentSegmentRatio * currentSegmentRatio * point2.y + currentSegmentRatio * currentSegmentRatio * currentSegmentRatio * point3.y;
            resultingPoint.z = tempRatio * tempRatio * tempRatio * point0.z + 3 * tempRatio * tempRatio * currentSegmentRatio * point1.z + 3 * tempRatio * currentSegmentRatio * currentSegmentRatio * point2.z + currentSegmentRatio * currentSegmentRatio * currentSegmentRatio * point3.z;
    
            return resultingPoint;
        }
    

    您可以将此函数扩展为补间对象的一部分。 我已经在2D空间中对它进行了测试,它完美地沿着随机多段贝塞尔曲线循环精灵的运动

    干杯!