求助高人 关于给闭合三角形填充颜色问题

hngydx000 2012-03-11 02:29:58
我用如下代码在同一个picture空间给很多(5000以上)个三角形填充颜色,屏幕会卡住。三角形数量少的话就不会出现、怎么解决啊。

Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
'创建区域
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
'创建纯色的刷子
Private Declare Function FillRgn Lib "gdi32" (ByVal hdc As Long, ByVal hRgn As Long, ByVal hBrush As Long) As Long
'用指定刷子填充区域的函数
Private Type POINTAPI
x As Long
y As Long
End Type
'点结构
Private Const WINDING = 2
'根据绘图方向填充图形


Private Sub Picture1_Paint()
Dim POI(2) As POINTAPI
POI(0).x = 0 '第一个点的横坐标(使用容器的坐标系)
POI(0).y = 0 '第一个点的纵坐标(使用容器的坐标系)

POI(1).x = 0 '第二个点的横坐标
POI(1).y = 200 '第二个点的纵坐标

POI(2).x = 200
POI(2).y = 200

Shapes = CreatePolygonRgn(POI(0), 3, WINDING)
'创建三角形区域,POI(0)是第一个点,3是点数
Brush = CreateSolidBrush(QBColor(3))
'创建一个黑色的刷子(RGB(0,0,0)代表黑色)
FillRgn Picture1.hdc, Shapes, Brush
'填充三角形,Me.hdc是窗体的图形设备句柄,shapes是区域句柄,Brush是刷子句柄
End Sub
...全文
394 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
worldy 2012-03-13
  • 打赏
  • 举报
回复
Brush = CreateSolidBrush(QBColor(3))
GDI对象Brush没有删除吧
hngydx000 2012-03-13
  • 打赏
  • 举报
回复
谢谢大哥。那我好好学学OpenGl吧
[Quote=引用 20 楼 veron_04 的回复:]

这个使用OpenGL的确是不错的方法
[/Quote]
hngydx000 2012-03-13
  • 打赏
  • 举报
回复
非常感谢你啊。不过这种方法画出来的图很离散,效果不好,还是在想想别的办法。非常感谢你
[Quote=引用 18 楼 tiger_zhao 的回复:]

先定义一下这样一个距离 S 为任意两个点 (x1,y1) (x2,y2) 在 X,Y 轴投影的距离和
S = Abs(x1-x2) + Abs(y1-y2)

一个三角的3个顶点可以算出3个 S
a)如果其中一个 S=0,两点重合,不用填充;
b)如果其中一个 S=1,两点相邻,不用填充;
c)如果其中一个 S=2 And (Abs(x1-x2)=1),两点相邻,不用填充。
[/Quote]
贝隆 2012-03-13
  • 打赏
  • 举报
回复
这个使用OpenGL的确是不错的方法
hngydx000 2012-03-13
  • 打赏
  • 举报
回复
嗯,那样最好。可是我刚学,那个估计比较复杂,目前先不弄。只要每个三角形画一个颜色就行了
[Quote=引用 17 楼 dreamcs 的回复:]

三角形的颜色是不是还要根据应力大小渐变么?
[/Quote]
Tiger_Zhao 2012-03-13
  • 打赏
  • 举报
回复
先定义一下这样一个距离 S 为任意两个点 (x1,y1) (x2,y2) 在 X,Y 轴投影的距离和
 S = Abs(x1-x2) + Abs(y1-y2)

一个三角的3个顶点可以算出3个 S
a)如果其中一个 S=0,两点重合,不用填充;
b)如果其中一个 S=1,两点相邻,不用填充;
c)如果其中一个 S=2 And (Abs(x1-x2)=1),两点相邻,不用填充。
dreamcs 2012-03-13
  • 打赏
  • 举报
回复
三角形的颜色是不是还要根据应力大小渐变么?
dreamcs 2012-03-13
  • 打赏
  • 举报
回复
楼主可以百度下OpenGL。可先试一下它。如果不行。楼主可使用四叉树等分层数据结构加速显示。
hngydx000 2012-03-13
  • 打赏
  • 举报
