汇总篇:计算几何汇总
点到直线的距离
cos(x)=BA*BC/(|BA|*|BC|)
求AD有很多种方法,可以用勾股定理
这里用的三角函数
x=acos(cos(x))
|AD|=|BA|*sin(x)
如果x是钝角,|AD|=|BA|*sin(pi-x)=|BA|*sin(x)
如果是直角,sin(x) = 1,|AD|=|BA|
点A到直线BC的投影点
方法一
设D(dx,dy)
AD=(dx-ax,dy-ay)
BC=(C.x-B.x,C.y-B.y)
|BA|=sqrt((bx-ax)^2+(by-ay)^2)
令AD*BC=0,(dx-ax)*(cx-bx)+(dy-ay)*(cy-by)=0
|AD|=sqrt((dx-ax)^2+(dy-ay)^2)= |BA|*sin(x)
解上述方程组可解得dx,dy
方法二
BA在BC上的投影等于BA乘以BC的方向向量
D = B +BD
#include<iostream>
class point{
public:
double x;
double y;
point(double x_=0,double y_=0):x(x_),y(y_){}
friend const point operator+(const point& p1,const point& p2){
return point(p1.x+p2.x,p1.y+p2.y);
};
friend const point operator-(const point& p1,const point& p2){
return point(p1.x-p2.x,p1.y-p2.y);
};
friend const point operator*(const point& p,const double& m){
return point(p.x*m,p.y*m);
};
friend const point operator*(const double& m,const point& p){
return point(p.x*m,p.y*m);
};
friend const point operator/(const point& p,const double& m){
return point(p.x/m,p.y/m);
};
friend ostream& operator <<(ostream& out,point& a){
printf("(%lf,%lf)",a.x,a.y);
return out;
};
};
typedef point vect2;//重命名,向量也是用坐标表示
class line{
public:
point start;
point end;
line(point s=point(0,0),point e=point(0,0)):start(s),end(e){}
};
double dot(point O,point A,point B){//点乘
double oa_x=A.x-O.x;
double oa_y=A.y-O.y;
double ob_x=B.x-O.x;
double ob_y=B.y-O.y;
return oa_x*ob_x+oa_y*ob_y;
}
double dis(const point &p1,const point &p2){//求两点之间距离
double ans=(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
return sqrt(ans);
}
double dis2(const point &p1,const point &p2){//求两点之间距离的平方
return(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
//点到直线的距离
double disOfPointToLine(point O,line l){
double cos0=dot(l.start,O,l.end)/(dis(O,l.start)*dis(l.start,l.end));
return dis(O,l.start)*sin(acos(cos0));
}
//点在直线上的投影
point shadowPointOfPointToLine(point A,line l){//投影点出了问题
point B = l.start;
point C = l.end;
point D;
vect2 BC = C - B;
vect2 BA = B - A;
vect2 BD = BC * BA /dis2(B,C) * BC;
D = B + BD;
return D;
}