Eli, le code que vous avez installés sur est incorrect. Un point près de la ligne sur laquelle le segment se trouve, mais de loin l'une des extrémités du segment peut être mal jugé à proximité du segment. Mise à jour: La réponse incorrecte mentionné n'est plus accepté.
Voici quelques bon code en C++. Il suppose une classe de 2D vectoriel class vec2 {float x,y;}
, essentiellement, avec des opérateurs pour ajouter, subract, échelle, etc, et à une distance et point en fonction du produit (c - x1 x2 + y1 y2
).
float minimum_distance(vec2 v, vec2 w, vec2 p) {
// Return minimum distance between line segment vw and point p
const float l2 = length_squared(v, w); // i.e. |w-v|^2 - avoid a sqrt
if (l2 == 0.0) return distance(p, v); // v == w case
// Consider the line extending the segment, parameterized as v + t (w - v).
// We find projection of point p onto the line.
// It falls where t = [(p-v) . (w-v)] / |w-v|^2
const float t = dot(p - v, w - v) / l2;
if (t < 0.0) return distance(p, v); // Beyond the 'v' end of the segment
else if (t > 1.0) return distance(p, w); // Beyond the 'w' end of the segment
const vec2 projection = v + t * (w - v); // Projection falls on the segment
return distance(p, projection);
}
EDIT: j'avais besoin d'un Javascript de mise en œuvre, si elle est ici, sans dépendances (ou des commentaires, mais c'est un port direct de la ci-dessus). Les Points sont représentés comme des objets avec x
et y
attributs.
function sqr(x) { return x * x }
function dist2(v, w) { return sqr(v.x - w.x) + sqr(v.y - w.y) }
function distToSegmentSquared(p, v, w) {
var l2 = dist2(v, w);
if (l2 == 0) return dist2(p, v);
var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
if (t < 0) return dist2(p, v);
if (t > 1) return dist2(p, w);
return dist2(p, { x: v.x + t * (w.x - v.x),
y: v.y + t * (w.y - v.y) });
}
function distToSegment(p, v, w) { return Math.sqrt(distToSegmentSquared(p, v, w)); }