Rating:1763 | 几何基础(3) 求线段交点: 前面已经讲了如何判断两条线段是否相交,现在我们来学下如何求线段的交点坐标 首先先了解下 : 定比分点公式 公式介绍 数学中常用的重要公式之一! 在直角坐标系内,已知两点A(x1,y1),B(x2,y2);在两点连线上有一点P,设它的坐标为(x,y),且向量AP比向量PB的比值为λ,那么我们说P分有向线段AB的比为λ 且P的坐标为 x=(x1 + λ · x2) / (1 + λ) y=(y1 + λ · y2) / (1 + λ) 求得直线 AB 与直线 CD 的交点P? 如此就可求出 :λ 再有公式: x=(x1 + λ · x2) / (1 + λ) y=(y1 + λ · y2) / (1 + λ) 求出坐标.
point jiaodian(line l1,line l2)//求交点 {
double t=fabs(((l1.e-l2.s)^(l1.s-l2.s))/((l1.e-l2.e)^(l1.s-l2.e))); point p; p.x=(l2.s.x+t*l2.e.x)/(1+t); p.y=(l2.s.y+t*l2.e.y)/(1+t); return p; }
完整代码如下 : #include <iostream> #include <cstdio> #include <cmath> using namespace std; const double eps=1e-8; const double PI=acos(-1.0); int sgn(double x) { if(fabs(x)<eps) return 0; if(x < 0) return -1; else return 1; }
struct point { double x,y; point(){} point (double _x,double _y) { x=_x,y=_y; } point operator -(const point &b)const { return point(x-b.x,y-b.y); } point operator +(const point &b)const { return point (x+b.x,y+b.y); } double operator ^(const point &b)const //叉积 { return x*b.y-y*b.x; } double operator *(const point &b)const //点积 { return x*b.x+y*b.y; } void transxy(double B) //绕原点旋转角度B(弧度值),后的x,y { double tx=x,ty=y; x= tx*cos(B) - ty*sin(B); y= tx*sin(B) + ty*cos(B); } };
struct line//线 { point s,e; line(){} line(point _s,point _e) { s=_s,e=_e; } };
double dist(point a,point b)//两点间距离 { return sqrt((a-b)*(a-b)); }
bool inter(line l1,line l2)//判断线段相交 { return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&& max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&& max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&& max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&& sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&& sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0; }
point jiaodian(line l1,line l2)//求交点 {
double t=fabs(((l1.e-l2.s)^(l1.s-l2.s))/((l1.e-l2.e)^(l1.s-l2.e))); point p; p.x=(l2.s.x+t*l2.e.x)/(1+t); p.y=(l2.s.y+t*l2.e.y)/(1+t); return p; } bool inter_line(line l1,line l2)//判断直线与线段是否相交 { return sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0; } int main() { double ax,ay,bx,by,cx,cy,dx,dy; while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy)!=EOF)//分别输入两条线段的首尾端点 { point k1(ax,ay); point k2(bx,by); point k3(cx,cy); point k4(dx,dy); line l1(k1,k2); line l2(k3,k4); if(inter(l1,l2)) { printf("Yes\n"); point p; p=jiaodian(l1,l2); printf("%lf %lf\n",p.x,p.y); } else printf("No\n"); } // printf("%lf %lf\n",ke.x,ke.y); return 0; }
继续更新中…… |