AS3- 在 3D 空间中创建一个可循环的随机路径 [英] AS3- create a loopable random path in 3D space

查看:22
本文介绍了AS3- 在 3D 空间中创建一个可循环的随机路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过用 3d 点填充查找表来优化 3d 演示(矢量 3D http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Vector3D.html) 稍后我将访问

I'm trying to optimize a 3d demo by populating a lookup table with 3d points(Vector 3D http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Vector3D.html) which I will then access later on.

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

These 3D points will define a random and loopable path in 3D space.

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

Does anyone know a way of achieving this?

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

I was thinking modifying the Greensock Bezier tween to create a bezier in 3d space, and then somehow grabbing the xyz values of the resulting tween.

推荐答案

好的,你需要做两件事:

Ok, you'll need to do two things:

  1. 从几个片段创建一个循环的 3D 三次贝塞尔曲线

  1. Create a looped 3D cubic bezier curve from several fragments

创建一个自定义补间函数,它将您的对象作为目标,您的贝塞尔循环作为路径和您的总循环时间.

Create a custom tween function that will take your object as a target, your bezier loop as a path and your total loop time.

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

One fragment of your cubic bezier curve will always take 4 vertices, a full loop must contain at least 2 segments, so you will need to randomly create at least 7 vertices. The number of vertices will always be 3 * NumberOfSegments + 1, but we will store just 3 * NumberOfSegments as the first vertex will be equal to the last one

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

Most simple case (2 segments, 6 vertices):

...
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 对象来为您处理所有事情.我将展示最基本的例子 - 自治功能:

Now when we have our path, we can parse it to get this tweening effect. You can either call this function every time you'll need new coordinates (but you'll need to store your initial time somewhere), or create a tweener object that will handle everything for you. I'll show the most basic example - autonomous function:

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 空间中对其进行了测试,它沿着随机的多段贝塞尔曲线完美地循环了精灵的运动

You can extend this function to be a part of the tweening object. I've tested it in 2D space and it perfectly loops sprite's movement along a random multi-segment bezier curve

干杯!

这篇关于AS3- 在 3D 空间中创建一个可循环的随机路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