【C++】【GDI+】如何检测鼠标是否在矩形内,并粗化该矩形(图中有多个矩形)

VergilYe 2017-05-22 02:31:43
加精
我现在正在做一个绘矩形,并可随意修改矩形的边和旋转角度。

目前需要判断鼠标是否在矩形内,并将这个矩形粗化显示。
如果只是一个矩形的话,是没有任何问题,直接调用Region里的IsVisible函数就能实现了,网上教程一大堆。

但是,问题来了,如果是多个矩形呢?
如何知道鼠标在Region里的哪个Rect?
还是将每个Rect对应一个Region,然后遍历所有Region的IsVisible?
这样的话,运算量会随着矩形的增多而增多,肯定不是一种好办法。

请问一下各位,应该用怎样的算法去实现这个功能,才能避免运算量的增多?
...全文
2953 56 打赏 收藏 转发到动态 举报
写回复
用AI写文章
56 条回复
切换为时间正序
请发表友善的回复…
发表回复
A289672082 2017-08-28
  • 打赏
  • 举报
回复
建议对ui操作或者组合比较复杂的 用qt
VergilYe 2017-06-22
  • 打赏
  • 举报
回复
引用 52 楼 wangyaninglm 的回复:
楼主吧 [quote=引用 49 楼 VergilYe 的回复:] [quote=引用 48 楼 akuma8848 的回复:] 要是矩形套矩形或者局部交叠,这怎么判断?
这个问题可以调整你的遍历顺序来解决。 按照绘制顺序遍历的话,则优先判断底层的矩形。 反着遍历的话,就是优先判断顶层的矩形。 好了,我的问题已经解决了,正式结贴了。 完整代码已经上传了,等待审核中。有兴趣的朋友可以查看我上传的资源,并进行下载。[/quote] 代码链接是?[/quote] 额,抱歉,最近在忙项目,好久没看回复了,你可以直接查看我的资源空间。 也可以访问一下链接: http://download.csdn.net/detail/vergilye/9851069。 当然,我这只是一个Demo, 目前我已经实现了旋转矩形的拉伸与旋转以及缩放了,由于是在公司项目里实现的,所以不方便发出来给大家看,见谅。
nettman 2017-06-03
  • 打赏
  • 举报
回复
shiter 2017-05-29
  • 打赏
  • 举报
回复
楼主吧
引用 49 楼 VergilYe 的回复:
[quote=引用 48 楼 akuma8848 的回复:] 要是矩形套矩形或者局部交叠,这怎么判断?
这个问题可以调整你的遍历顺序来解决。 按照绘制顺序遍历的话,则优先判断底层的矩形。 反着遍历的话,就是优先判断顶层的矩形。 好了,我的问题已经解决了,正式结贴了。 完整代码已经上传了,等待审核中。有兴趣的朋友可以查看我上传的资源,并进行下载。[/quote] 代码链接是?
绥新 2017-05-27
  • 打赏
  • 举报
回复
为什么我没有获得十几分的啊
绥新 2017-05-27
  • 打赏
  • 举报
回复
膜拜大神带来了了了
VergilYe 2017-05-24
  • 打赏
  • 举报
回复
引用 43 楼 schlafenhamster 的回复:
CreateRhombus 化简为:

void CreateRhombus(CPoint P1,CPoint P2,CPoint &P3,CPoint &P4,CDC *pDC)
{
	int dx=P2.x-P1.x;
	int dy=P2.y-P1.y;
//	double L=sqrt(dx*dx+dy*dy);// 96
//	double cosa=dx/L;
//	double sina=dy/L;
	P3.x=P2.x-dy;// L*sina=L*dy/L
	P3.y=P2.y+dx;// L*cosa=L*dx/L
	P4.x=P1.x-dy;// L*sina;
	P4.y=P1.y+dx;// L*cosa;
//
	pDC->MoveTo(P2);
	pDC->LineTo(P3);
	pDC->LineTo(P4);
	pDC->LineTo(P1);
}
哈哈,这步化简,堪称神来之笔!有效避免三角函数计算造成的误差! 不过这个是正方形的画法。 我再修改如下,矩形的画法:

afx_msg void CBottomFormView::CreateRhombus(Point _ptUL,Point _ptBL,Point &_ptUR,Point &_ptBR, double _dWidth,CDC *pDC)
{
	//矩形的坐标计算
	int dx=_ptBL.X-_ptUL.X;
	int dy=_ptBL.Y-_ptUL.Y;
	double dHeight=pow(pow((double)(_ptUL.X-_ptBL.X),2)+pow((double)(_ptUL.Y-_ptBL.Y),2),0.5);

	_ptBR.X=_ptBL.X-_dWidth*dy/dHeight;
	_ptBR.Y=_ptBL.Y+_dWidth*dx/dHeight;
	_ptUR.X=_ptUL.X-_dWidth*dy/dHeight;
	_ptUR.Y=_ptUL.Y+_dWidth*dx/dHeight;

	CPoint _ptPointUL(_ptUL.X,_ptUL.Y);
	CPoint _ptPointBL(_ptBL.X,_ptBL.Y);
	CPoint _ptPointUR(_ptUR.X,_ptUR.Y);
	CPoint _ptPointBR(_ptBR.X,_ptBR.Y);
draw:
	pDC->MoveTo(_ptPointUL);
	pDC->LineTo(_ptPointBL);
	pDC->LineTo(_ptPointBR);
	pDC->LineTo(_ptPointUR);
	pDC->LineTo(_ptPointUL);
}
完美!接下来就是实现HitTest了!
xiaohuh421 2017-05-24
  • 打赏
  • 举报
回复
1. 矩形数据的存放, 肯定是要放到一个list中, 并且不是栈上申请, 最好是堆上动态扩展, 建议使用std::list 或者 std::vector 2. 效率问题, 你100个矩形的遍历, 对于现代的计算机来说, 只能算是渣渣运算, 哪怕10000个, 也用不了什么时间. CPU消耗也不会太大. 并且商用的话, 可以很容易的做优化. 比如使用坐标给这些矩形排序. 根据x,y排序. 这样查找效率就会增加. 减少遍历. 还有根据创建顺序, 后创建的在上层, 有了Z顺序, 遍历次数也会减少. 所以, 楼主, 你就放心的把 矩形放到 list中, 然后鼠标移动的时候遍历判断一下吧. 实际应用中, 应该不会出现几千,几万个矩形. 几十百把个已经不得了了
schlafenhamster 2017-05-24
  • 打赏
  • 举报
回复
schlafenhamster 2017-05-24
  • 打赏
  • 举报
回复
CreateRhombus 化简为:

void CreateRhombus(CPoint P1,CPoint P2,CPoint &P3,CPoint &P4,CDC *pDC)
{
int dx=P2.x-P1.x;
int dy=P2.y-P1.y;
// double L=sqrt(dx*dx+dy*dy);// 96
// double cosa=dx/L;
// double sina=dy/L;
P3.x=P2.x-dy;// L*sina=L*dy/L
P3.y=P2.y+dx;// L*cosa=L*dx/L
P4.x=P1.x-dy;// L*sina;
P4.y=P1.y+dx;// L*cosa;
//
pDC->MoveTo(P2);
pDC->LineTo(P3);
pDC->LineTo(P4);
pDC->LineTo(P1);
}

VergilYe 2017-05-24
  • 打赏
  • 举报
