2D简单图形相关算法罗列
??? 因?yàn)槠匠T赒t開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)與一些簡(jiǎn)單的2D幾何圖形打交道,因此學(xué)習(xí)和掌握一些基本的2D幾何計(jì)算還是很有必要的,在這里羅列一些常用的基本情況,之后會(huì)適時(shí)補(bǔ)充。
[1] 兩點(diǎn)之間距離,根據(jù)兩個(gè)點(diǎn)的差值算出對(duì)應(yīng)的向量,然后算出這個(gè)向量的斜邊開(kāi)放即這兩點(diǎn)的距離。
qreal distance(const QPointF &pt1, const QPointF &pt2) {QPointF offset = pt1 - pt2;return sqrt(offset.x() * offset.x() + offset.y() * offset.y()); }[2]? 計(jì)算兩條直線的交點(diǎn)
QPointF intersection(const QPointF &pt1, const QPointF &pt2, const QPointF &pt3, const QPointF &pt4) {// 首先根據(jù)兩點(diǎn)式 (y - y1) / (y2 - y1) = (x - x1) / (x2 - x1)// 得出 y = (y2 - y1) / (x2 - x1)(x - x1) + y1// 其中(y2 - y1) / (x2 - x1)為斜率k// 即 y = k(x - x1) + y1// 兩線平行即k1 == k2// 一線平行y即 p1.x == p2.xint state -- 標(biāo)志位 用來(lái)進(jìn)行簡(jiǎn)單的情況判斷if (pt1.x() != pt2.x()){a = (p2.y() - p1.y()) / (p2.x() - p1.x());state |= 1; // 1即01 }if (pt3.x() != pt4.x()){b = (p4.y() - p3.y()) / (p4.x() - p3.x());state |= 2; // 2即10 }switch(sate){case 0: // 既不是01也不是10,即兩線同時(shí)平行于Yreturn QPointF();case 1: // 第一條直線斜線,第二條直線平行于Yfloat x = p3.x();float y = a * x - a * p1.x() + p1.y();return QPointF(x, y);case 2: // 第二條直線斜線,第一條直線平行于Yfloat x = p1.x();float y = b * x - a * p3.x() + p3.y();return QPointF(x, y);case 3: // 兩條直線都存在斜率if (a == b)return QPointF();float x = (a * p1.x() - b * p3.x() - p1.y() + p3.y()) / (a - b);float y = a * x - a * p1.x() + p1.y();return QPointF(x, y); } }[3] 返回一點(diǎn)到直線的垂直交點(diǎn)的坐標(biāo)
QPointF Formula::verticalCrossPoint(const QPointF &pt1, const QPointF &pt2, const QPointF &pt3){
if((fabs(pt1.x() - pt2.x()) < 1e-6)) // 判斷是否平行于Y軸 {return QPointF(pt1.x(), pt3.y());}// 直線 y = ax + b, 垂線則為 -ay = x - m // 直線斜率為k,垂線斜率為-1/kqreal a = (pt1.y()- pt2.y()) / (pt1.x()- pt2.x());qreal b = (pt1.y()- a * pt1.x());qreal m = pt3.x() + a * pt3.y();// 硬解求出交點(diǎn) QPointF ptCross;ptCross.setX((m - a * b) / (a * a + 1));ptCross.setY(a * ptCross.x() + b);return ptCross
}
[4]? 判斷點(diǎn)是否在直線上,需要注意的是,浮點(diǎn)數(shù)與0的比較通常為 < 1e-6。
bool isPointInLIne(const QPointF &pt1, const QPointF &pt2, const QPointF &pt3) {if((fabs(pt1.x() - pt2.x()) < 1e-6)) // 判斷是否平行于Y軸 {return (fabs(pt1.x() - pt3.x()) < 1e-6);}// 因?yàn)?y = ax + b qreal A = (pt1.y()- pt2.y()) / (pt1.x()- pt2.x());qreal B = (pt1.y()- A*pt1.x());return (fabs(A * pt3.x() - pt3.y() + B) < 1e-6); }[5] 根據(jù)直線的橫坐標(biāo)來(lái)求點(diǎn)
QPointF getPointInLineByX(const QPointF &pt1, const QPointF &pt2, qreal x) {if((fabs(pt1.x() - pt2.x()) < 1e-6)) // 是否平行于Y {return pt1;}if((fabs(pt1.y() - pt2.y()) < 1e-6)) // 是否平行于X {return QPointF(x, pt1.y());}// y = ax + bqreal A = (pt1.y()- pt2.y()) / (pt1.x()- pt2.x());qreal B = (pt1.y()- A*pt1.x());return QPointF(x, (A * x + B));}
?[6] 根據(jù)直線的縱坐標(biāo)來(lái)求點(diǎn)
QPointF getPointInLineByY(const QPointF &pt1, const QPointF &pt2, qreal y) {if((fabs(pt1.x() - pt2.x()) < 1e-6)) {return QPointF(pt1.x(), y);}if((fabs(pt1.y() - pt2.y()) < 1e-6)){return pt1;}// y = ax + bqreal A = (pt1.y()- pt2.y()) / (pt1.x()- pt2.x());qreal B = (pt1.y()- A*pt1.x());return QPointF((qreal)(y - B) / A, y );}?[7] 橢圓周長(zhǎng)
// 橢圓周長(zhǎng):L = 2 π b + 4(a-b) // a表示橢圓長(zhǎng)半軸的長(zhǎng),b表示橢圓短半軸的長(zhǎng),且a>b>0 qreal ellipsePerimeter(qreal a, qreal b) {qreal l = a / 2, s = b / 2;if(a < b){l = b / 2;s = a / 2;}return 2 * M_PI * s + 4 * (l - s); }[8] 橢圓面積
// 橢圓的面積:S=π×a×b // π圓周率,a是橢圓的長(zhǎng)半軸,b是短半軸的長(zhǎng) qreal ellipseArea(qreal a, qreal b) {return M_PI * a * b / 4; }[9] 上下左右反轉(zhuǎn),返回變換矩陣
QTransform flipTransform(bool up,bool left) {int xSign = left ? 1 : -1;int ySign = up ? 1 : -1;return QTransform (xSign, 0, 0,0, ySign, 0,0, 0, 1); }[10] 根據(jù)兩點(diǎn)直線,獲取從x軸正方向轉(zhuǎn)換到該直線的變換矩陣
QTransform rotateTransform(const QPointF &fromPos, const QPointF& toPos) {QVector2D directionVec = QVector2D(toPos) - QVector2D(fromPos);const qreal hypotenuse = directionVec.length();QTransform rotateTransfrom;if (hypotenuse!=0) {const qrealangleCos = directionVec.x() / hypotenuse,angleSin = directionVec.y() / hypotenuse;rotateTransfrom=QTransform(angleCos,angleSin, 0,-angleSin, angleCos, 0,0, 0, 1);}return rotateTransfrom; }?
轉(zhuǎn)載于:https://www.cnblogs.com/rickyk/p/3981689.html
總結(jié)
以上是生活随笔為你收集整理的2D简单图形相关算法罗列的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 矩阵快速幂---BestCoder Ro
- 下一篇: 5. SQL Server数据库性能监控