基于DXF文件利用VB编程实现对图形文件内线段相交的检查

时间:2022-09-14 05:49:27

基于DXF文件利用VB编程实现对图形文件内线段相交的检查

【摘要】:本文在对AUTOCAD中DXF文件进行深入研究的基础上,实现了脱离AUTOCAD环境通过对DXF文件进行读取,并条件提取相关内容,通过VB编程实现对图形数据线段的相交检查。

【关键词】:DXF文件 ,VB ,向量, 跨立

【 abstract 】 this paper in AUTOCAD DXF file based on a thorough investigation, realize the AUTOCAD DXF through to the environment from the documents are read, and extraction conditions related content, through the VB programming realize to the graphics data line fellowship inspection.

【 key words 】 : DXF file, VB, vector, cross made

中图分类号:TU74文献标识码:A 文章编号:

0、前言

AutoCAD平台的数字测图软件,因其简单易用,界面开放友好,而被广范应用。实际工作中,由于工作习惯和疏忽而导致某些线段没有完全捕捉到位,而存在或多或少的相交问题。这种问题在数据入库时会造成拓扑结构不严谨,数据冗余过大。本文针对这种情况,通过对DXF文件进行深入研究,结合VB编程,实现了对图形数据内所有相交点的检查。

1、DXF文件结构

DXF格式是 AutoCAD图形文件中包含的所有信息的一种带标记数据的表示方式。带标记数据是指文件中的每个数据元素前面都带有一个称为组码的整数。组码的值表明了随后的数据元素的类型。还指出了数据元素对于给定对象(或记录)类型的含义。实际上,图形文件中所有用户指定的信息都可以用 DXF 格式表示。

完整的DXF文件由六个段和结束标志组成,每段都是以一个其后跟随着字符串“SECTION”的组码“0”开始,接着是组码“2”和表示段名称的字符串(例如“HEADER”)。每个段内容都是由元素的组码和组值组成,其后跟着字符串“ENDSEC”的组码“0”表示该段结束。文件结束标志用组码“0”和字符串“EOF”。完整的DXF文件结构详见图1

图1 DXF文件数据结构图

“HEADER”段:包含图形的基本信息,它由许多AutoCAD系统变量组成;

“CLASSES”段:包含有关应用程序定义类的信息;

“TABLES”段:包含九个符号表的定义(APPID-应用程序标识表;BLOCK_RECORD-块引用表;DIMSTYLE-标注样式表;LAYER-图层表;LTYPE-线型表;STYLE-文本样式表;UCS-用户坐标系表;VIEW-视图表;VPORT-视口配置表);

“BLOCKS”段:包括块定义和组成图形中每个块引用的图形图元;

“ENTITIES”段:包含图形中的图形对象(图元),包括块引用(插入图元)。

“OBJECTS”段:包含图形中非图形对象,所有那些非符号记录的、符号表的非图元的对象都存储在此段中。在“OBJECTS”段中的条目样例是包含多线和组的字典。

2、图元结构

在DXF文件中,图元可以出现在“BLOCKS”段和“ENTITIES”段中,两个段中的图元用法一致。值得注意的是某些定义的图元组码始终出现,而其他的组码仅在它的值与缺省值不同时才出现。以下列出LWPOLYLINE(多段线)、LINE(直线)的图元结构。

2.1 LWPOLYLINE(多段线)图元结构

图元字段 说明

LWPOLYLINE APP:图元名

5 句柄

4A7 句柄值

330 所有者词典的软指针 ID/句柄

AcDbEntity 类

8 图层

0 层名

6 线型

Continuous 线型名

AcDbPolyline 子类标记

90 顶点数

5 值

70 闭合,1=闭合;128=多段线生成

128 值

43 宽度

0.0 值

10 多段线第1顶点X坐标

125.615734460 值

20 多段线第1顶点Y坐标

27.5486692667 值

… …

10 多段线第n顶点X坐标

665.9800429696 值

20 多段线第n顶点Y坐标

172.858233892 值

2.1 LINE(直线)图元结构

图元字段 说明

LINE APP:图元名

5 句柄

4A8 句柄值

330 所有者词典的软指针 ID/句柄

AcDbEntity 类

8 图层

0 层名

6 线型

Continuous 线型名

AcDbLine 子类标记

10 直线段第1顶点X坐标

230.741154653 值

20 直线段第1顶点Y坐标

-54.9243272804 值

30 直线段第1顶点Z坐标

0.0 值

11 直线段第2顶点X坐标

525.485323089 值

21 直线段第2顶点Y坐标

-67.68800526216 值

31 直线段第2顶点Z坐标

0.0 值

3、利用VB编程对图形内线段交点进行检索的算法

3.1 设计思路

