точка пересечения двух линий, один случай работает, другой нет - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть этот код https://codepen.io/octaviandd/pen/dyoaJVZ?editors=0010

По существу, многоугольник и линия, когда я перемещаю мышь и пересекаю весь многоугольник, мне нужно найти пересечение между линией и линии многоугольника (только левая сторона и правая сторона многоугольника). Я использую один и тот же алгоритм для левой и правой стороны, для левой стороны он работает, для правой - нет.

Левая сторона:

if (
    (positions.a1x === positions.a2x && positions.a1y === positions.a2y) ||
    (points[0].x === points[6].x && points[0].y === points[6].y)
  ) {
    return false;
  }

  let denominator =
    (points[6].y - points[0].y) * (positions.a2x - positions.a1x) -
    (points[6].x - points[0].x) * (positions.a2y - positions.a1y);

  if (denominator === 0) {
    return false;
  }

  let ua =
    ((points[6].x - points[0].x) * (positions.a1y - points[0].y) -
      (points[6].y - points[0].y) * (positions.a1x - points[0].x)) /
    denominator;
  let ub =
    ((positions.a2x - positions.a1x) * (positions.a1y - points[0].y) -
      (positions.a2y - positions.a1y) * (positions.a1x - points[0].x)) /
    denominator;

  if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
    return false;
  }

  let x = positions.a1x + ua * (positions.a2x - positions.a1x);
  let y = positions.a1y + ua * (positions.a2y - positions.a1y);

Правая сторона:

if (
    (positions.a1x === positions.a2x && positions.a1y === positions.a2y) ||
    (points[2].x === points[3].x && points[2].y === points[3].y)
  ) {
    return false;
  }

  let denominator2 =
    (points[3].y - points[2].y) * (positions.a2x - positions.a1x) -
    (points[3].x - points[2].x) * (positions.a2y - positions.a1y);

  if (denominator2 === 0) {
    return false;
  }

  let ua2 =
    ((points[3].x - points[2].x) * (positions.a1y - points[2].y) -
      (points[3].y - points[2].y) * (positions.a1x - points[2].x)) /
    denominator;
  let ub2 =
    ((positions.a2x - positions.a1x) * (positions.a1y - points[2].y) -
      (positions.a2y - positions.a1y) * (positions.a1x - points[2].x)) /
    denominator;

  if (ua2 < 0 || ua2 > 1 || ub2 < 0 || ub2 > 1) {
    return false;
  }

  let x2 = positions.a1x + ua2 * (positions.a2x - positions.a1x);
  let y2 = positions.a1y + ua2 * (positions.a2y - positions.a1y);

Если я пересекаю полигон слева направо, точка столкновения, кажется, входит внутрь, если i go справа налево, точка столкновения кажется go наружу; Если моя линия идет слева и подходит близко к правой стороне, но не касается ее, алгоритм все равно находит ложное столкновение.

Начальные координаты для многоугольника:

    const points = [
      { x: 100, y: 100 },
      { x: 200, y: 50 },
      { x: 300, y: 50 },
      { x: 400, y: 200 },
      { x: 350, y: 250 },
      { x: 200, y: 300 },
      { x: 150, y: 300 }
    ];

Любые помощь

...