回复
谢谢你,OpenG1是什么啊,我这个以后可能还会有上万网格。我的有限元网格是用一个叫trangle的程序得来的
[Quote=引用 14 楼 dreamcs 的回复:]

楼主可以使用OpenGl,几千三角形对于显卡来说小菜一碟。随便问一句,这有有限元网格划分么?
[/Quote]
dreamcs 2012-03-13
  • 打赏
  • 举报
回复
楼主可以使用OpenGl,几千三角形对于显卡来说小菜一碟。随便问一句,这有有限元网格划分么?
hngydx000 2012-03-13
  • 打赏
  • 举报
回复
可是怎么判断那些三角形的像素足够小而不用填充啊[Quote=引用 11 楼 zhao4zhong1 的回复:]

显示在屏幕上小于2×2像素的三角形有必要填充吗?
[/Quote]
hngydx000 2012-03-13
  • 打赏
  • 举报
回复
谢谢大哥的帮助。
那个图是根据下面这个图把三角形分类,每一类三角形填充一个颜色得到的。
这些三角形都是由有限元剖分程序剖分出来的网格文件绘制的,忽略了可能显示效果不会很好。

[Quote=引用 10 楼 tiger_zhao 的回复:]
这是你2000+的图,明明大多数是方块,几乎没有三角。

所以你可以考虑一下简化绘图:
1)某些区域中聚集的三角直接合并成方块或大的三角。
2)即使在边界区域,某些很小的三角就不用填充了,最多直接画一个像素,更小的可以直接忽略的。
如果绘图区域不变,7000+ 的填充操作不会比 2000+ 多很多。
[/Quote]
赵4老师 2012-03-13
  • 打赏
  • 举报
回复
显示在屏幕上小于2×2像素的三角形有必要填充吗?
Tiger_Zhao 2012-03-13
  • 打赏
  • 举报
回复

这是你2000+的图,明明大多数是方块,几乎没有三角。

所以你可以考虑一下简化绘图:
1)某些区域中聚集的三角直接合并成方块或大的三角。
2)即使在边界区域,某些很小的三角就不用填充了,最多直接画一个像素,更小的可以直接忽略的。
如果绘图区域不变,7000+ 的填充操作不会比 2000+ 多很多。
hngydx000 2012-03-13
  • 打赏
  • 举报
回复
非常感谢大哥提供的办法。用大哥的办法试了,可是还是不行。运行完的图像如下图:

还是不能把所有三角形填充完全。这种方法是不是有一个填充图形数量的限制啊。
运行完时候电脑屏幕也会花,

那些图标都显示不出来了。
画这种图还有什么别的办法么。
在内存绘图然后复制到picture的代码如下
Option Explicit
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function FillRgn Lib "gdi32" (ByVal hdc As Long, ByVal hRgn As Long, ByVal hBrush As Long) As Long
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
'创建区域


Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source

Private dc As Long
Private hBmp As Long
Private Type POINTAPI
x As Long
y As Long
End Type
'点结构
Private Const WINDING = 2



Private Sub Command1_Click()
Dim Shapes As Long
Dim Brush As Long
Dim POI(2) As POINTAPI
POI(0).x = 0 '第一个点的横坐标(使用容器的坐标系)
POI(0).y = 0 '第一个点的纵坐标(使用容器的坐标系)

POI(1).x = 0 '第二个点的横坐标
POI(1).y = 200 '第二个点的纵坐标

POI(2).x = 200
POI(2).y = 200

dc = CreateCompatibleDC(Picture1.hdc) '创建一个与窗体相兼容的设备场景

hBmp = CreateCompatibleBitmap(dc, Picture1.ScaleWidth / Screen.TwipsPerPixelX, Picture1.ScaleHeight / Screen.TwipsPerPixelY) '在内存中创建与窗体同样大小的位图

SelectObject hdc, hBmp '将位图选入刚才创建的设备场景中


