actionscript-3 - 将 MovieClip 拖动到一个圆圈

标签 actionscript-3 trigonometry

...嗯,到一个不完整的圈子。

我有一个看起来像这样的可拖动 slider :Arc Slider

蓝色条的实例名称为 track粉色圆点的实例名称为 puck .

我需要将冰球始终限制在蓝色区域内,这就是我的数学失败对我不利的地方!到目前为止,我让冰球沿 x 轴移动,如下所示:

private function init():void
{
    zeroPoint = track.x + (track.width/2);
    puck.x = zeroPoint-(puck.width/2);
    puck.buttonMode = true;
    puck.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
}

private function onMouseDown(evt:MouseEvent):void
{
    this.stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
    this.stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
}

private function onMouseUp(evt:MouseEvent):void
{
    this.stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
}

private function onMouseMove(evt:MouseEvent):void
{
    puck.x = mouseX-(puck.width/2);
    //need to plot puck.y using trig magic...
}

我目前的想法是我可以使用不完整圆的半径(50)和相对于弧顶的mouseX来计算三角形,然后我可以从那里计算出所需的y位置。问题是,我正在阅读各种三角学网站,但仍然不知道从哪里开始。有人可以解释一下我需要做什么,就像对 child 说话一样吗?

编辑:圆圈被打破的事实应该不是问题,我可以轻松地将每个方向的运动限制在一定的度数上,它首先获得了我无法绕开的度数!

编辑2:我正在尝试遵循 Bosworth99 的回答,这是我想出的用于计算弧度以放入他的函数的函数:
private function getRadian():Number
{
    var a:Number = mouseX - zeroPoint;
    var b:Number = 50;
    var c:Number = Math.sqrt((a^2)+(b^2));
    return c;
}

最佳答案

如我所见,您解决的问题是在圆上找到最近的点。谷歌有很多关于这个主题的建议。

您可以通过首先检测鼠标位置和圆心之间的角度来优化它。为此使用 Math.atan2()。如果角度在间隙范围内,只需选择最近的端点:左或右。

编辑1 这是此策略的完整示例。

希望有帮助。

import flash.geom.Point;
import flash.events.Event;
import flash.display.Sprite;

var center:Point = new Point(200, 200);
var radius:uint = 100;

var degreesToRad:Number = Math.PI/180;

// gap angles. degrees are used here just for the sake of simplicity.
// what we use here are stage angles, not the trigonometric ones.
var gapFrom:Number = 45; // degrees
var gapTo:Number = 135; // degrees

// calculate endpoints only once

var endPointFrom:Point = new Point();
endPointFrom.x = center.x+Math.cos(gapFrom*degreesToRad)*radius;
endPointFrom.y = center.y+Math.sin(gapFrom*degreesToRad)*radius;

var endPointTo:Point = new Point();
endPointTo.x = center.x+Math.cos(gapTo*degreesToRad)*radius;
endPointTo.y = center.y+Math.sin(gapTo*degreesToRad)*radius;

// just some drawing
graphics.beginFill(0);
graphics.drawCircle(center.x, center.y, radius);
graphics.moveTo(center.x, center.y);
graphics.lineTo(endPointFrom.x, endPointFrom.y);
graphics.lineTo(endPointTo.x, endPointTo.y);
graphics.lineTo(center.x, center.y);
graphics.endFill();

// something to mark the closest point
var marker:Sprite = new Sprite();
marker.graphics.lineStyle(20, 0xFF0000);
marker.graphics.lineTo(0, 1);
addChild(marker);

var onEnterFrame:Function = function (event:Event) : void
{
    // circle intersection goes here
    var mx:int = stage.mouseX;
    var my:int = stage.mouseY;

    var angle:Number = Math.atan2(center.y-my, center.x-mx);
    // NOTE: in flash rotation is increasing clockwise, 
    // while in trigonometry angles increase counter clockwise
    // so we handle this difference
    angle += Math.PI;

    // calculate the stage angle in degrees
    var clientAngle:Number = angle/Math.PI*180

    // check if we are in a gap
    if (clientAngle >= gapFrom && clientAngle <= gapTo) {
        // we are in a gap, no sines or cosines needed
        if (clientAngle-gapFrom < (gapTo-gapFrom)/2) {        
            marker.x = endPointFrom.x;
            marker.y = endPointFrom.y;
        } else {
            marker.x = endPointTo.x;
            marker.y = endPointTo.y;
        }
        // we are done here
        return;
    }

    // we are not in a gp, calculate closest position on a circle
    marker.x = center.x + Math.cos(angle)*radius;
    marker.y = center.y + Math.sin(angle)*radius;
}
addEventListener(Event.ENTER_FRAME, onEnterFrame);

编辑2 一些链接

以下是一些常见问题,以清晰简洁的方式解释和解决:http://paulbourke.net/geometry/这个资源在很多天前帮助了我。

直线和圆的交点在这里有点矫枉过正,但这里是:http://paulbourke.net/geometry/sphereline/

关于actionscript-3 - 将 MovieClip 拖动到一个圆圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6509716/

相关文章:

math - 如何找到反射光线的角度以匹配一个点

ios - 适用于 iOS 的 AS3 DatePicker Air

actionscript-3 - Flash AS3和Base64库=编译错误

gcc 和 math.h 的 C 链接器错误

audio - 使用 SDL 库播放使用 sinf 函数生成的原始正弦波

正弦波生成的C编程

python - 绘制和更新车速表指针

javascript - Animate CC 中的 CreateJS JavasScript 框架脚本

actionscript-3 - 是否有支持 Socket.outputProgress 上传的 HTTP 客户端?

apache-flex - Flex Date() 构造函数错误地转换了 Unix 时间戳 argh