opencv检测相交点_opencv线段相交怎么判断

展开全部

#include "cvxcg.h"

#include 

#include 

//====================================================================

//====================================================================

// 判断32313133353236313431303231363533e59b9ee7ad9431333363366137某一与线段共线的点是否在线段上

static

bool icvxIsOnSegment(CvPoint pi, CvPoint pj, CvPoint pk)

{

int minx = (pi.x 

int maxx = (pi.x > pj.x)? pi.x: pj.x;

int miny = (pi.y 

int maxy = (pi.y > pj.y)? pi.y: pj.y;

// 点pk已经确定和线段直线共线

return pk.x >= minx && pk.x <= maxx

&& pk.y >= miny && pk.y <= maxy;

}

//====================================================================

//====================================================================

// 判断(pi->pj->pk)的方向

int cvxDirection(CvPoint pi, CvPoint pj, CvPoint pk)

{

int x1 = pk.x - pi.x;

int y1 = pk.y - pi.y;

int x2 = pj.x - pi.x;

int y2 = pj.y - pi.y;

return x1*y2 - x2*y1;

}

// 判断线段是否相交

bool cvxIsIntersect(CvPoint p1, CvPoint p2,

CvPoint p3, CvPoint p4,

CvPoint2D32f *px)

{

// 计算线段的相对位置

int d1 = cvxDirection(p3, p4, p1);

int d2 = cvxDirection(p3, p4, p2);

int d3 = cvxDirection(p1, p2, p3);

int d4 = cvxDirection(p1, p2, p4);

// 每个线段都跨越另一个线段的直线

if(((d1 > 0 && d2  0))

&& ((d3 > 0 && d4  0)))

{

if(px != NULL)

{

// 计算交点(没有验证)

int d  = (p2.y-p1.y)*(p4.x-p3.x)-(p4.y-p3.y)*(p2.x-p1.x);

int tx = (p2.x-p1.x)*(p4.x-p3.x)*(p3.y-p1.y) +

(p2.y-p1.y)*(p4.x-p3.x)*p1.x -

(p4.y-p3.y)*(p2.x-p1.x)*p3.x;

int ty = (p2.y-p1.y)*(p4.y-p3.y)*(p3.x-p1.x) +

(p2.x-p1.x)*(p4.y-p3.y)*p1.y -

(p4.x-p3.x)*(p2.y-p1.y)*p3.y;

px->x =  1.f * tx/d;

px->y = -1.f * ty/d;

}

return true;

}

// 线段某个端点位于另一个线段上

if(d1 == 0 && icvxIsOnSegment(p3, p4, p1))

{

if(px != NULL) *px = cvPoint2D32f(p1.x, p1.y);

return true;

}

if(d2 == 0 && icvxIsOnSegment(p3, p4, p2))

{

if(px != NULL) *px = cvPoint2D32f(p2.x, p2.y);

return true;

}

if(d3 == 0 && icvxIsOnSegment(p1, p2, p3))

{

if(px != NULL) *px = cvPoint2D32f(p3.x, p3.y);

return true;

}

if(d4 == 0 && icvxIsOnSegment(p1, p2, p4))

{

if(px != NULL) *px = cvPoint2D32f(p4.x, p4.y);

return true;

}

// 不相交

return false;

}

//====================================================================

//====================================================================

// 判断多边形是否自交

bool cvxCheckPolygonSelfIntersect(const CvPoint *pts, int nPoints)

{

assert(pts != NULL);

assert(nPoints >= 3); // 多边形至少3个顶点

// 每条线段单独判断

for(int i = 0; i 

{

int p1 = (i+0)%nPoints;

int p2 = (i+1)%nPoints;

for(int j = 0; j 

{

int p3 = (j+0)%nPoints;

int p4 = (j+1)%nPoints;

// 两个线段不相邻

if(p3 == p1 || p3 == p2) continue;

if(p4 == p1 || p4 == p2) continue;

// 如果i和j对应的线段相交, 则返回

if(cvxIsIntersect(pts[p1], pts[p2], pts[p3], pts[p4]))

return true;

}

}

// 没有自交

return false;

}

// 判断多边形是否是顺时针方向

bool cvxCheckPolygonClockwise(const CvPoint *Pts, int nPoints)

{

assert(Pts != NULL);

assert(nPoints >= 3); // 多边形至少3个顶点

// 多边形不自交

assert(!cvxIsSelfIntersect(Pts, nPoints));

// 寻找一条所有顶点都在其一侧的边

for(int i = 0; i 

{

int p1 = i;

int p2 = (i+1)%nPoints;

int px = (i+2)%nPoints;

// 第一个不相邻的点

int d = cvxDirection(Pts[p1], Pts[p2], Pts[px]);

// 确定方向

int flag = (d > 0);

// 判断剩余的点(除去第一个不相邻的点)

int j;

for(j = 0; j 

{

int k = (px+j)%nPoints;

// p1, p2, px点除外

if(k == p1 || k == p2 || k == px) continue;

// 判断方向是否一致

int f = (cvxDirection(Pts[p1], Pts[p2], Pts[k]) > 0);

// 如果方向不同则终止

if(flag ^ f) break;

}

// 如果判断结束, 则返回结果

// 如果点始终在左边, 则为逆时针

if(j >= nPoints) return (!flag);

}

// 不可能执行到这里

assert(false);

return false;

}

你可能感兴趣的:(opencv检测相交点)