¿Cómo calculo el punto final rebotado de la intersección de dos líneas?
Cuando me dieron las siguientes dos líneas, pude calcular el punto de intersección de dos líneas con la siguiente función.
export function intersection(line1, line2) { line1.y1 *= -1; line1.y2 *= -1; // for Webpage coordinates line2.y3 *= -1; line2.y4 *= -1; // for Webpage coordinates const [x1, y1, x2, y2] = line1; const [x3, y3, x4, y4] = line2; const [a1, b1, c1] = [y2 - y1, x1 - x2, x2 * y1 - x1 * y2]; if ( a1 === 0 && b1 === 0 ) return 'line1 does not have length'; const [a2, b2, c2] = [y4 - y3, x3 - x4, x4 * y3 - x3 * y4]; if ( a2 === 0 && b2 === 0 ) return 'line2 does not have length'; const denom = a1 * b2 - a2 * b1; if (denom === 0) return 'lines are parallel'; const x = (b1 * c2 - b2 * c1) / denom; // (x,y) is the intersection const y = (a2 * c1 - a1 * c2) / denom; // check if two lines are actually crossing w/o extending it function getDist(x1, y1, x2, y2) { return Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2); } const distLine1 = getDist(x1, y1, x2, y2); const distLine2 = getDist(x3, y3, x4, y4); const distToXY1 = Math.max(getDist(x1, y1, x, y), getDist(x2, y2, x, y)) ; const distToXY2 = Math.max(getDist(x3, y3, x, y), getDist(x4, y4, x, y)) ; if (distToXY1 > distLine1 || distToXY2 > distLine2) return 'lines does not meet'; return {x, y}; }
DEMOSTRACIÓN: https://stackblitz.com/edit/intersection-of-two-lines?file=index.js
Sin embargo, estoy luchando por encontrar una posición de rebote (o punto de reflexión) de dos líneas usando dos líneas.
¿Cuál es la fórmula para obtener la posición x/y de la línea 1 (x1, x2, y1, y2) y la línea 2 (x1, x2, y1, y2)?
Tienes que dividir la parte del vector rojo que está "dentro de la pared" en dos componentes, una paralela a la pared y la otra perpendicular a ella. Luego niegas el componente perpendicular y los vuelves a sumar.
class Line { constructor(x1, y1, x2, y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.dx = x2 - x1; this.dy = y2 - y1; } intersect(o) { const d = this.dy * o.dx - this.dx * o.dy; if (d === 0) return null; // parallel const k = ((o.y1 - this.y1) * o.dx + (this.x1 - o.x1) * o.dy) / d; return { x: this.x1 + k * this.dx, y: this.y1 + k * this.dy }; } bounce(o) { const i = this.intersect(o); if (!i) return null; // vector from intersection to end const v = { x: this.x2 - ix, y: this.y2 - iy }; // split v into two perpendicular vectors, one parallel to o // the perpendicular one is o's direction rotated by 90° const p = { x: o.dy, y: -o.dx }; // vx = a * o.dx + b * px // vy = a * o.dy + b * py // division by zero is impossible since o and p are perpendicular const a = (vy * px - vx * py) / (o.dy * px - o.dx * py); const b = (vy * o.dx - vx * o.dy) / (py * o.dx - px * o.dy); // negate b to mirror end of line on o return { x: ix + a * o.dx - b * px, y: iy + a * o.dy - b * py } } } const l1 = new Line(100, 300, 400, 100); const l2 = new Line(100, 100, 400, 300); console.log(l1.bounce(l2));Creo que estoy cerca de una respuesta.
este es mi enfoque
https://stackblitz.com/edit/intersección-de-dos-líneas-nes7zy?view=preview
En la demostración, este enfoque se ve bien. Si un experto en matemáticas puede confirmar este enfoque, se lo agradecería.
// https://stackoverflow.com/a/1811636/454252 function getPerpendicularPoint(iPoint, line1, line2) { const [x1, y1] = [iPoint.x, iPoint.y]; // start point const [x2, y2] = [line1[2], line1[3]]; // baseline end point const [x3, y3] = [line2[2], line2[3]]; // extended line end point const k = ((y2-y1) * (x3-x1) - (x2-x1) * (y3-y1)) / ((y2-y1)**2 + (x2-x1)**2); const x4 = x3 - k * (y2-y1); const y4 = y3 + k * (x2-x1); return {x: x4, y: y4}; } //http://www.java2s.com/Tutorials/Javascript/Canvas_How_to/Shape/Extend_a_line_before_and_after_original_endpoints.htm function getExtendedPoint(startPt, endPt, extent) { var dx = endPt.x - startPt.x; var dy = endPt.y - startPt.y; var x = startPt.x + dx * extent; var y = startPt.y + dy * extent; return {x, y}; } let line1 = [100, 100, 400, 300]; let line2 = [100, 300, 400, 100]; const iPoint = {x: 250, y: 200}; // intersection(line1, line2); const pPoint = getPerpendicularPoint(iPoint, line1, line2); const ePoint = getExtendedPoint({x:line2[2], y:line2[3]}, pPoint, 2); console.log(pPoint, ePoint);