RNLength R2Distance(const R2Point& point, const R2Span& span) { // Check span if (RNIsZero(span.Length())) return R2Distance(point, span.Start()); // Check if start point is closest R2Vector v1 = point - span.Start(); RNScalar dir1 = v1.Dot(span.Vector()); if (RNIsNegative(dir1)) return v1.Length(); // Check if end point is closest R2Vector v2 = point - span.End(); RNScalar dir2 = v2.Dot(span.Vector()); if (RNIsPositive(dir2)) return v2.Length(); // Return distance from point to span line return R2Distance(point, span.Line()); }
RNLength R2Distance(const R2Point& point, const R2Ray& ray) { // Check if start point is closest R2Vector v = point - ray.Start(); RNScalar dir = v.Dot(ray.Vector()); if (RNIsNegative(dir)) return v.Length(); // Return distance from point to ray line return R2Distance(point, ray.Line()); }
RNLength R2Distance(const R2Point& point, const R2Polyline& polyline) { // Compute distance to each segment // This could be a lot faster RNLength closest_distance = FLT_MAX; for (int i = 1; i < polyline.NPoints(); i++) { const R2Point& p0 = polyline.Point(i-1); const R2Point& p1 = polyline.Point(i); R2Span span(p0, p1); RNLength d = R2Distance(span, point); if (d < closest_distance) closest_distance = d; } // Return distance return closest_distance; }
RNLength R2Distance(const R2Point& point, const R2Polygon& polygon) { // Check if polygon contains point if (R2Contains(polygon, point)) return 0; // Compute distance to each segment // This could be a lot faster RNLength closest_distance = FLT_MAX; for (int i = 0; i < polygon.NPoints(); i++) { const R2Point& p0 = polygon.Point(i); const R2Point& p1 = polygon.Point((i+1)%polygon.NPoints()); R2Span span(p0, p1); RNLength d = R2Distance(span, point); if (d < closest_distance) closest_distance = d; } // Return distance return closest_distance; }
RNLength R2Distance(const R2Point& point, const R2Arc& arc) { // Figure sector - positive ds are inside arc sector RNLength d1 = R2SignedDistance(R2Line(arc.StartPoint(), arc.Center()), point); RNLength d2 = R2SignedDistance(R2Line(arc.Center(), arc.StopPoint()), point); if (d1 > 0.0) { if (d2 > 0.0) { // Point is in arc sector RNLength d = R2Distance(arc.Center(), point) - arc.Radius(); return (d < 0) ? -d : d; } else { // Point may be in arc sector if (arc.SweepAngle() > RN_PI) { // Point is in arc sector RNLength d = R2Distance(arc.Center(), point) - arc.Radius(); return (d < 0) ? -d : d; } else { // Point is closest to stop point return R2Distance(arc.StopPoint(), point); } } } else { if (d2 > 0.0) { // Point may be in arc sector if (arc.SweepAngle() > RN_PI) { // Point is in arc sector RNLength d = R2Distance(arc.Center(), point) - arc.Radius(); return (d < 0) ? -d : d; } else { // Point is closest to start point return R2Distance(arc.StartPoint(), point); } } else { // Point is outside arc sector RNLength d = R2Distance(arc.Center(), point) - arc.Radius(); return (d < 0) ? -d : d; } } }
void GLUTMouse(int button, int state, int x, int y) { // Invert y coordinate y = GLUTwindow_height - y; // Process mouse button event if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN)) { // Check for double click static RNTime click_time; const RNScalar max_double_click_elapsed = 0.5; RNBoolean double_click = (click_time.Elapsed() < max_double_click_elapsed); click_time.Read(); // Select closest point to cursor if (double_click) { selected_point = NULL; RNLength closest_distance = 10; R2Point cursor_position(x, y); for (int i = 0; i < all_points.NEntries(); i++) { TestPoint *point = all_points[i]; const R3Point& world_position = point->position; R2Point screen_position = viewer->ViewportPoint(world_position); RNLength distance = R2Distance(screen_position, cursor_position); if (distance < closest_distance) { selected_point = point; closest_distance = distance; } } // Find closest points closest_point = NULL; nearby_points.Empty(); if (selected_point) { if (max_nearby_points > 0) { kdtree->FindClosest(selected_point, min_nearby_distance, max_nearby_distance, max_nearby_points, nearby_points); closest_point = (nearby_points.NEntries() > 0) ? nearby_points.Head() : NULL; if (print_debug) printf("Found %d points\n", nearby_points.NEntries()); } else { kdtree->FindAll(selected_point, min_nearby_distance, max_nearby_distance, nearby_points); closest_point = kdtree->FindClosest(selected_point); if (print_debug) printf("Found %d points\n", nearby_points.NEntries()); } } } } // Remember button state int b = (button == GLUT_LEFT_BUTTON) ? 0 : ((button == GLUT_MIDDLE_BUTTON) ? 1 : 2); GLUTbutton[b] = (state == GLUT_DOWN) ? 1 : 0; // Remember modifiers GLUTmodifiers = glutGetModifiers(); // Remember mouse position GLUTmouse[0] = x; GLUTmouse[1] = y; // Redraw glutPostRedisplay(); }
RNLength R2Distance(const R2Circle& circle1, const R2Circle& circle2) { // Return distance from circle to circle RNLength d = R2Distance(circle2, circle1.Center()) - circle1.Radius(); return ((d > 0.0) ? d : 0.0); }
RNLength R2Distance(const R2Box& box, const R2Circle& circle) { // Return distance from box to circle RNLength d = R2Distance(box, circle.Center()) - circle.Radius(); return ((d > 0.0) ? d : 0.0); }
RNLength R2Distance(const R2Halfspace& halfspace, const R2Circle& circle) { // Return distance from halfspace to circle RNLength d = R2Distance(halfspace, circle.Center()) - circle.Radius(); return ((d > 0.0) ? d : 0.0); }
RNLength R2Distance(const R2Span& span, const R2Circle& circle) { // Return distance from span to circle RNLength d = R2Distance(span, circle.Center()) - circle.Radius(); return ((d > 0.0) ? d : 0.0); }
RNLength R2Distance(const R2Ray& ray, const R2Circle& circle) { // Return distance from ray to circle RNLength d = R2Distance(ray, circle.Center()) - circle.Radius(); return ((d > 0.0) ? d : 0.0); }
RNLength R2Distance(const R2Line& line, const R2Circle& circle) { // Return distance from line to circle RNLength d = R2Distance(line, circle.Center()) - circle.Radius(); return ((d > 0.0) ? d : 0.0); }
RNLength R2Distance(const R2Point& point, const R2Circle& circle) { // Return distance from point to circle RNLength d = R2Distance(point, circle.Center()) - circle.Radius(); return ((d > 0.0) ? d : 0.0); }