首页 > 代码库 > hdu 2857 Mirror and Light

hdu 2857 Mirror and Light

   题目大意:有一面镜子,一束光射进来,已知镜子的坐标(x1, y1)(x2, y2)两点确定一个镜子的面,光的入射点和光的反射点,求光照在镜子上面点的坐标。

   思路:如下图

       

    (1)求直线(x1, y1)(x2, y2)

    (2)求(s.x, s.y)关于直线(x1, y1)(x2, y2)的对称点(tmp.x, tmp.y)

    (3)求直线(tmp.x, tmp.y)(e.x, e.y)

    (4)求(x1, y1)(x2, y2)与(tmp.x, tmp.y)(e.x, e.y)的交点(x, y)


   公式:

    ·已知直线上的两点(x1, y1)(x2, y2),求直线ax+by+c=0

      a = y2-y1; b = x1-x2;  c = y1*x2-x1*y2;


    ·已知(x0, y0),求关于直线ax+by+c=0的对称点(x, y)

      k = -2 * (a*x0+b*y0+c)/(a*a+b*b);

      x = x0 + k*a;

      y = y0 + k*b;


    ·已知直线与直线,求交点(x, y)

      如果b1==0则

      

      否则

      

      AC代码

#include <iostream>
#include <cstdio>
using namespace std;
struct Node
{
	double x, y;
};
double a1,b1,c1,a2,b2,c2, k;
Node n1,n2,s, e, node1;
int main()
{
    int n;
	cin>>n;
	while (n--)
	{
		scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &n1.x, &n1.y,&n2.x, &n2.y,&s.x, &s.y,&e.x, &e.y);
		{
			//求镜子所在直线
           a1 = n2.y-n1.y;b1 = n1.x-n2.x;c1=n1.y*n2.x-n1.x*n2.y;
           //求对称点
		   k = -2*(a1*s.x+b1*s.y+c1)/(a1*a1+b1*b1);
          
		   node1.x = s.x + k*a1;
		   node1.y = s.y + k*b1;
      
		   a2 =e.y-node1.y ; b2=node1.x-e.x ; c2 =node1.y*e.x-node1.x*e.y;
           //求两条直线的交点
		   double x, y;
		   if (b1==0)
		   {
		       x=-c1/a1;
	      	   y=(-c2-a2*x)/b2;
		   }
		   else
		   {
		      x = (c2*b1-c1*b2)/(a1*b2-a2*b1);
		      y = (-a1*x-c1)/b1;
		   }
		   printf("%.3lf %.3lf\n", x, y);
		}
	}
	return 0;
}