Shapes = CreatePolygonRgn(POI(0), 3, WINDING)
'创建三角形区域,POI(0)是第一个点,3是点数
Brush = CreateSolidBrush(QBColor(3))
'创建一个黑色的刷子(RGB(0,0,0)代表黑色)
FillRgn Picture1.hdc, Shapes, Brush
'填充三角形,Me.hdc是窗体的图形设备句柄,shapes是区域句柄,Brush是刷子句柄

BitBlt Picture1.hdc, 0, 0, Picture1.ScaleWidth / Screen.TwipsPerPixelX, Picture1.ScaleHeight / Screen.TwipsPerPixelY, dc, 0, 0, SRCCOPY '将内存位图中的图形拷贝到窗体上显示

DeleteObject Shapes '删除以前创建的对像用于释放内存
DeleteObject Brush
DeleteObject hBmp
DeleteDC dc

End Sub

[Quote=引用 5 楼 veron_04 的回复:]

可否考虑在内存中绘图,填充,然后再通过bitblt复制到picturebox上来?速度肯定可以提高,但具体提高多少我就没有试验过了。
[/Quote]
贝隆 2012-03-13
  • 打赏
  • 举报
回复
可以给你一个绘图的例子,但不是绘制三角形并填充的,你可以看看:
http://download.csdn.net/detail/veron_04/2368159
这个方法比直接在PictureBOx上绘图快出很多。
hngydx000 2012-03-13
  • 打赏
  • 举报
回复
这种方法怎么实现呢,麻烦大哥能不能给一个例子啊。
[Quote=引用 5 楼 veron_04 的回复:]

可否考虑在内存中绘图,填充,然后再通过bitblt复制到picturebox上来?速度肯定可以提高,但具体提高多少我就没有试验过了。
[/Quote]
of123 2012-03-13
  • 打赏
  • 举报
回复
5 楼说的是。

类似的情况:在连续用大数组内容填充当前窗体上的 TextBox 时,就最好不要直接对 TextBox 循环操作,而是在后台填好一个变量,将变量赋值给 TextBox 控件。
贝隆 2012-03-13
  • 打赏
  • 举报
回复
可否考虑在内存中绘图,填充,然后再通过bitblt复制到picturebox上来?速度肯定可以提高,但具体提高多少我就没有试验过了。
hngydx000 2012-03-12
  • 打赏
  • 举报
回复
谢谢大哥指导、我的问题是这样的
如下图所示的一个图形

把每个三角形进行涂色,当三角形数量为2000+时可以把每个三角形都涂色,然后显示的结果如下图:
http://hi.csdn.net/attachment/201203/12/5554075_1331533960l4RS.png
但当三角形数量为7000+时,就不会显示出来结果,只能显示出如下图所示的图形,然后屏幕就乱了。
http://hi.csdn.net/attachment/201203/12/5554075_1331533912g19F.png
这个问题怎么解决啊
[Quote=引用 1 楼 veron_04 的回复:]

