只支持直線段的多段線檢查,由於主要用了初中的知識,一元一次方程求交點,詳細的說就是,把多段線上相鄰的兩個點構成一條直線段,而後每條直線段與剩餘的直線段求交點,一條直線段就表明一個一元一次方程,知道兩點就知道這個方程是什麼樣的。
求出交點以後得判斷這個點是不是多段線上自己的點,判斷方法是判斷求出來的交點與構成交點的兩條直線段的4個點作比較,若是點的偏差在1e-4以內,就認爲這個交點是在多段線的端點上,不做爲要求的交點。
除了這種可能以外,所求交點有多是在直線段的延長線上,經過觀察能夠知道,若是交點在任意一條直線段兩個端點之間,則能夠知道這個交點到這條直線段兩個端點的距離都要小於這個直線段兩個端點的距離,若是交點到兩個端點的距離大於了兩個端點的距離,則說明這個交點是在線段的延長線上,也不做爲要求的交點。
還須要注意的地方是,要考慮直線段垂直於x軸的狀況,由於要求直線方程時的斜率時,分母不能爲0,須要把直線垂直於x軸的狀況單獨考慮。
除了這種思路外,還能夠直接使用intersectwith函數來作,相交類型是都不延長,(不知是直接炸開這個多段線好,仍是分割這個多段線好)。總之首先得獲得兩個端點之間的線段。這樣做,不只支持直線段的多段線,還支持帶凸度的,帶圓弧的多段線了。
下面放出使用到的函數:函數
static bool IsEqual(const AcGePoint2d & firstPoint, const AcGePoint2d & secondPoint, double tol) { return (fabs(firstPoint.x - secondPoint.x) < tol&& fabs(firstPoint.y - secondPoint.y) < tol); }
struct StLine { AcGePoint2d ptPre; AcGePoint2d ptNext; };
static bool JiaoDian(StLine &l1, StLine &l2, AcGePoint3d& ptCenter) { double x0, y0, x1, y1, x2, y2, x3, y3; x0 = l1.ptPre.x; y0 = l1.ptPre.y; x1 = l1.ptNext.x; y1 = l1.ptNext.y; x2= l2.ptPre.x; y2 = l2.ptPre.y; x3 = l2.ptNext.x; y3 = l2.ptNext.y; if (x0 - x1 == 0) { if (x2 - x3 == 0) { if (IsEqual(l1.ptPre, l2.ptPre, 1e-4) || IsEqual(l1.ptPre, l2.ptNext, 1e-4) || IsEqual(l1.ptNext, l2.ptPre, 1e-4) || IsEqual(l1.ptNext, l2.ptNext, 1e-4)) { acutPrintf(L"存在重疊的部分\n"); return false; } else { acutPrintf(L"存在平行的部分\n"); return false; } } else { double k2 = (y3 - y2) / (x3 - x2); double b2 = (y2 - k2*x2); AcGePoint2d jd; jd.x = x0; jd.y = k2*x0 + b2; double distance = l1.ptPre.distanceTo(l1.ptNext); double dis1 = jd.distanceTo(l1.ptPre); double dis2 = jd.distanceTo(l1.ptNext); if (dis1 < distance&&dis2 < distance) { if (IsEqual(l1.ptPre, jd, 1e-4) || IsEqual(jd, l2.ptNext, 1e-4) || IsEqual(l1.ptNext, jd, 1e-4) || IsEqual(jd, l2.ptPre, 1e-4)) { return false; } ptCenter.x = jd.x; ptCenter.y = jd.y; ptCenter.z = 0; return true; } else { return false; } } } else if (x3 - x2 == 0) { if (x0 - x1 != 0) { double k2 = (y1 - y0) / (x1 - x0); double b2 = (y1 - k2*x1); AcGePoint2d jd; jd.x = x3; jd.y = k2*x3 + b2; double distance = l1.ptPre.distanceTo(l1.ptNext); double dis1 = jd.distanceTo(l1.ptPre); double dis2 = jd.distanceTo(l1.ptNext); if (dis1 < distance&&dis2 < distance) { if (IsEqual(l1.ptPre, jd, 1e-4) || IsEqual(jd, l2.ptNext, 1e-4) || IsEqual(l1.ptNext, jd, 1e-4) || IsEqual(jd, l2.ptPre, 1e-4)) { return false; } ptCenter.x = jd.x; ptCenter.y = jd.y; ptCenter.z = 0; return true; } //交點在延長線上 else { return false; } } else { if (IsEqual(l1.ptPre, l2.ptPre, 1e-4) || IsEqual(l1.ptPre, l2.ptNext, 1e-4) || IsEqual(l1.ptNext, l2.ptPre, 1e-4) || IsEqual(l1.ptNext, l2.ptNext, 1e-4)) { acutPrintf(L"存在重疊的部分\n"); return false; } else { acutPrintf(L"存在平行的部分\n"); return false; } } } else { double k1 = (y1 - y0) / (x1 - x0); double b1 = (y1 - k1*x1); double k2 = (y3 - y2) / (x3 - x2); double b2 = (y2 - k2*x2); AcGePoint2d jd; if (k1 == k2) { return false; } double x0 = (b2 - b1) / (k1 - k2); jd.x = x0; jd.y = k1*x0 + b1; double distance = l1.ptPre.distanceTo(l1.ptNext); double dis1 = jd.distanceTo(l1.ptPre); double dis2 = jd.distanceTo(l1.ptNext); if (dis1 < distance&&dis2 < distance) { if (IsEqual(l1.ptPre, jd, 1e-4) || IsEqual(jd, l2.ptNext, 1e-4) || IsEqual(l1.ptNext, jd, 1e-4) || IsEqual(jd, l2.ptPre, 1e-4)) { return false; } ptCenter.x = jd.x; ptCenter.y = jd.y; ptCenter.z = 0; return true; } else { return false; } } }