2016-06-20 8 views
0

То, что я намереваюсь сделать, - это положение круга в направлении положения курсора мыши, это все относительно мира, просматриваемого через холст. Чтобы сохранить ручку скорости, с которой перемещался круг, я решил сделать границу больше круга, если мышь находится за пределами границы, тогда «позиция» мыши доведена до границы, так что, когда я приближаюсь к coords, если они arent сверх далеки от положения круга он не движется на сумасшедших скоростях. У меня есть эта работа, и это код, который делает это:Аркирующие координаты от 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; 
     } 
    } 

Магия для «вне границы» лежит во времени. Это лучшее исправление, которое я мог бы придумать, и я не могу видеть это как элегантное или быстрое решение, и мне интересно, какой должен быть правильный курс действий.

Im художник, но, надеюсь, этот образ помогает проиллюстрировать то, чего я пытаюсь достичь. Черная точка - это мышь, черный круг - круг, а красный круг - это граница, которую я указал. Я хочу, чтобы получить COORDS ознаменовались X. enter image description here

+0

Только боковое примечание, о котором я забыл упомянуть, это делается полностью в javascript. – Rhexis

+0

Вам нужно найти координату точки в круге заданного радиуса (заданную координату центра и мыши)? – MBo

ответ

3

Ваш вопрос является частным случаем Circle line-segment collision detection algorithm?, в данном случае с В и С брались те же точки, так что вы можете использовать центральную точку для обоих из них.

Это решение дается в C, но это приводит к JavaScript очень легко, просто заменить float с var, используйте Math.sqrt() и так далее ...

О, и затем есть версия JvaScript здесь: Calculate the point of intersection of circle and line through the center, что более уместно :-)

+0

Похоже, это может быть идеально, мне просто нужно изменить его, чтобы быть точкой, а не прямой? (установите для начала и конца строки то же значение, в этом случае мышь pos) – Rhexis

+1

Нет, вы неправильно поняли. Конечными точками линии являются центр окружности и мышь. Ваш крест - это пересечение этой линии с красным кружком. –

+0

Ах, правильно! Моя ошибка, я понимаю сейчас. Я тоже работаю, спасибо большое! Im немного медленный прямо сейчас, его почти 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; 
} 

и если т он старт линии не является центром, тогда функция перехвата линии круга общего назначения решит проблему. Если линия начинается внутри круга, функция вернет только одну точку. Если линия не достаточно длинная, она вернет пустой массив.

// 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; 
    } 
Смежные вопросы