Как найти перпендикулярную линию данной 2 точки? - PullRequest
0 голосов
/ 25 апреля 2020

Я пытаюсь нарисовать перпендикулярную линию на холсте во флаттере, после некоторого повторения моей математики мне не удалось внедрить формулу в мой код.

У меня есть точка p1 и точка p2, чтобы нарисовать прямая линия, sample image, но тогда мне нужно нарисовать перпендикулярную линию, которая проходит через p3 (ожидаемый результат похож на синюю линию на рисунке)

Сначала мой код - найти уравнение линии дается две точки ( p1 , p2 ). Ниже показано, как я нахожу m (наклон).

double x1=p1.x;
double x2=p2.x;
double y1=p1.y;
double y2=p2.y;

double m=(y2-y1)/(x2-x1);

И чтобы найти наклон для перпендикулярной линии, я пишу код, подобный приведенному ниже

//this code I expected to transform the previous m to negative reciprocal.
double invertedM = ( 1 / m ) * -1;

И тогда мне нужно найти новое c (y-точка пересечения) с моей третьей точкой p3 , чтобы сформировать новое линейное уравнение. И замените y1 = 0 и y2 = screeen_height, чтобы нарисовать перпендикулярную линию, проходящую через p3

double invertedC = p3.y / (invertedM * p3.x) ;

//get x give y = 0
qy1 = 0 ;
double findX1 = (qy1-invertedC)/invertedM;
Point answerPoint1 = Point(findX1,qy1);

//get x given y = screenheight
qy2 = screenheight ;
double findX2 = (qy2-invertedC)/invertedM;
Point answerPoint2 = Point(findX2,qy2);

Но каким-то образом результат, который я получаю, хотя и перпендикулярен, но не проходит через p3. wrong result

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

Я думаю, вы просто немного усложнили свою алгебру.

Наклон m линии p1-p2 определяется как:

m = (y2-y1)/(x2-x1)

Тогда уравнение линии, перпендикулярной p1-p2, проходящей через p3, составляет:

(y-y3)/(x-x3) = -1/m 

Перестановка дает:

x = (y3-y)*m + x3

Следовательно:

double findX1 = (p3.y-qy1)*m + p3.x;
double findX2 = (p3.y-qy2)*m + p3.x;

где qy1 = 0, qy2 = screenHeight, как в вашем коде.

Что происходит, когда p3 таков, что findX1 и / или findX2 меньше нуля или больше screenWidth? Затем вы хотите привязать линию влево или вправо?

0 голосов
/ 25 апреля 2020

Не так много ... просто основы c тригонометрия

class Shape {
  constructor(ctx, coord) {
    this.ctx = ctx;
    this.coord = coord;
    let v = {
      x: coord[1].x - coord[0].x,
      y: coord[1].y - coord[0].y
    }
    this.angle = Math.atan2(v.y, v.x)
  }

  drawLine(coord, color) {
    this.ctx.beginPath();
    this.ctx.moveTo(coord[0].x, coord[0].y);
    this.ctx.lineTo(coord[1].x, coord[1].y);
    this.ctx.strokeStyle = color;
    this.ctx.stroke();
  }

  draw(pos) {
    this.drawLine(this.coord, "black");

    var x = pos.x + 200 * Math.cos(this.angle + Math.PI / 2)
    var y = pos.y + 200 * Math.sin(this.angle + Math.PI / 2)
    this.drawLine([{x,y,}, pos], "red");
  }
}

function getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: evt.clientX - rect.left,
    y: evt.clientY - rect.top
  };
}

const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
shape = new Shape(ctx, [{x: 0,y: 50}, {x: 200,y: 100}])

shape.draw({x: 100,y: 0})
canvas.addEventListener('mousemove', function(evt) {
  var mousePos = getMousePos(canvas, evt);
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  shape.draw(mousePos);

}, false);
<canvas id="c" width=200 height=160 style="border:2px solid #a7a4a4;"></canvas>

Учитывая две точки, мы можем вычислить угол:
this.angle = Math.atan2(v.y, v.x)

Тогда, если мы добавим 90 градусов или в радианах (Math .PI / 2) это угол перпендикулярной линии.

В вопросе неясно, где должна быть перпендикулярная линия (p3), поэтому я сделал это относительно мыши, если вы запустите сниппет и наведете указатель мыши на холст, вы должны увидеть линию от мыши Положение вниз.

Я использовал HTML canvas, но то же самое можно применить к любому другому холсту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...