Estoy trabajando en una aplicación de pizarra simple donde los dibujos están representados por curvas Bezier cuadráticas (usando la función CanvasPath.quadraticCurveTo de JavaScript). Estoy tratando de implementar la funcionalidad para que una herramienta de borrador o una herramienta de selección puedan determinar si están tocando un dibujo.
Para mostrar de lo que estoy hablando, en la siguiente imagen hay un dibujo rojo y necesito poder determinar que los rectángulos negros y el punto negro se superponen con el área del dibujo. Para fines de depuración, he agregado círculos azules que son puntos de control de la curva y la línea verde que es la misma curva Bezier pero con un ancho mucho menor.
He incluido mi código que genera la curva Bezier:
context.beginPath(); context.moveTo(localPoints[0].x, localPoints[0].y); let i; for (i = 1; i < localPoints.length - 2; i++) { let xc = (localPoints[i].x + localPoints[i + 1].x) / 2; let yc = (localPoints[i].y + localPoints[i + 1].y) / 2; context.quadraticCurveTo(localPoints[i].x, localPoints[i].y, xc, yc); } // curve through the last two points context.quadraticCurveTo(localPoints[i].x, localPoints[i].y, localPoints[i + 1].x, localPoints[i + 1].y); context.stroke();He podido encontrar respuestas sobre cómo determinar si un segmento de línea se cruza con una curva Bezier, pero no he podido encontrar cómo determinar si algo no se cruza con la curva real pero está lo suficientemente cerca como para considerar que se superpone a su " área". Para hacerlo, imagino que solo necesito encontrar la distancia entre la curva y el rectángulo/punto y luego asegurarme de que la distancia sea menor que el ancho utilizado para dibujar la curva, pero no estoy seguro de cómo encontrar esa distancia.
Algunos artículos/posts interesantes:
Cómo rastrear coordenadas en la curva cuadrática
https://coderedirect.com/questions/385964/nearest-point-on-a-quadratic-bezier-curve
Y si no funciona, tal vez pueda echar un vistazo a esta biblioteca: https://pomax.github.io/bezierjs/
Como sugirió Pomax en los comentarios, lo que está buscando está en la biblioteca y parece que hay una explicación adecuada.
Hay una demostración en vivo si quieres probarlo: https://pomax.github.io/bezierinfo/#projections
El código fuente está aquí: https://pomax.github.io/bezierinfo/chapters/projections/project.js
Para usarlo, instálelo siguiendo los pasos de GitHub: https://github.com/Pomax/bezierjs
Por supuesto, crédito a Pomax por sugerir su biblioteca.