最近在搞图片编辑功能,发现有意思地方,也花费不少时间精力,今天mark下
图片编辑功能,很重要一个细节,就是要判断当前鼠标坐标是否落在某个图形上
最简单的做法,就是求得图像的边缘矩形框,然后判断是否包含该点,如:
红色框就是直线的边缘,
很显然这不是我们想要的
- 首先范围太大了,会遮挡其他“元件”的范围,实际使用体验效果非常差
- 第二对于水平方向或接近水平向的直线,范围又太小了,垂直方向也是同样问题。实际结果是判断不到范围
实际上,我们想要效果应该是这样的:
如图,虚线所示,这个才是我们想要的边缘效果。
那么问题来了,回归到数学知识了,如何生成这个虚线呢?(如何获取这些点)
首先,看下已知条件:
1. 线段的两个点,start、end点,的坐标是已知的
2. 那么,线段长度L也是已知的
3. 线段与X轴夹角a也是已知(与Y轴夹角b也是已知,且存在a+b=90°关系)
4. 虚线与直线是平行关系,且与线段的距离 s 也是已知的
那么存在如下关系:
那么,平行线的起点、终点的坐标都知道了
这个方法比较简单,效果也很好
利用相似三角形原理
翠花上code
QLineF line(start,end);
qreal distance = abs(line.length());
QPointF p1,p2,p3,p4,p5,p6;
//
qreal dy = abs(start.y() - end.y()) * len / distance;
qreal dx = abs(start.x() - end.x()) * len / distance;
QPointF newStart = start;
QPointF newEnd = end;
if(start.x() > end.x())
{
newStart = end;
newEnd = start;
}
if(newStart.y() >= newEnd.y())
{
p1.setX(newStart.x() - dy);
p1.setY(newStart.y() - dx);
p2.setX(newStart.x() - dx);
p2.setY(newStart.y() + dy);
p3.setX(newStart.x() + dy);
p3.setY(newStart.y() + dx);
p4.setX(newEnd.x() + dy);
p4.setY(newEnd.y() + dx);
p5.setX(newEnd.x() + dx);
p5.setY(newEnd.y() - dy);
p6.setX(newEnd.x() - dy);
p6.setY(newEnd.y() - dx);
}
else
{
p1.setX(newStart.x() + dy);
p1.setY(newStart.y() - dx);
p2.setX(newStart.x() - dx);
p2.setY(newStart.y() - dy);
p3.setX(newStart.x() - dy);
p3.setY(newStart.y() + dx);
p4.setX(newEnd.x() - dy);
p4.setY(newEnd.y() + dx);
p5.setX(newEnd.x() + dx);
p5.setY(newEnd.y() + dy);
p6.setX(newEnd.x() + dy);
p6.setY(newEnd.y() - dx);
}
points << p1 << p2 << p3 << p4 << p5 << p6;