利用VB编程,读取DXF文件内所有的LWPOLYLINE(多段线)和LINE(直线),提起其顶点X、Y坐标值,并将其分界为线段,以数组的形式进行存储,以每条线段与其他各条进行求交解算,采取递归调用的方式遍历所有线段后,求出该条线段与其他的线段是否存在交点,如有,则记录交点坐标。

3.2 设计原理

1)快速排斥试验

设以线段P1P2为对角线的矩形为P;

设以线段Q1Q2为对角线的矩形为Q;

如果P和Q不相交,显然两线段不会相交。

2)跨立试验

如果两线段相交,则两线段必然相互跨立对方。

若P1P2跨立Q1Q2,则矢量( P1- Q1)

和(P2-Q1)位于矢量( Q2-Q1)的两侧,即(P1- Q1)×(Q2 -Q1) * (P2 - Q1)×( Q2 - Q1 ) >0。

上式可改写成(P1-Q1)×(Q2 -Q1) * (Q2 - Q1)×(P2 -Q1) > 0。

当(P1 -Q1)×(Q2 -Q1)=0 时,说明( P1 - Q1)和(Q2 - Q1)共线,但是因为已经通过快速排斥试验,所以P1一定在线段Q1Q2上;

同理,(Q2 -Q1)×(P2 -Q1)=0 说明P2一定在线段Q1Q2上。

所以判断P1P2跨立Q1Q2的依据是:( P1 - Q1 )×(Q2 - Q1) * (Q2 - Q1)×( P2 -Q1) >=0。

同理判断Q1Q2跨立P1P2的依据是:( Q1 - P1 )×( P2 - P1) * ( P2 - P1)×(Q2 - P1) >= 0。

X:为叉积 叉积的计算公式为:P1×P2 = x1y2 - x2y1;

3.3 部分源码

Function L2L_Intersect(p1_s() As Double, p1_e() As Double, p2_s() As Double, p2_e() As Double) As Boolean

Dim Xmax_1, Xmax_2, Xmin_1, Xmin_2, Ymax_1, Ymax_2, Ymin_1, Ymin_2 As Double

Dim V1As Double, V2 As Double

Dim V3As Double, V4 As Double

If p1_s(0) > p1_e(0) Then

Xmax_1 = p1_s(0)

Xmin_1 = p1_e(0)

Else

Xmax_1 = p1_e(0)

Xmin_1 = p1_s(0)

End If

If p1_s(1) > p1_e(1) Then

Ymax_1 = p1_s(1)

Ymin_1 = p1_e(1)

Else

Ymax_1 = p1_e(1)

Ymin_1 = p1_s(1)

End If

If p2_s(0) > p2_e(0) Then

Xmax_2 = p2_s(0)

Xmin_2 = p2_e(0)

Else

Xmax_2 = p2_e(0)

Xmin_2 = p2_s(0)

End If

If p2_s(1) > p2_e(1) Then

Ymax_2 = p2_s(1)

Ymin_2 = p2_e(1)

Else

Ymax_2 = p2_e(1)

Ymin_2 = p2_s(1)

End If

L2L_Intersect = False

If Xmax_1 < Xmin_2 Or Xmin_1 > Xmax_2 Or Ymin_1 > Ymax_2 Or Ymax_1 < Ymin_2 Then '两线段最小矩形不相交,得出两线段不相交

L2L_Intersect = False

Exit Function

Else '利用向量的叉积性质,当其中一条线段的两个端点在另一条线段的同一侧时,不相交。否则,相交。

V1 = (p1_e(0) - p1_s(0)) * (p2_s(1) - p1_s(1)) - (p2_s(0) - p1_s(0)) * (p1_e(1) - p1_s(1))

V2 = (p1_e(0) - p1_s(0)) * (p2_e(1) - p1_s(1)) - (p2_e(0) - p1_s(0)) * (p1_e(1) - p1_s(1))

V3 = (p2_e(0) - p2_s(0)) * (p1_s(1) - p2_s(1)) - (p1_s(0) - p2_s(0)) * (p2_e(1) - p2_s(1))

V4 = (p2_e(0) - p2_s(0)) * (p1_e(1) - p2_s(1)) - (p1_e(0) - p2_s(0)) * (p2_e(1) - p2_s(1))

If V3 * V4

L2L_Intersect = True

End If

End If

End Function

参考文献:

1、李芳珍;许伦辉;;DXF文件格式及其外部接口的研究[J];兵工自动化;2008年07期

2、《VB程序设计》;清华大学出版社; 第1版 (2009年7月1日)

注:文章内所有公式及图表请用PDF形式查看。

上一篇:探讨建筑工程质量检测的工作 下一篇:手持GPS在水利普查中的应用探析