需求描述
这是一个室内设计网站的需求,在绘制户型特别需要对齐,但是如果绘制者去手动对齐就很麻烦。这就需要软件帮忙,主要是在靠近端点和墙的时候,将绘制点自动挪到端点或墙上,这就是墙体绘制时的吸附功能。一图胜千言,看动图吧!
需求拆分
根据对需求的分析,简而言之就是当足够近的时候,就将绘制点吸附上去,处理点的吸附、墙的吸附两种情况。
实现思路
先简单描述下我怎么处理它:
- 使用所有房间端点,一一遍历
- 先判断点与点之间的吸附(这个优先级更高)
- 求绘制点和端点两点之间的距离,小于某个值,吸附上去,绘制点等于端点,结束,否则进行下一步
- 判断墙的吸附,有两种墙,直的和弯的
- 如果是直型墙(线段),求出绘制点到线段所在的直线的垂足点,在算出绘制点和垂足点两点之间的距离
- 垂足点在线段上且距离够小,同上,亲上去,口误,吸附上去
- 如果是弯的就比较麻烦了。根据弧形的两个端点,和一个控制点(注意不是圆点,这个点是用来调整弧形的弧度)求出圆心
- 连接圆心和绘制点,求出交点,又是熟悉的距离判断,距离够小就吸附。
图示
我觉得你们看我说那么多,我表述能力有很难讲,就贴张图吧。
有没有感觉思路很简单,开始动手拿上就可以完成。我一开始也是这么觉得,可是打开编辑器,啊,天啊,我算不来,这哪里是编程,这明明是写数学题,但是这种中学数学我早忘记了,对于数学,我只有小学水平了吧。 在恶补一堆数学知识(其实都有公式)终于开始动笔了,下面就来展现下恶补的数学知识。其实这个功能的主要点就在于求点到点的距离,点到线段的距离,点到弧线的距离。点到点的距离
这个根据那个著名的勾股定律写成的,最简单的,后面的都好麻烦,我不想写了,算了,坚持下
static distance(pt1: Point, pt2: Point): number {
return Math.sqrt((pt1.x - pt2.x) * (pt1.x - pt2.x) + (pt1.y - pt2.y) * (pt1.y - pt2.y));
}
复制代码
点到线段的距离
已知直线上两点求直线的一般式方程
点到直线的距离公式 当时写的时候和这两个公式有一点变形,但就是这个意思哈。 public static pointToLineDistance(p1: Point, p2: Point, p3: Point): number {
let a: number = Math.pow(1 / Point.distance(p1, p2), 0.5);
let distance: number = 0;
distance = Math.abs(a * ((p2.x - p1.x) * p3.y - (p2.y - p1.y) * p3.x - p1.y * p2.x + p1.x * p2.y));
distance = Math.pow(distance, 0.5);
return distance;
}
复制代码
点到弧线的距离
三点(x1,y1),(x2,y2),(x3,y3)
代码就不贴了,相信你们懂得,求出圆心和半径,只要求出绘制点和圆心的距离减掉半径就是与弧形墙的距离了,再判断下距离即可。
废话
讲真的,这些东西,我写过一遍,我也记不住,我大概是个废人了,可是不知道为啥,我和别人面试不太一样,他们就喜欢问我数学相关的知识,一问我就挂,还有算法,我也不会(我为什么这么菜鸡呢),我就偶尔用用的那几个知道些,下次再写篇文章将有向图在户型绘制里的应用吧!
最后,感谢谭老大的帮忙!!!