如何判断点位于平行四边形内?

凌乱哥 2017-09-08 06:29:04
CRect有一个PtInRect函数,但是适用于矩形,那么普通的平行四边形该怎么判断

图例:

...全文
1195 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2017-09-12
  • 打赏
  • 举报
回复

//****************************************************************************************
//  求二条直线的交点的公式
//  有如下方程    a1*x+b1*y=c1
//                a2*x+b2*y=c2
//                x= | c1 b1|  / | a1 b1 |      y= | a1 c1| / | a1 b1 |
//                   | c2 b2|  / | a2 b2 |         | a2 c2| / | a2 b2 |
//
//   a1= (L1.pEnd.y-L1.pStart.y)   
//   b1= (L1.pEnd.x-L1.pStart.x)
//   c1= L1.pStart.x*(L1.pEnd.y-L1.pStart.y)-(L1.pEnd.x-L1.pStart.x)*L1.pStart.y
//   a2= (L2.pEnd.y-L2.pStart.y)   
//   b2= (L2.pEnd.x-L2.pStart.x)
//   c2= L2.pStart.x*(L2.pEnd.y-L2.pStart.y)-(L2.pEnd.x-L2.pStart.x)*L2.pStart.y  
CPoint CDrawLinesView::CrossPoint(const LINE *line1, const LINE *line2)
{
//	if(!SegmentIntersect(line1->pStart, line1->pEnd, line2->pStart, line2->pEnd))
//	{// segments not cross	
//		return 0;
//	}
	CPoint pt;
// line1's cpmponent
	double X1=line1->pEnd.x-line1->pStart.x;//b1
	double Y1=line1->pEnd.y-line1->pStart.y;//a1
// line2's cpmponent
	double X2=line2->pEnd.x-line2->pStart.x;//b2
	double Y2=line2->pEnd.y-line2->pStart.y;//a2
// distance of 1,2
	double X21=line2->pStart.x-line1->pStart.x;
	double Y21=line2->pStart.y-line1->pStart.y;
// determinant
	double D=Y1*X2-Y2*X1;// a1b2-a2b1
// 
	if(D==0) return 0;
// cross point
	pt.x=(X1*X2*Y21 + Y1*X2*line1->pStart.x - Y2*X1*line2->pStart.x)/D;
// on screen y is down increased ! 
	pt.y=-(Y1*Y2*X21 + X1*Y2*line1->pStart.y - X2*Y1*line2->pStart.y)/D;
// segments intersect.
	if ((abs(pt.x-line1->pStart.x-X1/2) <= abs(X1/2)) &&
	    (abs(pt.y-line1->pStart.y-Y1/2) <= abs(Y1/2)) &&
		(abs(pt.x-line2->pStart.x-X2/2) <= abs(X2/2)) &&
		(abs(pt.y-line2->pStart.y-Y2/2) <= abs(Y2/2)) )
	{
		return pt;
	}
	return 0;
}
mk_lucifer 2017-09-11
  • 打赏
  • 举报
回复
引用 18 楼 summergo123321 的回复:
直线相交,其实和GDI的画刷填充是同一个原理,只不过他的直线总是水平的,从左到右开始填充画刷,碰见第1个Path点还是填充像素,碰到第二个Path交点停止关闭填充像素,到第三个交点又开启填充。 这个方法是万能的这是闭合曲线的特性,和什么形状无关。
其实就是进入出去,进入出去,只能这个流程,所以才会有这个方法,你不可能进入同一个房间两次。
mk_lucifer 2017-09-11
  • 打赏
  • 举报
回复
直线相交,其实和GDI的画刷填充是同一个原理,只不过他的直线总是水平的,从左到右开始填充画刷,碰见第1个Path点还是填充像素,碰到第二个Path交点停止关闭填充像素,到第三个交点又开启填充。 这个方法是万能的这是闭合曲线的特性,和什么形状无关。
mk_lucifer 2017-09-11
  • 打赏
  • 举报
