[英]Arcing coords from A to B
我的目標是將圓弧的位置朝向鼠標光標的位置,這都是相對於通過畫布查看的世界而言的。 為了控制圓的移動速度,我決定使邊界大於圓,如果鼠標位於邊界之外,則將鼠標的“位置”移至邊界處,以便當我向圓弧方向移動時坐標,如果它們不在圓的位置以外,則不會以瘋狂的速度移動。 我有這個工作,這是做到這一點的代碼:
dx = Game.controls.mouseX - (this.x - xView); // get the distance between the x coords
dy = Game.controls.mouseY - (this.y - yView); // get the distance between the y coords
radii = this.radius + 1; // +1 because the "radius" of the mouse is 1
if((dx * dx) + (dy * dy) > radii * radii) // is the mouse not over the player?
{
if((dx * dx) + (dy * dy) < 301 * 301)
{
this.x += ((Game.controls.mouseX - (this.x - xView)) * 2 / (this.mass)) + step;
this.y += ((Game.controls.mouseY - (this.y - yView)) * 2 / (this.mass)) + step;
}
else
{
mx = Game.controls.mouseX;
my = Game.controls.mouseY;
do
{
dx = mx - (this.x - xView);
dy = my - (this.y - yView);
mx += (((this.x - xView) - mx) * 2 / (this.mass)) + step;
my += (((this.y - yView) - my) * 2 / (this.mass)) + step;
} while((dx * dx) + (dy * dy) > 301 * 301)
this.x += ((mx - (this.x - xView)) * 2 / (this.mass)) + step;
this.y += ((my - (this.y - yView)) * 2 / (this.mass)) + step;
}
}
“超越邊界”的魔力在於做一會兒。 這是我能提出的最佳解決方案,我不能認為這是一個優雅或快速的解決方案,並且想知道應該采取什么正確的措施。
我不是藝術家,但希望這張圖片有助於說明我要實現的目標。 黑點是鼠標pos,黑圈是圓圈,紅圈是我指定的邊界。 我想獲得標有X的坐標。
您的問題是Circle線段碰撞檢測算法的特例? ,在這種情況下,B和C是相同的點,因此您可以將它們的中心點都使用。
該解決方案是用C語言給出的,但是它很容易轉換為JavaScript,只需將float
替換為var
,使用Math.sqrt()
等等。
哦,這里有一個JvaScript版本: 計算通過中心的圓和線的交點 ,這更合適:-)
如果黑色圓圈在紅色圓圈的中心,並且您具有紅色圓圈的半徑
// c is circle center
// mouse is the mouse position. Should have properties x,y
// radius is the circle radius;
// returns the point on the line where the circle intercepts it else it returns undefined.
function findX(c, mouse, radius)
var v = {};
// get the vector to the mouse
v.x = mouse.x - c.x;
v.y = mouse.y - c.y;
var scale = radius / Math.hypot(v.x,v.y);
if(scale < 1){ // is it outside the circle
return {
x : c.x + v.x * scale,
y : c.y + v.y * scale
};
}
return;
}
如果線的起點不是中心,則通用的線圓截距功能將解決該問題。 如果直線在圓內開始,該函數將僅返回一點。 如果行不夠長,它將返回一個空數組。
// p1,p2 are the start and end points of a line
// returns an array empty if no points found or one or two points depending on the number of intercepts found
// If two points found the first point in the array is the point closest to the line start (p1)
function circleLineIntercept(circle,radius,p1,p2){
var v1 = {};
var v2 = {};
var ret = [];
var u1,u2,b,c,d;
// line as vector
v1.x = p2.x - p1.x;
v1.y = p2.y - p1.y;
// vector to circle center
v2.x = p1.x - circle.x;
v2.y = p1.y - circle.y;
// dot of line and circle
b = (v1.x * v2.x + v1.y * v2.y) * -2;
// length of line squared * 2
c = 2 * (v1.x * v1.x + v1.y * v1.y);
// some math to solve the two triangles made by the intercept points, the circle center and the perpendicular line to the line.
d = Math.sqrt(b * b - 2 * c * (v2.x * v2.x + v2.y * v2.y - radius * radius));
// will give a NaN if no solution
if(isNaN(d)){ // no intercept
return ret;
}
// get the unit distance of each intercept to the line
u1 = (b - d) / c;
u2 = (b + d) / c;
// check the intercept is on the line segment
if(u1 <= 1 && u1 >= 0){
ret.push({x:line.p1.x + v1.x * u1, y : line.p1.y + v1.y * u1 });
}
// check the intercept is on the line segment
if(u2 <= 1 && u2 >= 0){
ret.push({x:line.p1.x + v1.x * u2, y : line.p1.y + v1.y * u2});
}
return ret;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.