因为平常在Qt开发过程中经常会与一些简单的2D几何图形打交道,因此学习和掌握一些基本的2D几何计算还是很有必要的,在这里罗列一些常用的基本情况,之后会适时补充。

[1] 两点之间距离,根据两个点的差值算出对应的向量,然后算出这个向量的斜边开放即这两点的距离。

qreal distance(const QPointF &pt1, const QPointF &pt2)
{
QPointF offset = pt1 - pt2;
return sqrt(offset.x() * offset.x() + offset.y() * offset.y());
}

[2]  计算两条直线的交点

QPointF intersection(const QPointF &pt1, const QPointF &pt2, const QPointF &pt3, const QPointF &pt4)
{
// 首先根据两点式 (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.x
int state -- 标志位 用来进行简单的情况判断
if (pt1.x() != pt2.x())
{
a = (p2.y() - p1.y()) / (p2.x() - p1.x());
state |= ; // 1即01
}
if (pt3.x() != pt4.x())
{
b = (p4.y() - p3.y()) / (p4.x() - p3.x());
state |= ; // 2即10
}
switch(sate)
{
case : // 既不是01也不是10,即两线同时平行于Y
return QPointF();
case : // 第一条直线斜线,第二条直线平行于Y
float x = p3.x();
float y = a * x - a * p1.x() + p1.y();
return QPointF(x, y);
case : // 第二条直线斜线,第一条直线平行于Y
float x = p1.x();
float y = b * x - a * p3.x() + p3.y();
return QPointF(x, y);
case : // 两条直线都存在斜率
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] 返回一点到直线的垂直交点的坐标

QPointF Formula::verticalCrossPoint(const QPointF &pt1, const QPointF &pt2, const QPointF &pt3)
{
if((fabs(pt1.x() - pt2.x()) < 1e-)) // 判断是否平行于Y轴
{
return QPointF(pt1.x(), pt3.y());
}
// 直线 y = ax + b, 垂线则为 -ay = x - m
// 直线斜率为k,垂线斜率为-1/k
qreal a = (pt1.y()- pt2.y()) / (pt1.x()- pt2.x());
qreal b = (pt1.y()- a * pt1.x()); qreal m = pt3.x() + a * pt3.y(); // 硬解求出交点
QPointF ptCross;
ptCross.setX((m - a * b) / (a * a + ));
ptCross.setY(a * ptCross.x() + b);
return ptCross
}

[4]  判断点是否在直线上,需要注意的是,浮点数与0的比较通常为 < 1e-6。

bool isPointInLIne(const QPointF &pt1, const QPointF &pt2, const QPointF &pt3)
{
if((fabs(pt1.x() - pt2.x()) < 1e-)) // 判断是否平行于Y轴
{
return (fabs(pt1.x() - pt3.x()) < 1e-);
} // 因为 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-);
}

[5] 根据直线的横坐标来求点

QPointF getPointInLineByX(const QPointF &pt1, const QPointF &pt2, qreal x)
{ if((fabs(pt1.x() - pt2.x()) < 1e-)) // 是否平行于Y
{
return pt1;
} if((fabs(pt1.y() - pt2.y()) < 1e-)) // 是否平行于X
{
return QPointF(x, pt1.y());
} // y = ax + b
qreal A = (pt1.y()- pt2.y()) / (pt1.x()- pt2.x());
qreal B = (pt1.y()- A*pt1.x()); return QPointF(x, (A * x + B));
}

[6] 根据直线的纵坐标来求点

QPointF getPointInLineByY(const QPointF &pt1, const QPointF &pt2, qreal y)
{ if((fabs(pt1.x() - pt2.x()) < 1e-))
{
return QPointF(pt1.x(), y);
} if((fabs(pt1.y() - pt2.y()) < 1e-))
{
return pt1;
} // y = ax + b
qreal A = (pt1.y()- pt2.y()) / (pt1.x()- pt2.x());
qreal B = (pt1.y()- A*pt1.x()); return QPointF((qreal)(y - B) / A, y ); }

[7] 椭圆周长

// 椭圆周长:L = 2 π b + 4(a-b)
// a表示椭圆长半轴的长,b表示椭圆短半轴的长,且a>b>0
qreal ellipsePerimeter(qreal a, qreal b)
{
qreal l = a / , s = b / ;
if(a < b)
{
l = b / ;
s = a / ;
} return * M_PI * s + * (l - s);
}

[8] 椭圆面积

// 椭圆的面积:S=π×a×b
// π圆周率,a是椭圆的长半轴,b是短半轴的长
qreal ellipseArea(qreal a, qreal b)
{
return M_PI * a * b / ;
}

[9] 上下左右反转,返回变换矩阵

QTransform flipTransform(bool up,bool left)
{
int xSign = left ? : -;
int ySign = up ? : -; return QTransform
(xSign, , ,
, ySign, ,
, , );
}

[10] 根据两点直线,获取从x轴正方向转换到该直线的变换矩阵

QTransform rotateTransform(const QPointF &fromPos, const QPointF& toPos)
{
QVector2D directionVec = QVector2D(toPos) - QVector2D(fromPos); const qreal hypotenuse = directionVec.length(); QTransform rotateTransfrom; if (hypotenuse!=)
{
const qreal
angleCos = directionVec.x() / hypotenuse,
angleSin = directionVec.y() / hypotenuse; rotateTransfrom=QTransform
(angleCos,angleSin, ,
-angleSin, angleCos, ,
, , );
} return rotateTransfrom;
}

2D简单图形相关算法罗列的更多相关文章

  1. 盘点十大GIS相关算法

    1.道格拉斯-普克算法(Douglas–Peucker) 道格拉斯-普克算法(Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法.迭代适应点算法.分裂与合并算法)是将曲 ...

  2. 学习笔记:HTML5 Canvas绘制简单图形

    HTML5 Canvas绘制简单图形 1.添加Canvas标签,添加id供js操作. <canvas id="mycanvas" height="700" ...

  3. iPhone之Quartz 2D系列--图形上下文(2)(Graphics Contexts)

    以下几遍关于Quartz 2D博文都是转载自:http://www.cocoachina.com/bbs/u.php?action=topic&uid=38018 iPhone之Quartz ...

  4. [ASP.NET] 图形验证码破解-以简单图形为例

    原文 http://www.dotblogs.com.tw/joysdw12/archive/2013/06/08/captcha-cracked.aspx 前言 这次来讲个比较有趣的主题,就是该如何 ...

  5. GIS开发 图形常见算法

    摘录:OSGeo中国中心 http://www.osgeo.cn/post/ae457 计算机的出现使得很多原本十分繁琐的工作得以大幅度简化,但是也有一些在人们直观看来很容易的问题却需要拿出一套并不简 ...

  6. [java,2017-05-15] 内存回收 (流程、时间、对象、相关算法)

    内存回收的流程 java的垃圾回收分为三个区域新生代.老年代. 永久代 一个对象实例化时 先去看伊甸园有没有足够的空间:如果有 不进行垃圾回收 ,对象直接在伊甸园存储:如果伊甸园内存已满,会进行一次m ...

  7. UCI机器学习库和一些相关算法(转载)

    UCI机器学习库和一些相关算法 各种机器学习任务的顶级结果(论文)汇总 https://github.com//RedditSota/state-of-the-art-result-for-machi ...

  8. 采样方法(二)MCMC相关算法介绍及代码实现

    采样方法(二)MCMC相关算法介绍及代码实现 2017-12-30 15:32:14 Dark_Scope 阅读数 10509更多 分类专栏: 机器学习   版权声明:本文为博主原创文章,遵循CC 4 ...

  9. sklearn简单实现机器学习算法记录

    sklearn简单实现机器学习算法记录 需要引入最重要的库:Scikit-learn 一.KNN算法 from sklearn import datasets from sklearn.model_s ...

随机推荐

  1. java学习之函数

    讲完了语句结构还有运算符.变量,下面我们来了解下函数. 那么什么是函数,函数的定义是怎样的呢? 函数的定义: 函数是指在类当中定义的一段有特殊功能的代码段,同时函数在类中也被成为方法. class F ...

  2. Unity 技能按钮触发特效

    unity 版本:4.5.1 NGUI版本:3.6.5 首先,要导入特效资源包,导入应该是基本中的基础,但是对于初学者来说好像很少有这方面的介绍,也许是我现学现用书看的不够认真,因为导入这个问题卡了好 ...

  3. weblogic服务器保存图片失败解决办法

    日志中报错如下: java.lang.NoClassFoundError: Could not initialize class sun.awt.X11GraphicsEnvironment 解决办法 ...

  4. delphi笔记之nativeXml 转

    delphi笔记之nativeXml   使用 CreateName 建立可直接指定根节点的名称 var XmlDoc: TnativeXml; Node:TxmlNode; Begin XmlDoc ...

  5. C数组的相关知识

    数组的定义:具有相同数据类型的集合.在内存中开辟连续的存贮空间,从上往下,依次存储 补充:内存是以字节位单位的存储空间,内存中的每一个字节都唯一对应一个编号.这个编号就是地址.只要是存在内存中的数据都 ...

  6. ASIHttpRequest或者SDWebImage给UIImageView加载图片的逻辑是什么样子的

    非常非常喜欢SDWebImage,就算后来AF也做了图片缓存,我也还是一直使用.图片缓存真的是一件令人头疼的事,但是SDWebImage封装了一切,你所需要的只是简单的set一个URL:1.设置一个展 ...

  7. Hive 创建和生成Rcfile 和SequenceFile格式的表

    rcfile格式表需要从原始的textfile 文件格式表导出数据并导入到新建好的rcfile格式表里 转: HIVE RCFile高效存储结构 创建rcfile 格式的表: CREATE TABLE ...

  8. windows7实用快捷键 分类: windows常用小技巧 2014-04-18 14:34 169人阅读 评论(0) 收藏

    几个比较实用的快捷键 windows键:简写成win win+   方向键上下,可以使当前窗体放大或缩小 win+   方向键左右,可以使当前窗体悬靠在左边或右边 win+Home   仅保留当前窗体 ...

  9. C++ 求阶乘 四种方法

    来总结下求阶乘的各种方法哈. 写在最前:①各个代码仅仅是提供了求阶乘的思路,以便在实际须要时再来编码,代码并不健壮!②各个程序都在1到10内測试正确. 代码一: #include<iostrea ...

  10. 谈谈iOS中粘性动画以及果冻效果的实现

    在最近做个一个自定义PageControl——KYAnimatedPageControl中,我实现了CALayer的形变动画以及CALayer的弹性动画,效果先过目: https://github.c ...