回复
直线相交法,是可以解决任何图形内外情况的方法。原理很简单,对图形任意画一条通过某点但穿越图形的直线,然后求出和所有路径段(直线,曲线皆可),我们甚至不用计算交点的准确位置,只用判断该点在直线上左右两侧交点的个数是否为都为奇数。 三种情况: 1. 两侧交点都为奇数, 证明该点在区域内。 2. 强侧交点都为偶数, 证明该点在区域外。 3. 一奇一偶不存在,如果是这样,只有一个可能,图形非连通,即有一个豁口,不是闭合图形。
schlafenhamster 2017-09-11
  • 打赏
  • 举报
回复
"五角星的点击测试" 里是 m_Rgn.CreatePolygonRgn(m_aPtAll,10,ALTERNATE); 不是 //WINDING); 五角星 也不是 凸包 1 就出 对角线 的 交 点 , 2 安排 交点 顺序 CreatePolygonRgn
schlafenhamster 2017-09-11
  • 打赏
  • 举报
回复
nMode Specifies the filling mode for the region. This parameter may be either ALTERNATE or WINDING.
schlafenhamster 2017-09-11
  • 打赏
  • 举报
回复
CRgn::CreatePolygonRgn BOOL CreatePolygonRgn( LPPOINT lpPoints, int nCount, int nMode ); Return Value Nonzero if the operation succeeded; otherwise 0. Parameters lpPoints Points to an array of POINT structures or an array of CPoint objects. Each structure specifies the x-coordinate and y-coordinate of one vertex of the polygon. The POINT structure has the following form: typedef struct tagPOINT { int x; int y; } POINT; nCount Specifies the number of POINT structures or CPoint objects in the array pointed to by lpPoints. nMode Specifies the filling mode for the region. This parameter may be either ALTERNATE or WINDING. Remarks Creates a polygonal region. The system closes the polygon automatically, if necessary, by drawing a line from the last vertex to the first. The resulting region is stored in the CRgn object. The size of a region is limited to 32,767 by 32,767 logical units or 64K of memory, whichever is smaller. When the polygon-filling mode is ALTERNATE, the system fills the area between odd-numbered and even-numbered polygon sides on each scan line. That is, the system fills the area between the first and second side, between the third and fourth side, and so on. When the polygon-filling mode is WINDING, the system uses the direction in which a figure was drawn to determine whether to fill an area. Each line segment in a polygon is drawn in either a clockwise or a counterclockwise direction. Whenever an imaginary line drawn from an enclosed area to the outside of a figure passes through a clockwise line segment, a count is incremented. When the line passes through a counterclockwise line segment, the count is decremented. The area is filled if the count is nonzero when the line reaches the outside of the figure. When an application has finished using a region created with the CreatePolygonRgn function, it should select the region out of the device context and use the DeleteObject function to remove it.
凌乱哥 2017-09-11
  • 打赏
  • 举报
回复
引用 10 楼 schlafenhamster 的回复:
你这个 不是 凸包
那就是说PtInRegion是适用于凸多边形对吧
凌乱哥 2017-09-11
  • 打赏
  • 举报
回复
引用 7 楼 brk1985 的回复:
判断点是否在多边形内部 http://www.cnblogs.com/luxiaoxun/p/3722358.html
这个看起来挺麻烦的,能否看看我8楼的说法
schlafenhamster 2017-09-11
  • 打赏
  • 举报
回复
也不是 平行四边形
schlafenhamster 2017-09-11
  • 打赏
  • 举报
回复
你这个 不是 凸包
凌乱哥 2017-09-11
  • 打赏
  • 举报
回复
引用 5 楼 worldy 的回复:
如果点在外,点到每边构成的三角形面积必定大于平行四边形的面积
这个理论很有道理,但是计算面积就有点麻烦了,不过封装成类会好些 另外,能否看看我8楼的说法,对于多边形,只给定几个点,系统会认为它们是怎样的一个图形
凌乱哥 2017-09-11
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
if (!rgn.PtInRegion(x,y))continue;


