• poj3819 Coverage (求直线与圆的交占直线的百分比 )


        题意:给你一条直线和若干个圆,求圆与直线相交的长度占整条直线的比例

       解题思路:通过定比分点的方法求出圆与直线的交占圆的比例。

        第一步:(确定投影的方向是x轴还是y轴) 

       (1)当直线的line.s(x, y), line.e(x, y)的line.s.x与line.e.x不同一时候,这条直线能够等同于起点为line.s.x, line.e.x;

       (2)不满足(1)时(即line.s.x==line.e.x时),当直线的line.s(x, y), line.e(x, y)的line.s.y与line.e.y不同一时候。这条直线能够等同于起点为line.s.x, line.e.x;

       (3)当不满足(1)以及(2)时(即line.s==line.e),这时候直线为一个点,不论什么的圆都与它没有交。圆占整条直线的比例为0;

        第二步:(将圆投影到第一步得到的直线上)

        求出圆在直线上的投影的范围;

        第三步:

        求出全部圆的并。将圆的并除以线段的长度。求圆与线段的交占线段的百分比;


       

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    using namespace  std;
    const int MAX = 300;
    struct Node
    {
    	double x, y;
    };
    struct Line
    {
    	Node s, e;
    };
    Line line;
    Node p[MAX];
    double A, B, C, delta;
    double x, y, r;
    double x11, y11, dx, dy;
    Node tmp, cir;
    double sqr(double x)
    {
    	return x * x;
    }
    int circle_cross_line(Node s, Node e, Node O, double r)//推断圆与直线是否有交点
    {
    	double x0 = O.x, y0=O.y;
    	x11 = s.x, y11 = s.y;
    	double x2 = e.x, y2 = e.y;
    	dx = x2 - x11, dy = y2 - y11;
    	A = dx * dx + dy*dy;
    	B = 2 * dx * (x11 - x0) + 2 * dy * (y11 - y0);
    	C = sqr(x11-x0) + sqr(y11-y0) - sqr(r);
    	delta = sqr(B) - 4 * A * C;
    	return delta > 0;
    }
    int cmp(Node a, Node b)
    {
    	if (a.x < b.x)
    		return 1;
    	return 0;
    }
    int main()
    {
    	int n, i, cnt;
    	int flag, flagnum;
    	double leng;
    	while (scanf("%d", &n) && n)
    	{
    		flagnum = 0;
    		scanf("%lf%lf%lf%lf", &line.s.x, &line.s.y, &line.e.x, &line.e.y);
    		if (line.s.x!=line.e.x)
    		{
    			if (line.s.x < line.e.x)
    			{
    				tmp.x = line.s.x;
    				tmp.y = line.e.x;
    			}
    			else
    			{
    				tmp.x = line.e.x;
    				tmp.y = line.s.x;
    			}
    			flag = 0;
    			leng = fabs(line.e.x - line.s.x);
    		}
    		else if (line.s.x==line.e.x && line.s.y!=line.e.y)
    		{
    			if (line.s.y < line.e.y)
    			{
    				tmp.x = line.s.y;
    				tmp.y = line.e.y;
    			}
    			else
    			{
    				tmp.x = line.e.y;
    				tmp.y = line.s.y;
    			}
    			flag = 1;
    			leng = fabs(line.e.y - line.s.y);
    		}
    		else
    			flagnum = 1;
    		cnt = 0;
    		for (i=0; i<n; i++)
    		{
    			scanf("%lf%lf%lf", &cir.x, &cir.y, &r);
    			if (flagnum)
    				continue;
    			if (circle_cross_line(line.s, line.e, cir, r))
    			{
    				p[cnt].x = (-B-sqrt(delta))/(2.0*A);
    				p[cnt].y = (-B+sqrt(delta))/(2.0*A);
    				if (flag==0)
    				{
    					p[cnt].x = p[cnt].x * dx + x11;
    					p[cnt].y = p[cnt].y * dx + x11;
    				}
    				else
    				{
    					p[cnt].x = p[cnt].x * dy + y11;
    					p[cnt].y = p[cnt].y * dy + y11;
    				}
    				if (p[cnt].x>p[cnt].y)
    				{
    					double t = p[cnt].x;
    					p[cnt].x = p[cnt].y;
    					p[cnt].y = t;
    				}
    				if (p[cnt].x>tmp.y || p[cnt].y<tmp.x)
    					continue;
    				if (p[cnt].x<tmp.x)
    					p[cnt].x = tmp.x;
    				if (p[cnt].y>tmp.y)
    					p[cnt].y = tmp.y; 
    				cnt++;
    			}
    		}
    		if (flagnum || cnt==0)
    			printf("0.00
    ");
    		else
    		{
    			sort(p, p+cnt, cmp);
    			double sum = 0;
    			tmp = p[0];
    			for (i=1; i<cnt; i++)
    			{
    				if (p[i].x < tmp.y)
    				{
    					if (p[i].y > tmp.y)
    						tmp.y = p[i].y;
    				}
    				else
    				{
    					sum += tmp.y - tmp.x;
    					tmp = p[i];
    				}
    			}
    			sum += tmp.y - tmp.x;
    			printf("%.2f
    ", sum/leng*100.0);
    		}
    	}
    	return 0;
    }

      


  • 相关阅读:
    时间选择器组件之table避坑指南
    ⼯⼚模式
    外观模式
    中介者模式+装饰器模式
    代理模式
    策略模式
    设计模式--------单例模式
    设计模式--------订阅/发布模式 (观察者)
    对ts的研究
    对react的研究20200724
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5167408.html
Copyright © 2020-2023  润新知