沿着正弦波移动和旋转物体

发布于 2024-11-10 05:31:21 字数 4066 浏览 3 评论 0原文

我遇到了几个问题 - 第一个是如何找到每个正弦曲线的尖端在哪里(即频率),第二个是如何旋转每个对象,以便它沿着正弦波横向滑动

(注意文件是 800 x 600)

这是我的代码: CarouselTest.as:CarouselItem.as

package  
{
    import com.greensock.easing.Sine;
    import com.greensock.TweenMax;
    import com.components.CarouselItem;
    import com.theflashblog.fp10.SimpleZSorter;
    import flash.display.Sprite;
    import flash.events.Event;
    import uk.co.thereceptacle.utils.Trig;

    public class CarouselTest extends Sprite 
    {
        public static const SPACING : int = 20;
        public static const XSPACING: int = SPACING * 5;
        public static const SPEED   : Number = .05;
        public static const XSPEED  : Number = 800 / 360 * 2;
        public static const RADIUS  : int = 400;

        private var _items:Array;
        private var _container:Sprite;
        private var _movePerItem:Number;
        private var _noOfItems:int;

        public function CarouselTest() 
        {
            _items = new Array();
            _noOfItems = 200;
            _movePerItem = 360 / _noOfItems; // my attempt at finding how much each item must move in order to bring it to the front

            _container = new Sprite();
            _container.x = 400;
            _container.y = 300;
            _container.z = 200;
            addChild(_container);

            var item:CarouselItem = new CarouselItem();
            for (var i:int = 0; i < _noOfItems; i++)
            {
                item = new CarouselItem();
                item.radius = RADIUS;
                item.angle = (i * SPACING) % 360;
                item.x = i * XSPACING - 300;
                item.speed = SPEED;
                _container.addChild(item);
                _items.push(item);
            }

            moveItems(-1 * _movePerItem);
        }

        private function moveItems(direction:int):void
        {
            TweenMax.allTo(_items, 5, { angle:direction.toString(), x:(direction * XSPACING).toString(), ease:Sine.easeInOut } );
            TweenMax.to(this, 5, { onUpdate:SimpleZSorter.sortClips, onUpdateParams:[_container] } );
        }
    }
}

帮忙

package com.components 
{
    import flash.display.Sprite;
    import flash.text.TextField;
    import uk.co.thereceptacle.components.HTMLTextField;
    import uk.co.thereceptacle.utils.Trig;

    public class CarouselItem extends Sprite
    {
        private var _angle  : Number;
        private var _prevX  : Number;
        private var _prevZ  : Number;

        public var speed    : int;
        public var radius   : Number;

        public function CarouselItem() 
        {
            graphics.beginFill(0x99ff00);
            graphics.lineStyle(1);
            graphics.drawRect( -100, -150, 200, 300);

            var tf:TextField = new HTMLTextField();
            tf.embedFonts = false;
            tf.wordWrap = false;
            tf.htmlText = "<p>THIS IS A TEST</p>";
            tf.x = -100;
            tf.y = -tf.textHeight / 2;
            addChild(tf);
        }

        public function get angle():Number { return _angle; }
        public function set angle(value:Number):void 
        {
            _angle = value;

            z = Math.sin(angle) * radius;

            var deltaX:Number = x - _prevX;
            var deltaZ:Number = z - _prevZ;
            var rotate:Number = Trig.radiansToDegrees(Math.atan2(deltaZ, deltaX));
            rotationY = rotate; <strike>// this is getting close but always rotates the item away from the center and i need it to rotate towards the center on the positive side of the sine wave</strike>
// edit: i've updated this as it's much closer but still flaky - it feels like i haven't done it right

        }

        override public function set x(value:Number):void 
        {
            _prevX = x;
            super.x = value;
        }

        override public function set z(value:Number):void 
        {
            _prevZ = z;
            super.z = value;
        }
    }
}

希望你能 奥比

There are a couple of problems i'm having with this - the first is how to work out how to find where the tip of each sine curve is (ie the frequency) and the second is to work out how to rotate each object so that it slides sideways along the sine wave

(note file is 800 x 600)

here's my code:
CarouselTest.as:

package  
{
    import com.greensock.easing.Sine;
    import com.greensock.TweenMax;
    import com.components.CarouselItem;
    import com.theflashblog.fp10.SimpleZSorter;
    import flash.display.Sprite;
    import flash.events.Event;
    import uk.co.thereceptacle.utils.Trig;

    public class CarouselTest extends Sprite 
    {
        public static const SPACING : int = 20;
        public static const XSPACING: int = SPACING * 5;
        public static const SPEED   : Number = .05;
        public static const XSPEED  : Number = 800 / 360 * 2;
        public static const RADIUS  : int = 400;

        private var _items:Array;
        private var _container:Sprite;
        private var _movePerItem:Number;
        private var _noOfItems:int;

        public function CarouselTest() 
        {
            _items = new Array();
            _noOfItems = 200;
            _movePerItem = 360 / _noOfItems; // my attempt at finding how much each item must move in order to bring it to the front

            _container = new Sprite();
            _container.x = 400;
            _container.y = 300;
            _container.z = 200;
            addChild(_container);

            var item:CarouselItem = new CarouselItem();
            for (var i:int = 0; i < _noOfItems; i++)
            {
                item = new CarouselItem();
                item.radius = RADIUS;
                item.angle = (i * SPACING) % 360;
                item.x = i * XSPACING - 300;
                item.speed = SPEED;
                _container.addChild(item);
                _items.push(item);
            }

            moveItems(-1 * _movePerItem);
        }

        private function moveItems(direction:int):void
        {
            TweenMax.allTo(_items, 5, { angle:direction.toString(), x:(direction * XSPACING).toString(), ease:Sine.easeInOut } );
            TweenMax.to(this, 5, { onUpdate:SimpleZSorter.sortClips, onUpdateParams:[_container] } );
        }
    }
}

CarouselItem.as

package com.components 
{
    import flash.display.Sprite;
    import flash.text.TextField;
    import uk.co.thereceptacle.components.HTMLTextField;
    import uk.co.thereceptacle.utils.Trig;

    public class CarouselItem extends Sprite
    {
        private var _angle  : Number;
        private var _prevX  : Number;
        private var _prevZ  : Number;

        public var speed    : int;
        public var radius   : Number;

        public function CarouselItem() 
        {
            graphics.beginFill(0x99ff00);
            graphics.lineStyle(1);
            graphics.drawRect( -100, -150, 200, 300);

            var tf:TextField = new HTMLTextField();
            tf.embedFonts = false;
            tf.wordWrap = false;
            tf.htmlText = "<p>THIS IS A TEST</p>";
            tf.x = -100;
            tf.y = -tf.textHeight / 2;
            addChild(tf);
        }

        public function get angle():Number { return _angle; }
        public function set angle(value:Number):void 
        {
            _angle = value;

            z = Math.sin(angle) * radius;

            var deltaX:Number = x - _prevX;
            var deltaZ:Number = z - _prevZ;
            var rotate:Number = Trig.radiansToDegrees(Math.atan2(deltaZ, deltaX));
            rotationY = rotate; <strike>// this is getting close but always rotates the item away from the center and i need it to rotate towards the center on the positive side of the sine wave</strike>
// edit: i've updated this as it's much closer but still flaky - it feels like i haven't done it right

        }

        override public function set x(value:Number):void 
        {
            _prevX = x;
            super.x = value;
        }

        override public function set z(value:Number):void 
        {
            _prevZ = z;
            super.z = value;
        }
    }
}

hope you can help
obie

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

開玄 2024-11-17 05:31:21

我假设您想要为起伏的山丘上的滑板(或海上的船,或具有类似运动的物体)等物体制作动画。

对于此问题,您需要了解的所有三角/微积分:以您想要的方式位于曲线上的线是切线。它由曲线的导数来描述。正弦曲线的导数是余弦。微积分魔法:如果你的曲线是 a*sin(b*x),则正切是 a*b*cos(b*x)。这给了你(起身/奔跑)。如果您希望将其表示为角度,则需要其 atan (或 atan2)。请注意,您需要与角度单位保持一致。最有可能的是 atan 给你弧度而你想要度数。

I assume you want to animate something like a skateboard on a rolling hill (or boat on seas, or something with similar motion).

All of the trig/calculus you need to know for this problem: The line sitting on a curve in the way you want is the tangent line. It is described by the derivative of the curve. The derivative of the sine curve is the cosine. Calculus magic: if your curve is a*sin(b*x), the tangent is a*b*cos(b*x). That gives you (rise/run). If you want this expressed as an angle, you will want the atan (or atan2) of that. Note, you will need to be consistent with your angle units. Most likely atan gives you radians and you want degrees.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文