填充例子
[/Quote]
加载更多回复(3)
重要提示】本资源设置为0积分下载,若非0积分请勿轻易下载 亲爱的CSDN用户: 首先感谢你点进这个资源页面。我需要提前说明一个重要情况: 本资源原本已设置为“0积分下载”,即作者希望完全免费共享。但CSDN平台有时会根据文件的下载热度、文件大小、用户权限等因素,自动将部分资源的积分调整为非0数值(如1积分、2积分、5积分等)。这是平台系统的自动行为,而非作者本人的设定。 因此,如果你当前看到该资源的下载所需积分不是0(例如显示为1、2、3……),请谨慎决定是否下载。 如果你按照非0积分支付并下载后发现资源内容不符合预期、链接失效,或者实际上该资源本应是免费的,作者无法为此承担积分损失或退还操作。强烈建议:仅在页面显示为0积分时进行下载。 另外,本资源描述中并未直接提供具体的下载地址或外部链接,因为它本身是一个通过CSDN官方上传通道提交的文件/内容包。如果你看到描述中没有外部网盘地址,这是正常的——资源文件应通过CSDN内置的“下载”按钮获取。若因平台积分显示异常导致你支付了积分,请优先联系CSDN客服咨询积分退还政策,作者没有权限修改平台自动设定的积分值。 感谢你的理解与支持。技术分享本应开放,但受限于平台规则,特此提醒如上。祝学习进步!
内容概要:本文围绕三相逆变器模型仿真及软开关技术展开研究,基于Simulink平台构建系统仿真模型,深入分析三相逆变器的工作原理、主电路拓扑结构、空间矢量脉宽调制(SVPWM)控制策略及其动态响应特性。重点研究了软开关技术在三相逆变器中的实现方法,通过优化开关时序与谐振网络设计,有效降低了功率器件的开关损耗,提升了系统转换效率与电磁兼容性能。文中详细仿真了不同负载条件下逆变器输出的电压、电流波形,验证了LCL滤波器对高频谐波的抑制效果,并探讨了闭环控制策略对系统稳定性的提升作用。此外,研究结合工程实际,分析了软开关的实现条件及其对系统可靠性的影响,为高性能逆变电源的设计提供了理论支撑与仿真依据。; 适合人群:电气工程、自动化、电力电子与电力传动等相关专业的高年级本科生、研究生,以及从事新能源发电、电能变换、微电网系统研发的工程技术人员。; 使用场景及目标:①作为高校电力电子技术、现代电源设计等课程的仿真教学案例,辅助学生理解逆变器控制与软开关原理;②为新能源并网逆变器、不间断电源(UPS)、电机驱动系统等工业产品的研发提供仿真验证手段和技术参考;③帮助科研人员掌握Simulink在电力电子系统建模、控制器设计与系统级性能评估中的综合应用能力。; 阅读建议:建议读者结合Simulink软件动手搭建仿真模型,逐步调试PWM发生模块、SVPWM调制单元与LCL滤波环节,重点关注软开关谐振过程的波形特征与控制逻辑的匹配关系,进一步可延伸学习数字锁相环(DPLL)、重复控制、模型预测控制等先进算法的集成应用,全面提升电力电子系统仿真与设计水平。
内容概要:本文围绕“移动边界法”这一创新方法,系统研究了融合光热电站与分时电价机制的微电网运行调度问题,并提供了完整的Matlab代码实现方案。研究充分利用光热电站具备能量存储与灵活调控的优势,结合分时电价引导用户侧负荷转移,优化微网内多能源协同运行策略,从而提升系统运行的经济性、稳定性和可再生能源消纳能力。所提出的“移动边界法”通过动态调整优化时段的时间边界,增强了模型预测控制(MPC)在应对光伏发电、风力发电等出力波动及负荷需求不确定性方面的适应性与预测精度,有效改善了传统固定时窗优化带来的偏差问题。该资源属于电力系统智能优化领域,聚焦微电网双层能量管理与多目标调度,涵盖系统建模、优化算法设计与仿真验证全过程,配套完整代码与案例分析,具有较强的科研复现与工程参考价值; 适合人群:面向具备电力系统、能源动力、自动化或相关专业背景,熟悉Matlab编程环境及优化工具箱(如YALMIP/CPLEX)的研究生、科研人员及从事新能源并网、微电网优化调度、综合能源系统规划的工程技术人员; 使用场景及目标:① 深入学习并复现“移动边界法”在微网调度中的创新建模思路与实现路径;② 掌握光热电站的热电联供与储热建模方法,及其与分时电价需求响应机制的协同优化策略;③ 实践基于Matlab的微电网多目标优化模型构建、求解流程与结果分析,提升科研仿真能力与高水平论文复现水平; 阅读建议:建议结合文中提及的相关研究方向(如分时电价需求响应、综合能源系统双层优化、模型预测控制等)进行横向对比学习,重点剖析模型构建的逻辑架构与代码实现的关键细节,配合提供的网盘资源开展仿真实验,通过调试与参数敏感性分析深化对优化算法与实际工程问题深度融合的理解。

807

社区成员

发帖
与我相关
我的任务
社区描述
VB 多媒体
社区管理员
  • 多媒体
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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