引用 2 楼 zgl7903 的回复:
CreatePolygonRgn 构造 RGN
PtInRegion 判断



给定四个点,出来的可能是四边形,也可能是另一种图形,这个PtInRegion接口内部会是怎么处理分辨这两种情况的呢

图例:

系统会不会认为给定的4个点组成的是这个图形?
又或者说,假如我要判断点是否位于这个颜色填充区域,那是否只能拆分成2个三角形来判断
brk1985 2017-09-11
  • 打赏
  • 举报
回复
判断点是否在多边形内部 http://www.cnblogs.com/luxiaoxun/p/3722358.html
CT8100 2017-09-11
  • 打赏
  • 举报
回复
指鹿为马法..假装点永远在平行四边形内~谁反对掐掉谁~
mk_lucifer 2017-09-11
  • 打赏
  • 举报
回复
所说的夹角要么大于逆时针,要么顺时针。其实形象点就是,夹角形成的角是面朝右还是面朝左。。 所谓的判断b1=<b && b2>=b,其实是判断,这两个点是否落在直线的两侧,在一侧,一定没有交点,因为直线不会拐弯,所以这个方法对曲线无效。
mk_lucifer 2017-09-11
  • 打赏
  • 举报
回复
引用 21 楼 worldy 的回复:
[quote=引用 17 楼 summergo123321 的回复:] 直线相交法,是可以解决任何图形内外情况的方法。原理很简单,对图形任意画一条通过某点但穿越图形的直线,然后求出和所有路径段(直线,曲线皆可),我们甚至不用计算交点的准确位置,只用判断该点在直线上左右两侧交点的个数是否为都为奇数。 三种情况: 1. 两侧交点都为奇数, 证明该点在区域内。 2. 强侧交点都为偶数, 证明该点在区域外。 3. 一奇一偶不存在,如果是这样,只有一个可能,图形非连通,即有一个豁口,不是闭合图形。
判断交点有没有什么好的算法?[/quote] 很简单,比如你的点是 (a,b) , 比如一个直线段的两个顶点为 (a1,b1) (a2,b2) ,我们求他与 直线 y=b的交点大致范围, 首先必须满足,b1=<b && b2>=b,否则一定无交点,如果由再判断另一个问题,交点在 (a,b)的哪一次,其实很简单,假设 (a,b)为p0点,(a1,b1)为p1, (a2,b2)为p2, p0->p1向量 e, p0->p2 向量 e1, 只用判断 e0和e1的夹角是否大于180°,即可,等于代表在线上,小于和大于分别是在左和在右(和取点顺序有关)。如果只判断角度的是否大于180度,也有渐变算法,不用算出具体角度。
worldy 2017-09-11
  • 打赏
  • 举报
回复
引用 17 楼 summergo123321 的回复:
直线相交法,是可以解决任何图形内外情况的方法。原理很简单,对图形任意画一条通过某点但穿越图形的直线,然后求出和所有路径段(直线,曲线皆可),我们甚至不用计算交点的准确位置,只用判断该点在直线上左右两侧交点的个数是否为都为奇数。 三种情况: 1. 两侧交点都为奇数, 证明该点在区域内。 2. 强侧交点都为偶数, 证明该点在区域外。 3. 一奇一偶不存在,如果是这样,只有一个可能,图形非连通,即有一个豁口,不是闭合图形。
判断交点有没有什么好的算法?
worldy 2017-09-11
  • 打赏
  • 举报
回复
引用 9 楼 dingxz105090 的回复:
[quote=引用 5 楼 worldy 的回复:] 如果点在外,点到每边构成的三角形面积必定大于平行四边形的面积
这个理论很有道理,但是计算面积就有点麻烦了,不过封装成类会好些 另外,能否看看我8楼的说法,对于多边形,只给定几个点,系统会认为它们是怎样的一个图形[/quote] 点要有顺序,不然图形是不一样的
worldy 2017-09-09
  • 打赏
  • 举报
回复
这个判断应该可以推广到任意形状的凸多边形
加载更多回复(5)

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