......嗯,一个不完整的圆。
我有一个可拖动滑块,看起来像这样:
蓝色条具有实例名称跟踪
和粉红色的圆点有实例名称冰球
。
我需要的冰球要在蓝色区域在所有时间内的限制,而这正是我的数学工作的失败对我!到目前为止,我有冰球沿x轴移动仅是这样的:
私有函数的init():无效
{
zeroPoint = track.x +(track.width / 2);
puck.x = zeroPoint-(puck.width / 2);
puck.buttonMode =真;
puck.addEventListener(的MouseEvent.MOUSE_DOWN,onmousedown事件);
}
私有函数onmousedown事件(EVT:MouseEvent)方法:无效
{
this.stage.addEventListener(的MouseEvent.MOUSE_MOVE,的OnMouseMove);
this.stage.addEventListener(侦听MouseEvent.MOUSE_UP,onMouseUp);
}
私有函数onMouseUp(EVT:MouseEvent)方法:无效
{
this.stage.removeEventListener(的MouseEvent.MOUSE_MOVE,的OnMouseMove);
}
私有函数的OnMouseMove(EVT:MouseEvent)方法:无效
{
puck.x = mouseX-(puck.width / 2);
//需要使用触发魔法阴谋puck.y ...
}
我的思路是目前我可以使用不完全的圆(50)和mouseX相对的半径与弧顶计算三角形,并从那里我可以计算出所需的y位置。问题是,我读各种各样的三角点,仍然不知道从哪里开始。有人能解释什么,我需要做的仿佛在诉说着一个孩子好吗?
编辑:事实上,该圈被打破不应该是一个问题,我可以盖运动到一定度数在每个方向上很容易,它变得度摆在首位我不能让我的头周围!
EDIT2:我试图按照Bosworth99的答案,这是我想出来的计算弧度投入到自己的函数的函数:
私有函数getRadian():数
{
VAR一:数= mouseX - zeroPoint;
变种B:数= 50;
变种C:数=的Math.sqrt((A ^ 2)+(B ^ 2));
返回℃;
}
解决方案
在我看来,你解决问题的找到的最近点上圆的。谷歌有很多的建议,关于这个问题的。
您可以通过先检测鼠标位置和圆心之间的角度对其进行优化。使用Math.atan2()了点。如果角度在间隙范围内,只要选择最接近端点:左或右
EDIT1 以下是这一战略的一个完整的例子。
希望有所帮助。
进口flash.geom.Point;
进口对象类型:flash.events.Event;
进口flash.display.Sprite;
VAR中心:点=新的点(200,200);
VAR半径:UINT = 100;
VAR degreesToRad:数= Math.PI / 180;
//差距的角度。度在这里被用来只为简单起见。
//我们这里使用的是什么阶段的角度,而不是三角的。
VAR gapFrom:数= 45; //度
VAR gapTo:数= 135; //度
//只计算一次端点
VAR endPointFrom:点=新的点();
endPointFrom.x = center.x + Math.cos(gapFrom * degreesToRad)*半径;
endPointFrom.y = center.y + Math.sin(gapFrom * degreesToRad)*半径;
VAR endPointTo:点=新的点();
endPointTo.x = center.x + Math.cos(gapTo * degreesToRad)*半径;
endPointTo.y = center.y + Math.sin(gapTo * degreesToRad)*半径;
//只是一些图纸
graphics.beginFill(0);
graphics.drawCircle(center.x,center.y,半径);
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();
//一些标记的最近点
VAR标记:雪碧=新的Sprite();
marker.graphics.lineStyle(20,为0xFF0000);
marker.graphics.lineTo(0,1);
的addChild(标记);
VAR的onEnterFrame:功能=功能(事件:事件):无效
{
//圈交汇到这里
VAR MX:INT = stage.mouseX;
VAR我:INT = stage.mouseY;
VAR角度:数= Math.atan2(center.y-我,center.x-MX);
//注意:在Flash旋转顺时针增加,
//而在三角学的角度逆时针加大
//所以我们处理这种差异
角+ = Math.PI;
//计算度阶段角
VAR clientAngle:数=角/ Math.PI * 180
//检查,如果我们是在一个空白
如果(clientAngle> = gapFrom和放大器;&安培; clientAngle< = gapTo){
//我们是在一个缺口,无需正弦余弦或
如果(clientAngle-gapFrom≤(gapTo-gapFrom)/ 2){
marker.x = endPointFrom.x;
marker.y = endPointFrom.y;
} 其他 {
marker.x = endPointTo.x;
marker.y = endPointTo.y;
}
//我们在这里做
返回;
}
//我们不在一个GP,计算一个圆的最近距离
marker.x = center.x + Math.cos(角度)*半径;
marker.y = center.y + Math.sin(角度)*半径;
}
的addEventListener(Event.ENTER_FRAME,的onEnterFrame);
EDIT2 有些链接
下面是一些常见问题的解释和一个出色的清晰简明的方式解决: http://paulbourke.net/geometry/ 这个资源了很多天以前帮助过我。
直线和圆的交点是有点矫枉过正了这里,但在这里它是: http://paulbourke.net/几何/ sphereline /
...well, to an incomplete circle.
I have a draggable slider that looks like this:
The blue bar has the instance name track
and the pink dot has the instance name puck
.
I need the puck to be constrained within the blue area at all times, and this is where my maths failings work against me! So far I have the puck moving along the x axis only like this:
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...
}
My thinking is currently that I can use the radius of the incomplete circle (50) and the mouseX relative to the top of the arc to calculate a triangle, and from there I can calculate the required y position. Problem is, I'm reading various trigonometry sites and still have no idea where to begin. Could someone explain what I need to do as if speaking to a child please?
Edit: The fact that the circle is broken shouldn't be an issue, I can cap the movement to a certain number of degrees in each direction easily, it's getting the degrees in the first place that I can't get my head around!
Edit2: I'm trying to follow Bosworth99's answer, and this is the function I've come up with for calculating a radian to put into his function:
private function getRadian():Number
{
var a:Number = mouseX - zeroPoint;
var b:Number = 50;
var c:Number = Math.sqrt((a^2)+(b^2));
return c;
}
解决方案
As I see it, the problem you solve is finding the closest point on a circle. Google have a lot of suggestions on this subject.
You can optimise it by first detecting an angle between mouse position and circle center. Use Math.atan2() for that. If the angle is in a gap range, just choose the closest endpoint: left or right.
EDIT1 Here is a complete example of this strategy.
Hope that helps.
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);
EDIT2 Some links
Here are some common problems explained and solved in a brilliantly clear and concise manner: http://paulbourke.net/geometry/ This resource helped me a lot days ago.
Intersection of a line and a circle is a bit of an overkill here, but here it is: http://paulbourke.net/geometry/sphereline/