#include "MLFuncom.h" #include "MLVector.h" MLFuncom::MLFuncom() { } MLFuncom::~MLFuncom() { } void swap(double& a, double& b) { double tmp; tmp = a; a = b; b = tmp; } //判断两个浮点数据是否相等 bool Equ(double dVal1, double dVal2) { if (abs(dVal2 - dVal1) < DOUBLE_ERROR) return true; return false; } bool Equ(double dVal1, double dVal2, int dot) { if (dot == 0) { return Equ(dVal1, dVal2); } double error = 1.0; for (int i = 0; i < dot; i++) { error *= 0.1; } if (fabs(dVal1 - dVal2) <= error) { return true; } return false; } double GetDistance(const MLPlNode& dpt1, const MLPlNode& dpt2) { double dxa = dpt2.x - dpt1.x; double dya = dpt2.y - dpt1.y; return sqrt(dxa * dxa + dya * dya); } double GetDistance(double dx1, double dy1, double dx2, double dy2) { return sqrt(pow(dx2 - dx1, 2) + pow(dy2 - dy1, 2)); } double GetDistance(const MLPlNode& dpt, const MLPlNode& dpt1, const MLPlNode& dpt2, MLPlNode& dptDest) { MLPoint ptDest; double dis = GetDistance(dpt.toPoint(), dpt1.toPoint(), dpt2.toPoint(), ptDest); dptDest = ptDest.toPlNode(); return dis; } double GetDistance(const MLPoint& dpt, const MLPoint& dpt1, const MLPoint& dpt2, MLPoint& dptDest) { if (Equ(dpt1.x, dpt2.x) && Equ(dpt1.y, dpt2.y)) { dptDest.x = (dpt1.x + dpt2.x) / 2.0; dptDest.y = (dpt1.y + dpt2.y) / 2.0; } else if (Equ(dpt1.x, dpt2.x)) { dptDest.x = (dpt1.x + dpt2.x) / 2.0; dptDest.y = dpt.y; } else if (Equ(dpt1.y, dpt2.y)) { dptDest.x = dpt.x; dptDest.y = (dpt1.y + dpt2.y) / 2.0; } else { double slope1 = (dpt2.y - dpt1.y) / (dpt2.x - dpt1.x); double slope2 = -1.0 / slope1; // 垂线斜率等于直线斜率的负倒数 dptDest.x = (dpt.y - dpt1.y + slope1 * dpt1.x - slope2 * dpt.x) / (slope1 - slope2); dptDest.y = slope1 * (dptDest.x - dpt1.x) + dpt1.y; } if (abs(dpt2.x - dpt1.x) > abs(dpt2.y - dpt1.y)) { if (dpt1.x > dpt2.x) { if (dptDest.x < dpt2.x) dptDest = dpt2; else if (dptDest.x > dpt1.x) dptDest = dpt1; } else { if (dptDest.x < dpt1.x) dptDest = dpt1; else if (dptDest.x > dpt2.x) dptDest = dpt2; } } else { if (dpt1.y > dpt2.y) { if (dptDest.y < dpt2.y) dptDest = dpt2; else if (dptDest.y > dpt1.y) dptDest = dpt1; } else { if (dptDest.y < dpt1.y) dptDest = dpt1; else if (dptDest.y > dpt2.y) dptDest = dpt2; } } return GetDistance(dpt, dptDest); } int LineLine(double L1x1, double L1y1, double L1x2, double L1y2, double* L2x1, double* L2y1, double* L2x2, double* L2y2, bool bExtend1 /*= false*/) { /* 0 两条直线段不相交 1 两条直线段有一个交点,交点坐标通过(*L2x1,*L2y1)返回 2 两第直线段部分后重合,重合段的起终坐标分别通过(*L2x1,*L2y1)和(*L2x2,*L2y2)返回 */ double xx1, xx2, yy1, yy2; double x1, x2, y1, y2, n1, n2, n3, n4; double k1, k2; double oldx = *L2x1; double oldy = *L2y1; //以下第一条直线段的两个顶点按横越坐标由小到大放置在点(xx1,yy1)和(xx2,yy2)中 if (L1x1 > L1x2) { xx1 = L1x2; xx2 = L1x1; yy1 = L1y2; yy2 = L1y1; } else { xx1 = L1x1; xx2 = L1x2; yy1 = L1y1; yy2 = L1y2; } if (fabs(xx1 - xx2) <= 0. && fabs(yy1 - yy2) < 0.) //如果第一直线段两个顶相同,函数返回0 (不相交) return 0; //以下第二第直线段的两个顶点按横坐标由小到大放置在点(x1,y1)和(x2,y2)中 if (*L2x1 > *L2x2) { x1 = *L2x2; x2 = *L2x1; y1 = *L2y2; y2 = *L2y1; } else { x1 = *L2x1; x2 = *L2x2; y1 = *L2y1; y2 = *L2y2; } if (fabs(x1 - x2) <= 0. && fabs(y1 - y2) < 0.) //如果第二直线段两个顶相同,函数返回0 (不相交) return 0; if (fabs(x1 - x2) <= 0. && fabs(xx1 - xx2) <= 0.)//如果两条直线都是坚直线 { if (x1 != xx1) // 两个平行坚直线的横坐标不同,两条直线不相交 return 0; *L2x1 = x1; //得到交点的横坐标 n1 = MIN(yy1, yy2); //第一条直线段的最小纵坐标 n2 = MAX(yy1, yy2); //第一条直线段的最大纵坐标 n3 = MIN(y1, y2); //第二条直线段的最小纵坐标 n4 = MAX(y1, y2); //第二条直线段的最大纵坐标 if (n1 > n4 || n2 < n3) //如果两条横坐标相同的坚直线纵坐标没有交叉,两条直线不相交 return 0; else if (n1 == n4 || n2 == n3) //如果两条横坐标相同的坚直线纵坐标有一点相交(连续) { if (n1 == n4) //如果第一条直线的开如点与第二条直线的终点相同 { *L2y1 = n1; return 1; } if (n2 == n3) //如果第一条直线的终点与第二条直线的起点相同 { *L2y1 = n2; return 1; } } else //如果两条直线的纵坐标重叠 { *L2x2 = x1; *L2y1 = MAX(n1, n3); //重叠直线段的起点坐标 *L2y2 = MIN(n2, n4); //重叠直线段的终点坐标 return 2; } } else if (fabs(x1 - x2) <= 0. && xx1 != xx2) //如果第一条直线是斜线,第二条直线是坚直线 { *L2x1 = x1; //得到交点的横坐标 //if (!(x1 >= xx1 && x1 <= xx2) || !bExtend1) //如果交点横坐标没有在第一条直线段的横坐标范围内,相不交 // return 0; if (!(x1 >= xx1 && x1 <= xx2) || &bExtend1) //如果交点横坐标没有在第一条直线段的横坐标范围内,相不交 return 0; *L2y1 = yy1 + (x1 - xx1) / (xx2 - xx1)*(yy2 - yy1);//计算得到交点的纵坐标 if ((*L2y1 >= y1 && *L2y1 <= y2 || *L2y1 >= y2 && *L2y1 <= y1))//交点纵坐标在第二条直线段坐标范围内 return 1; else { // 要恢复一下,因为下一个函数有可能要用到 *L2x1 = oldx; *L2y1 = oldy; return 0; } } else if ((x1 != x2) && fabs(xx1 - xx2) <= 0.) { *L2x1 = xx1; if (!(xx1 >= x1 && xx1 <= x2)) //如果交点横坐标没有在第二条直线段的横坐标范围内,相不交 return 0; *L2y1 = y1 + (xx1 - x1) / (x2 - x1)*(y2 - y1);//计算得到交点的纵坐标 if (bExtend1) { return 1; } if ((*L2y1 >= yy1 && *L2y1 <= yy2 || *L2y1 >= yy2 && *L2y1 <= yy1))//交点纵坐标在第一条直线段坐标范围内 return 1; else { // 要恢复一下,因为下一个函数有可能要用到 *L2x1 = oldx; *L2y1 = oldy; return 0; } } else //如果两条都是斜线 { //得到两条直线的斜率 k1 = (y2 - y1) / (x2 - x1); k2 = (yy2 - yy1) / (xx2 - xx1); if (k1 == k2) //如果两条直线平行 { if (x1 > xx2 || x2 < xx1) //两条直线横坐标不重叠 return 0; else { //以下分别得到同一横坐标x1下,在两条直线上的纵坐标 n1 = y1 + (0 - x1)*k1; n2 = yy1 + (0 - x1)*k2; if (n1 != n2) return 0; else { n3 = MAX(xx1, x1); n4 = MIN(xx2, x2); *L2x1 = n3; *L2y1 = y1 + (n3 - x1)*k1; if (n3 == n4) return 1; else { *L2x2 = n4; *L2y2 = y1 + (n4 - x1)*k1; return 2; } } } } else ////如果两条直线不平行 { *L2x1 = (yy1 - y1 + x1 * k1 - xx1 * k2) / (k1 - k2); //交点横坐标 *L2y1 = y1 + (*L2x1 - x1)*k1; //交点纵坐标 if (bExtend1)//如果第一直线段允许延长 交点横坐标在第二直线段内 { if (*L2x1 >= x1 && *L2x1 <= x2) return 1; } //如果交点横坐标在两条直线段的横坐标范围内 if ((*L2x1 >= x1 && *L2x1 <= x2) && (*L2x1 >= xx1 && *L2x1 <= xx2)) return 1; else { // 要恢复一下,因为下一个函数有可能要用到 *L2x1 = oldx; *L2y1 = oldy; return 0; } } } return 0; } bool ptInRect(const MLRect& Rect, double dbx, double dby) { if (dbx > Rect.left&& dbx Rect.bottom && dby < Rect.top) return true; return false; } //查找 int bs(double dbKey, MLPline& pline, int nKey/*=3*/) { int num = pline.getCount(); int i1, i2, i; i1 = 0; i2 = num - 1; if (nKey == 3) { if (pline.getTailPt().l >= pline.getHeadPt().l) { if (dbKey > pline.getTailPt().l)return num + 100; if (dbKey < pline.getHeadPt().l)return -100; } else if (pline.getTailPt().l < pline.getHeadPt().l) { if (dbKey < pline.getTailPt().l)return num + 100; if (dbKey > pline.getHeadPt().l)return -100; } if (fabs(dbKey - pline.getHeadPt().l) < 1e-10)return 0; if (fabs(dbKey - pline.getTailPt().l) < 1e-10)return i2 - 1; while (i2 - i1 > 1) { i = (i1 + i2) / 2; if ((dbKey - pline[i].l)*(dbKey - pline[i2].l) > 1e-10) i2 = i; else i1 = i; } } return i1; } double CZ(double x0, double x1, double x2, double y1, double y2) { double s; s = x2 - x1; if (fabs(s) < 1e-30) return y1; s = y1 + (y2 - y1) / s * (x0 - x1); return s; } double cz(double dbKey, int nIndex, MLPline& pline, int nKey1, int nKey2) { double dbVable1 = 0.0, dbVable2 = 0.0; double dbKey1 = 0.0, dbKey2 = 0.0; int nKey = nIndex; if (nKey1 == 3) { dbKey1 = pline[nKey].l; dbKey2 = pline[nKey + 1].l; } /*if(nKey1 ==4) { dbKey1 = pline[nKey].s; dbKey2 = pline[nKey+1].s; }*/ if (nKey2 == 0) { dbVable1 = pline[nKey].x; dbVable2 = pline[nKey + 1].x; } if (nKey2 == 1) { dbVable1 = pline[nKey].y; dbVable2 = pline[nKey + 1].y; } return CZ(dbKey, dbKey1, dbKey2, dbVable1, dbVable2); } // 判断两矩形之间关系 bool CrossRtRt(const MLRect& rect1, const MLRect& rect2) { int nx1, ny1, nx2, ny2; int nx3, ny3, nx4, ny4; nx1 = rect1.left; ny1 = rect1.top; nx2 = rect1.right; ny2 = rect1.bottom; nx3 = rect2.left; ny3 = rect2.top; nx4 = rect2.right; ny4 = rect2.bottom; int m = (nx1 > nx4) | (nx2 < nx3); int n = (ny2 > ny3) | (ny1 < ny4); if (m | n) return false; //不相交 else return true; //相交 //return false; } QString ToString(int nVal) { QString strVal = QString("%1").arg(nVal); return strVal; } QString ToString(double dVal) { QString strVal = QString("%1").arg(dVal); return strVal; } QString ToString(double dVal, int nDotNum) { QString strVal = QString("%1").arg(dVal, 0, 'f', nDotNum); return strVal; }