回复
引用 41 楼 schlafenhamster 的回复:
调用: void CDrawLinesView::OnLButtonUp(UINT nFlags, CPoint point) { // draw a new line CDC *pDC=GetDC(); Line(m_startPoint,point,pDC); // test CPoint P3;CPoint P4; CreateRhombus(m_startPoint,point,P3,P4,pDC);
大神,非常感谢你的帮忙~ 看到你的方法,我大概有思路了,我先试试看 十分感谢!
VergilYe 2017-05-24
  • 打赏
  • 举报
回复
引用 48 楼 akuma8848 的回复:
要是矩形套矩形或者局部交叠,这怎么判断?
这个问题可以调整你的遍历顺序来解决。 按照绘制顺序遍历的话,则优先判断底层的矩形。 反着遍历的话,就是优先判断顶层的矩形。 好了,我的问题已经解决了,正式结贴了。 完整代码已经上传了,等待审核中。有兴趣的朋友可以查看我上传的资源,并进行下载。
Anymore 2017-05-24
  • 打赏
  • 举报
回复
要是矩形套矩形或者局部交叠,这怎么判断?
qq853784861 2017-05-23
  • 打赏
  • 举报
回复
学习一下...
baidu_38890984 2017-05-23
  • 打赏
  • 举报
回复
系统卡屏怎么办
VergilYe 2017-05-23
  • 打赏
  • 举报
回复
引用 31 楼 VergilYe 的回复:
[quote=引用 30 楼 schlafenhamster 的回复:] 正方形 还是 矩形, 你那个 angle 到底干什么的?
angle是旋转的角度。 由于我需要绘制的矩形是有角度的,所以我在绘制前,先对坐标系进行旋转,再绘制矩形,这样子矩形相对于Client的坐标系就是斜的了。 我目前需要实现的功能是: [/quote] 啊,点错提交了。 我目前需要实现的功能是: 1.拉伸出一条直线,根据直线的位置和长度,进行绘制矩形(可以使正的,也可以使斜的) 2.针对绘制的矩形可以进行选中操作,拉伸边框操作,旋转操作。 目前我绘制步骤已经完成了,但是选中操作这里就遇到问题了。
VergilYe 2017-05-23
  • 打赏
  • 举报
回复
引用 30 楼 schlafenhamster 的回复:
正方形 还是 矩形, 你那个 angle 到底干什么的?
angle是旋转的角度。 由于我需要绘制的矩形是有角度的,所以我在绘制前,先对坐标系进行旋转,再绘制矩形,这样子矩形相对于Client的坐标系就是斜的了。 我目前需要实现的功能是:
schlafenhamster 2017-05-23
  • 打赏
  • 举报
回复
正方形 还是 矩形, 你那个 angle 到底干什么的?
VergilYe 2017-05-23
  • 打赏
  • 举报
回复
引用 28 楼 VergilYe 的回复:
[quote=引用 25 楼 zhao4zhong1 的回复:] 判断点是否在有旋转角度的矩形中请使用: PtInRegion The PtInRegion function determines whether the specified point is inside the specified region. BOOL PtInRegion( HRGN hrgn, // handle to region int X, // x-coordinate of point int Y // y-coordinate of point ); Parameters hrgn Handle to the region to be examined. X Specifies the x-coordinate of the point. Y Specifies the y-coordinate of the point. Return Values If the specified point is in the region, the return value is nonzero. If the specified point is not in the region, the return value is zero. QuickInfo Windows NT: Requires version 3.1 or later. Windows: Requires Windows 95 or later. Windows CE: Requires version 1.0 or later. Header: Declared in wingdi.h. Import Library: Use gdi32.lib. See Also Regions Overview, Region Functions, RectInRegion
所以我需要将矩形储存为多边形,再去进行判断? 这样的确可以避免转换精度的问题,待我再理一理,学习学习。 感谢![/quote] 再回到刚刚的问题,我的矩形是基于绘制时的坐标系储存的,请问如何转换成Client坐标系中的多边形呢?
VergilYe 2017-05-23
  • 打赏
  • 举报
回复
引用 25 楼 zhao4zhong1 的回复:
判断点是否在有旋转角度的矩形中请使用: PtInRegion The PtInRegion function determines whether the specified point is inside the specified region. BOOL PtInRegion( HRGN hrgn, // handle to region int X, // x-coordinate of point int Y // y-coordinate of point ); Parameters hrgn Handle to the region to be examined. X Specifies the x-coordinate of the point. Y Specifies the y-coordinate of the point. Return Values If the specified point is in the region, the return value is nonzero. If the specified point is not in the region, the return value is zero. QuickInfo Windows NT: Requires version 3.1 or later. Windows: Requires Windows 95 or later. Windows CE: Requires version 1.0 or later. Header: Declared in wingdi.h. Import Library: Use gdi32.lib. See Also Regions Overview, Region Functions, RectInRegion
所以我需要将矩形储存为多边形,再去进行判断? 这样的确可以避免转换精度的问题,待我再理一理,学习学习。 感谢!
加载更多回复(34)

19,468

社区成员

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

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