Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- double eps=1e-6;
- bool less_than(double a, double b){
- return a<b-eps;
- }
- bool equal(double a, double b){
- return abs(a-b)<eps;
- }
- bool less_than_or_equal_to(double a, double b){
- return (equal(a, b) || less_than(a, b));
- }
- int sign(double a){
- if (less_than(a, 0)){
- return -1;
- }
- if (equal(a, 0)){
- return 0;
- }
- return 1;
- }
- struct Point{
- double x;
- double y;
- };
- struct Line{
- double a;
- double b;
- double c;
- };
- struct Circle{
- Point o;
- double r;
- };
- bool equal_points(Point p, Point q){
- return (equal(p.x, q.x) && equal(p.y, q.y));
- }
- Point draw_vector(Point p, Point q){
- return {q.x-p.x, q.y-p.y};
- }
- Point sum_of_vectors(Point p, Point q){
- return {p.x+q.x, p.y+q.y};
- }
- double cross_product(Point p, Point q){
- return p.x*q.x+p.y*q.y;
- }
- double dot_product(Point p, Point q){
- return p.x*q.y-p.y*q.x;
- }
- double length_vector(Point p){
- return sqrt(p.x*p.x+p.y*p.y);
- }
- Point change_length(Point p, double l){
- return {(l*p.x)/(sqrt(p.x*p.x+p.y*p.y)), (l*p.y)/(sqrt(p.x*p.x+p.y*p.y))};
- }
- Point rotate_90_deg(Point p){
- return {-p.y, p.x};
- }
- double angle_between_vectors(Point p, Point q){
- return atan2(dot_product(p, q), cross_product(p, q));
- }
- double distance_points(Point p, Point q){
- return length_vector(draw_vector(p, q));
- }
- Line line_by_two_points(Point p, Point q){
- return {q.y-p.y, p.x-q.x, p.y*q.x-p.x*q.y};
- }
- bool three_points_collinear(Point p, Point q, Point r){
- return equal(0, dot_product(draw_vector(p, q), draw_vector(p, r)));
- }
- bool point_lie_on_segment(Point r, Point p, Point q){
- if (!three_points_collinear(p, q, r)){
- return false;
- }
- if (equal_points(r, p) || equal_points(r, q)){
- return true;
- }
- if (equal_points(p, q)){
- return equal_points(p, r);
- }
- return less_than_or_equal_to(cross_product(draw_vector(r, p), draw_vector(r, q)), 0);
- }
- bool same_lines(Line f, Line g){
- if (!equal(f.a*g.b,g.a*f.b)){
- return false;
- }
- if (!equal(f.a*g.c, f.c*g.a)){
- return false;
- }
- return true;
- }
- bool parallel_lines(Line f, Line g){
- if (same_lines(f, g)){
- return false;
- }
- if (equal(f.a*g.b, f.b*g.a)){
- return true;
- }
- return false;
- }
- Point intersection_two_lines(Line f, Line g){
- return {(f.c*g.b-f.b*g.c)/(1.0*(f.b*g.a-g.b*f.a)), (f.c*g.a-g.c*f.a)/(1.0*(f.a*g.b-g.a*f.b))};
- }
- double distance_point_line(Point p, Line f){
- return (abs(p.x*f.a+p.y*f.b+f.c))/sqrt(f.a*f.a+f.b*f.b);
- }
- Point base_of_perpendicular(Point p, Line f){
- if (equal(distance_point_line(sum_of_vectors(p, change_length({f.a, f.b}, distance_point_line(p, f))), f), 0)){
- return sum_of_vectors(p, change_length({f.a, f.b}, distance_point_line(p, f)));
- }
- return sum_of_vectors(p, change_length({-f.a, -f.b}, distance_point_line(p, f)));
- }
- double distance_point_segment(Point r, Point p, Point q){
- if (equal_points(p, q)){
- return distance_points(p, r);
- }
- Point H= base_of_perpendicular(r, line_by_two_points(p, q));
- if (point_lie_on_segment(H, p, q)){
- return distance_points(r, H);
- }
- return min(distance_points(r, p), distance_points(r, q));
- }
- bool two_segments_intersect(Point a, Point b, Point c, Point d){
- if (equal_points(a, b)){
- return three_points_collinear(a, c, d);
- }
- if (equal_points(c, d)){
- return three_points_collinear(a, b, c);
- }
- if (equal_points(a, c) || equal_points(a, d) || equal_points(b, c) || equal_points(b, d)){
- return true;
- }
- if (equal(dot_product(draw_vector(c, a), draw_vector(c, d)), 0)){
- if (equal(dot_product(draw_vector(c, b), draw_vector(c, d)), 0)) {
- if (less_than_or_equal_to(cross_product(draw_vector(a, c), draw_vector(a, d)), 0)){
- return true;
- }
- if (less_than_or_equal_to(cross_product(draw_vector(b, c), draw_vector(b, d)), 0)){
- return true;
- }
- if (less_than_or_equal_to(cross_product(draw_vector(c, a), draw_vector(c, b)), 0)){
- return true;
- }
- if (less_than_or_equal_to(cross_product(draw_vector(d, a), draw_vector(d, b)), 0)){
- return true;
- }
- return false;
- }
- if (less_than_or_equal_to(cross_product(draw_vector(a, c), draw_vector(a, d)), 0)){
- return true;
- }
- return false;
- }
- if (equal(dot_product(draw_vector(c, b), draw_vector(c, d)), 0)){
- if (less_than_or_equal_to(cross_product(draw_vector(b, c), draw_vector(b, d)), 0)){
- return true;
- }
- return false;
- }
- if (sign(dot_product(draw_vector(c, d), draw_vector(c, a)))!=sign(dot_product(draw_vector(c, d), draw_vector(c, b)))){
- if (sign(dot_product(draw_vector(a, b), draw_vector(a, c)))!=sign(dot_product(draw_vector(a, b), draw_vector(a, d)))){
- return true;
- }
- }
- return false;
- }
- bool point_lie_on_ray(Point r, Point p, Point q){
- if (!three_points_collinear(r, p, q)){
- return false;
- }
- if (equal_points(r, p) || equal_points(r, q)){
- return true;
- }
- return (less_than_or_equal_to(0, cross_product(draw_vector(p, r), draw_vector(p, q))));
- }
- double distance_point_ray(Point r, Point p, Point q){
- Point H = base_of_perpendicular(r, line_by_two_points(p, q));
- if (point_lie_on_ray(H, p, q)){
- return distance_points(r, H);
- }
- return distance_points(r, p);
- }
- bool segment_intersect_ray(Point p, Point q, Point r, Point s){
- Line f= line_by_two_points(p, q);
- Line g= line_by_two_points(r, s);
- if (same_lines(f, g)){
- return (point_lie_on_ray(p, r, s) || point_lie_on_ray(q, r, s));
- }
- if (parallel_lines(f, g)){
- return false;
- }
- Point t = intersection_two_lines(f, g);
- return (point_lie_on_segment(t, p, q) && point_lie_on_ray(t, r, s));
- }
- double distance_segment_ray(Point p, Point q, Point r, Point s){
- if (equal_points(p, q)){
- return distance_point_ray(p, r, s);
- }
- if (segment_intersect_ray(p, q, r, s)){
- return 0;
- }
- double minimum= distance_point_segment(r, p, q);
- Point h1 = base_of_perpendicular(p, line_by_two_points(r, s));
- Point h2 = base_of_perpendicular(q, line_by_two_points(r, s));
- if (point_lie_on_ray(h1, r, s)){
- minimum=min(minimum, distance_points(p, h1));
- }
- if (point_lie_on_ray(h2, r, s)){
- minimum=min(minimum, distance_points(q, h2));
- }
- return minimum;
- }
- bool rays_intersect(Point p, Point q, Point r, Point s){
- if (equal_points(p, q)){
- return point_lie_on_ray(p, r, s);
- }
- if (equal_points(r, s)){
- return point_lie_on_ray(r, p, q);
- }
- Line f = line_by_two_points(p, q);
- Line g = line_by_two_points(r, s);
- if (same_lines(f, g)){
- if (less_than_or_equal_to(0, cross_product(draw_vector(p, q), draw_vector(r, s)))){
- return true;
- }
- if (point_lie_on_ray(p, r, s) || point_lie_on_ray(r, p, q)){
- return true;
- }
- return false;
- }
- if (parallel_lines(f, g)){
- return false;
- }
- Point t= intersection_two_lines(f, g);
- return (point_lie_on_ray(t, p, q) && point_lie_on_ray(t, r, s));
- }
- double distance_rays(Point p, Point q, Point r, Point s) {
- if (rays_intersect(p, q, r, s)) {
- return 0;
- }
- Line f = line_by_two_points(p, q);
- Line g = line_by_two_points(r, s);
- if (same_lines(f, g)) {
- return distance_points(p, r);
- }
- if (parallel_lines(f, g)) {
- Point h1 = base_of_perpendicular(p, g);
- Point h2 = base_of_perpendicular(r, f);
- if (point_lie_on_ray(h1, r, s)) {
- return distance_points(h1, p);
- }
- if (point_lie_on_ray(h2, p, q)) {
- return distance_points(h2, r);
- }
- return distance_points(p, r);
- }
- return min(distance_point_ray(p, r, s), distance_point_ray(r, p, q));
- }
- bool ray_intersect_line(Point p, Point q, Line f){
- Line g= line_by_two_points(p, q);
- if (same_lines(f, g)){
- return true;
- }
- if (parallel_lines(f, g)){
- return false;
- }
- Point t= intersection_two_lines(f, g);
- return point_lie_on_ray(t, p, q);
- }
- double distance_segments(Point p, Point q, Point r, Point s){
- if (two_segments_intersect(p, q, r, s)){
- return 0;
- }
- double d1 = distance_point_segment(p, r, s);
- double d2 = distance_point_segment(q, r, s);
- double d3 = distance_point_segment(r, p, q);
- double d4 = distance_point_segment(s, p, q);
- return min(d4, min(d3, min(d2, d1)));
- }
- double distance_ray_line(Point p, Point q, Line f){
- if (ray_intersect_line(p, q, f)){
- return 0;
- }
- Line g= line_by_two_points(p, q);
- if (parallel_lines(f, g)){
- return distance_point_line(p, f);
- }
- return distance_point_line(p, f);
- }
- double distance_segment_lime(Point p, Point q, Line f){
- return min(distance_point_line(p, f), distance_point_line(q, f));
- }
- double distance_lines(Line f, Line g){
- if (same_lines(f, g)){
- return 0;
- }
- if (parallel_lines(f, g)){
- Point r;
- if (f.a!=0){
- r={-f.c/f.a, 0};
- }else{
- r={0, -f.c/f.b};
- }
- return distance_point_line(r, g);
- }
- return 0;
- }
- int main(){
- Point a, b, c, d;
- cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y>>d.x>>d.y;
- Line f= line_by_two_points(a, b);
- Line g= line_by_two_points(c, d);
- cout<<distance_points(a, c)<<"\n";
- cout<<distance_point_segment(a, c, d)<<"\n";
- cout<<distance_point_ray(a, c, d)<<"\n";
- cout<<distance_point_line(a, g)<<"\n";
- cout<<distance_point_segment(c, a, b)<<"\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement