Skip to content

Instantly share code, notes, and snippets.

@joseph-montanez
Created May 29, 2011 03:38
Show Gist options
  • Save joseph-montanez/997443 to your computer and use it in GitHub Desktop.
Save joseph-montanez/997443 to your computer and use it in GitHub Desktop.
Closest Point on Segment from a center point of a circle
public Gsl.Vector? closest_point_on_segment (
Gsl.Vector segment_1, Gsl.Vector segment_2, Gsl.Vector circle_position
) {
var segment = new Gsl.Vector(2);
segment.set(0, segment_1.get (0) - segment_2.get (0));
segment.set(1, segment_1.get (1) - segment_2.get (1));
var point = new Gsl.Vector(2);
point.set(0, circle_position.get (0) - segment_2.get (0));
point.set(1, circle_position.get (1) - segment_2.get (1));
// Length
var segment_length = Math.sqrt (
(segment.get (0) * segment.get (0))
+
(segment.get (1) * segment.get (1))
);
if (segment_length <= 0) {
/* Invalid segment length */
return null;
}
// Divide against scalar
var segment_unit = new Gsl.Vector(2);
segment_unit.set (0, segment.get (0) / segment_length);
segment_unit.set (1, segment.get (1) / segment_length);
// Dot Product
double projection =
(point.get (0) * segment_unit.get (0))
+
(point.get (0) * segment_unit.get (1))
;
var result = new Gsl.Vector(2);
if (projection <= 0) {
result.set(0, segment_1[0]);
result.set(1, segment_1[1]);
return result;
}
if (projection >= segment_length) {
result.set(0, segment_2[0]);
result.set(1, segment_2[1]);
return result;
}
// Multiple against scalar
var projection_vector = new Gsl.Vector(2);
projection_vector.set (0, segment_unit.get (0) * projection);
projection_vector.set (1, segment_unit.get (1) * projection);
// Closest
result.set (0, projection_vector.get (0) + segment_1.get (0));
result.set (1, projection_vector.get (1) + segment_1.get (1));
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment