Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- double line_circle_distance_fraction(coord2d origin, double radius, coord2d ray_start, coord2d ray_end, bool bidi = false)
- {
- if(ray_start == ray_end)
- return INF;
- origin = origin - ray_start;
- ray_end = ray_end - ray_start;
- double line_length = magnitude(ray_end);
- origin = origin / line_length;
- ray_end = ray_end / line_length;
- radius /= line_length;
- // divide by ray starting at origin to rotate frame to simple reference frame
- origin = normalized_complex_division(origin, ray_end);
- ray_end = coord2d(1, 0);
- // translate everything to center on the circle
- ray_start = -origin;
- ray_end = ray_end - origin;
- ray_start = ray_start / radius;
- ray_end = ray_end / radius;
- // ray now needs to intersect the unit circle `x^2 + y^2 = 1`
- const coord2d delta = ray_end - ray_start;
- // no delta along y axis
- if(delta.y == 0)
- {
- // passes outside of circle
- if(ray_start.y > 1 or ray_start.y < -1)
- return INF;
- // if it intersects, this is the y coordinate
- // (the ray necessarily goes "upwards" because of the frame rotation)
- double x = -sqrt(1-(ray_start.y*ray_start.y));
- // ensure the start and end point are not on the same side of the contact point
- if((ray_start.x > x and ray_end.x > x) or (ray_start.x < x and ray_end.x < x))
- {
- if(!bidi)
- return INF;
- x = -x;
- if((ray_start.x > x and ray_end.x > x) or (ray_start.x < x and ray_end.x < x))
- return INF;
- }
- //printf("%f\n", ray_start.y);
- return magnitude(coord2d(x, ray_start.y) - ray_start)*radius;
- }
- else // something went terribly wrong
- return INF;
- }
- double line_yplane_intersection(const coord & start, const coord & end, const double & y, coord & intersect)
- {
- coord delta = end-start;
- const double factor = (y-start.y)/delta.y;
- intersect = end*factor + start*(1-factor);
- return factor;
- }
- double line_disk_distance(coord origin, double radius, coord ray_start, coord ray_end, coord * contact_location)
- {
- if(contact_location)
- *contact_location = coord();
- if(ray_start == ray_end)
- return INF;
- if(ray_start.y - ray_end.y == 0)
- return INF;
- coord plane_intersection;
- double factor = line_yplane_intersection(ray_start, ray_end, origin.y, plane_intersection);
- if(factor < 0 or factor > 1)
- return INF;
- coord test_coord = plane_intersection - origin;
- test_coord.y = 0; // might merely be close to zero because of numerical instability; make exactly zero
- if(magnitude_sq(test_coord) > radius*radius)
- return INF;
- if(contact_location)
- *contact_location = plane_intersection;
- return magnitude(plane_intersection - ray_start);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement