2016-06-20 4 views
0

私がしようとしているのは、マウスカーソルの位置に向かう円の位置です。これは、キャンバスを通して見た世界に関連しています。円が動く速度にハンドルを当てるために、私は円より大きな境界を作ることにしました。もしマウスが境界の外にあれば、マウスの "位置"が境界に持ち込まれます。彼らが円の位置からはるか遠くにいなければ、それは狂ったスピードで動かない。私はこれが働いており、これはそれを行うコードです:Aから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; 
     } 
    } 

「境界の外側」の魔法はdoの中にあります。これは私が思いつくことができる最高の修正であり、私はこれをエレガントで速い解決策と見なすことはできません。

Imアーティストはいませんが、この画像は私が達成しようとしていることを説明するのに役立ちます。黒い点はマウスの位置、黒い円は円、赤い円は私が指定した境界です。私はあなたがそれらの両方のためにあなたの中心点を使用できるように enter image description here

+0

これは完全にjavascriptで行われています。 – Rhexis

+0

指定された半径の円(中心とマウスの座標を指定)の点座標を見つける必要はありますか? – MBo

答えて

3

あなたの質問は、BとCが同じ点であることと、この場合には、Circle line-segment collision detection algorithm?の特殊なケースであるcoordsのがXでマークを取得したいと思います。

溶液をCに与えられたが、それは非常に簡単にJavaScriptに変換し、ちょうどそうに、varfloatを置き換えるMath.sqrt()を使用している...

ああ、その後、ここでJvaScriptバージョンがあります:Calculate the point of intersection of circle and line through the centerは、黒丸は、赤い円の中心にある場合、それはより適切な:-)

+0

これは完璧かもしれないようですが、私はちょうどラインの代わりにポイントにそれを修正する必要がありますか? (行の先頭と末尾を同じ値に設定します。この場合マウスの位置) – Rhexis

+1

誤解はありません。線の終点は円の中心とマウスです。十字架はこの線と赤い円の交点です。 –

+0

ああ!私の間違い、私は今理解する。私はあまりにもありがとう、ありがとう!今はちょっと遅いんだけど、午前5時ごろ。 – Rhexis

0

だとあなたは、赤い円の半径

// 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; 
} 

とT場合があります彼はラインの開始は、一般的なラインサークルの傍受機能は、問題を解決する中心ではないです。円が円の内側から始まる場合、関数はただ1つの点を返します。行の長さが足りない場合は空の配列を返します。

// 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; 
    } 
関連する問題