最近在做一个小练习,做一个仿造CAD的软件。
在此最常用的就是要判断鼠标当前位置是否在某个已经画好的图形内。
ps:由于我懒,代码都是直接从我写的源码里拷贝过来的,仅供参考
一个通用的方法(对任何图形都适用),
将多边形相邻顶点到鼠标的点连起来,然后计算出鼠标的点为顶点,多边形相邻顶点为边的角度,这样重复,将每个相邻顶点都这样计算,然后将角度相加,如果和等于360°,则证明在点内。
如图,AOB+BOC+COD+COA==360°既ok。
其他方法
(其实网上图形再点內的方法太多了,我只是写出我的)。
判断点在矩形内
判断矩形再点內,只要确定点的坐标在矩形四个顶点限定的范围内即可。
看图,只要x<=x2&&x>x1&&y>y1&&y<y2就可满足。
//p为点 g.r为矩形
if ((g.r.x1 <= p.x&&g.r.y1 <= p.y&&g.r.x2 >= p.x&&g.r.y2 >= p.y) || (g.r.x1 >= p.x&&g.r.y1 >= p.y&&g.r.x2 <= p.x&&g.r.y2 <= p.y) || (g.r.x1 >= p.x&&g.r.y1 <= p.y&&g.r.x2 <= p.x&&g.r.y2 >= p.y) || (g.r.x1 <= p.x&&g.r.y1 >= p.y&&g.r.x2 >= p.x&&g.r.y2 <= p.y)) return true;//代码中考虑了A,B点的不同分布情况(两个对角线,两种情况,每个对角线AB翻转又是两种 2*2=4)
判断点在线内
由判断点在矩形我们可以想到,若要判断一个点是否在线内,可以线判断点是否在以该线为对角线的矩形内,然后只要判断该点与线段某条端点的连线是否与线段平行即可。(此处我使用向量判断)
//p为点 g.l为线段
if ((g.l.x1 <= p.x&&g.l.y1 <= p.y&&g.l.x2 >= p.x&&g.l.y2 >= p.y) || (g.l.x1 >= p.x&&g.l.y1 >= p.y&&g.l.x2 <= p.x&&g.l.y2 <= p.y) || (g.l.x1 >= p.x&&g.l.y1 <= p.y&&g.l.x2 <= p.x&&g.l.y2 >= p.y) || (g.l.x1 <= p.x&&g.l.y1 >= p.y&&g.l.x2 >= p.x&&g.l.y2 <= p.y)) { double x1, y1, x2, y2; x1 = g.l.x2 - g.l.x1, y1 = g.l.y2 - g.l.y1;//线段的向量 x2 = p.x - g.l.x1, y2 = p.y - g.l.y1;//点与某个端点的向量 if (fabs(x1*y2 - x2 * y1) <= 1000) //double无法用==判断相等 return true; }
判断点在三角行内
如果一个点在三角形内,其与三角形的三个点构成的三个子三角形的面积等于大三角形的面积。否则,大于大三角形的面积。
既S abc=S aob+S boc+S aoc
//p为点 g.t为三角形
double st, s1, s2, s3; st = fabs((g.t.x2 - g.t.x1)*(g.t.y3 - g.t.y2) - (g.t.x3 - g.t.x2)*(g.t.y2 - g.t.y1)); //矩形面积,/2才是三角形面积 s1 = fabs((p.x - g.t.x1)*(g.t.y3 - p.y) - (g.t.x3 - p.x)*(p.y - g.t.y1)); s2 = fabs((g.t.x2 - g.t.x1)*(p.y - g.t.y2) - (p.x - g.t.x2)*(g.t.y2 - g.t.y1)); s3 = fabs((g.t.x2 - p.x)*(g.t.y3 - g.t.y2) - (g.t.x3 - g.t.x2)*(g.t.y2 - p.y)); if (s1 + s2 + s3 - st < 1000) return true;
判断点在圆内
只需要判断圆心到点的距离是否小于等于半径即可
//p为点 g.c为圆
double x, y, l, r; x = (g.c.x1 + g.c.x2) / 2.0, y = (g.c.y1 + g.c.y2) / 2.0; l = (x - p.x)*(x - p.x) + (y - p.y)*(y - p.y); r = g.c.x1 - x > 0 ? g.c.x1 - x : g.c.x2 - x; if (sqrt(l) <= r) //点到圆心的距离小于半径 return true;