前情回顾

在上一节的CSDN中:

实现了直线和圆弧的绘制。

但是不能移动和缩放。

还需要一个方法,对这些数据进行组织。

正文

组织图元

铺垫:

怎么组织图元呢?

也许可以参考画家算法的处理顺序。

也许还能借用python的二维列表

根据相交关系,来组织零散的图元。

怎么判断直线与直线相交?

——未知

怎么判断圆弧与圆弧相交?

——未知

怎么判断直线与圆弧相交?

——点到直线距离公式

计算两点之间的距离,可能会用到numpy:

https://www.runoob.com/numpy/numpy-tutorial.htmlhttps://www.runoob.com/numpy/numpy-tutorial.html 然后,怎么重组?重组以后存哪?用什么数据结构存?

暂定是这样:

二维list里,得能判断每个元素具体是什么图元类。应该可以借助type实现:

#读取
dxf = dxfgrabber.readfile(inputFilePath)
lineNum=0
arcNum=0
for e in dxf.entities:if e.dxftype == 'LINE':LINELIST.append(Line(lineNum,e.start,e.end))lineNum+=1elif e.dxftype=='ARC':ARCLIST.append(Arc(arcNum,e.center,e.radius,e.start_angle,e.end_angle))arcNum+=1
#图元重组
#获取种类
if Line==type(LINELIST[0]):print("is line")
if Arc==type(ARCLIST[0]):print("is arc")

二维list,也许应该叫嵌套list:

https://www.runoob.com/python3/python3-list.htmlhttps://www.runoob.com/python3/python3-list.html

测试:

a=[1,2,4]
b=[4,5,6]x=[]
x.append(a)
x.append(b)print(x[0])
print(x[1])c=['x','y','x']
x.append(c)
print(x[2])print(x[2][0])

输出结果

python下如何使用switch-case——python3.10以上才能用。3.7不行。

#python-switch-case
i=10
match i:case 10:passcase 11:pass

怎么处理OpenGL的鼠标事件?比如,点击,按下并移动?

https://cuiqingcai.com/1776.htmlhttps://cuiqingcai.com/1776.html

http://blog.sina.com.cn/s/blog_687960370101e3xa.htmlhttp://blog.sina.com.cn/s/blog_687960370101e3xa.html实现了交互移动与缩放:

from asyncio.windows_events import NULL
from os import statimport dxfgrabber
import math
import numpy as npfrom OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *inputFilePath='e:/test3-11/Drawing1.dxf'  #输入文件的路径#供读取的数据结构
class Line:def __init__(self,id,start,end):self.id=idself.start=startself.end=end
LINELIST=[]class Arc:def __init__(self,id,center,radius,startAngle,endAngle) -> None:self.id=idself.center=centerself.radius=radiusself.start_angle=startAngleself.end_angle=endAnglepass
ARCLIST=[]VIRTUALLIST=[]SCALE=1.0#用于缩放
DX,DY=0,0#用于移动#读取
dxf = dxfgrabber.readfile(inputFilePath)
lineNum=0
arcNum=0
for e in dxf.entities:if e.dxftype == 'LINE':LINELIST.append(Line(lineNum,e.start,e.end))lineNum+=1elif e.dxftype=='ARC':ARCLIST.append(Arc(arcNum,e.center,e.radius,e.start_angle,e.end_angle))arcNum+=1
#图元重组def intersectionTest()->list:#加入新图元后,与之前加入的图元进行相交测试,返回与之相交的图元列表global VIRTUALLISTresult=[]if len(VIRTUALLIST)==1:return resultentity=VIRTUALLIST[-1]#列表的最后一个就是新加入的图元if type(entity)==Line:#直线与其它图元的相交测试for virtualEntity in VIRTUALLIST[0:len(VIRTUALLIST)]:if type(virtualEntity)==Line:passelif type(virtualEntity)==Arc:#计算圆弧起点与终点,与直线重合,则认为相交x=virtualEntity.center[0]+virtualEntity.radius*math.cos(virtualEntity.start_angle/180*math.pi)y=virtualEntity.center[1]+virtualEntity.radius*math.sin(virtualEntity.end_angle/180*math.pi)else:passelif type(entity)==Arc:for virtualEntity in VIRTUALLIST[0:len(VIRTUALLIST)]:if type(virtualEntity)==Line:#直线去找圆弧们,测试相交x=entity.center[0]+entity.radius*math.cos(entity.start_angle/180*math.pi)y=entity.center[1]+entity.radius*math.sin(entity.end_angle/180*math.pi)p0=np.array([x,y])p1=np.array(virtualEntity.start[0:2])p2=np.array(virtualEntity.end[0:2])passelif type(virtualEntity)==Arc:passelse:passelse:passfor line in LINELIST:VIRTUALLIST.append(line)intersectionTest()for arc in ARCLIST:VIRTUALLIST.append(arc)intersectionTest()#显示——OpenGL def init():glClearColor(0.3, 0.3, 0.3, 1.0)gluOrtho2D(0, 400.0, 0, 400)#窗口坐标系的大小,左下角是原点def drawFunc():glClear(GL_COLOR_BUFFER_BIT)glPushMatrix()glScale(SCALE,SCALE,1.0)#缩放——OpenGL里没有鼠标滚轮.pyQT里有吗?glTranslatef(DX,DY,0)#绘制所有直线glBegin(GL_LINES)for line in LINELIST:glVertex2f(line.start[0],line.start[1])glVertex2f(line.end[0],line.end[1])glEnd()#用描点的形式绘制所有弧线glBegin(GL_POINTS)for arc in ARCLIST:start_angle=arc.start_angle/180.0*math.piend_angle=arc.end_angle/180*math.pi#CAD里,圆弧都是从起点到终点,顺时针转的;所以,这里只取正值dAngle=abs(end_angle-start_angle)pointNum=500#一个弧500个点for i in range(0,pointNum):x=arc.center[0]+arc.radius*math.cos(start_angle+dAngle*i/pointNum)y=arc.center[1]+arc.radius*math.sin(start_angle+dAngle*i/pointNum)glVertex2f(x,y)glEnd()glPopMatrix()glFlush()#方向键选择图元
def specialKey(key=0,x=0,y=0):global SCALEif (key==GLUT_KEY_UP):SCALE+=0.1elif(key==GLUT_KEY_DOWN):SCALE-=0.1glutPostRedisplay()mouseX,mouseY=0,0
def mouseClick(button=0,state=0,x=0,y=0):glutPostRedisplay()def mouseDownAndMove(x=0,y=0):global DX,DYglobal mouseX,mouseYDX+=x-mouseXDY+=-(y-mouseY)#因为原点在左上角,Y轴与图形的Y轴颠倒,故取反mouseX=xmouseY=yglutPostRedisplay()def mouseMove(x=0,y=0):global mouseX,mouseYmouseX=xmouseY=yglutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(400, 400)
glutCreateWindow("test")
glutDisplayFunc(drawFunc)#回调函数
glutMouseFunc(mouseClick)#鼠标点击时调用
glutMotionFunc(mouseDownAndMove)#鼠标按下并移动时调用——原点在左上角
glutPassiveMotionFunc(mouseMove)
glutSpecialFunc(specialKey)#键盘交互
init()
glutMainLoop()

python切片:

https://www.jianshu.com/p/15715d6f4dadhttps://www.jianshu.com/p/15715d6f4dad

a=[1,2,3,4,5]
for i in a[0:-1]:print(i)

输出:看来不包括最后的-1索引的那个

python 优先级
https://www.jb51.net/article/198848.htmhttps://www.jb51.net/article/198848.htm

用于重组图元的一种可能的数据结构:

https://www.runoob.com/python3/python3-set.htmlhttps://www.runoob.com/python3/python3-set.html测试:

#什么数据结构比较好呢?列表里套很多集合行吗?
p=[]
p0=set()
p1=set()
p2=set()for i in range(5):p0.add(i)for i in range(5):p1.add(i)for i in range(5):p2.add(i)
p2.add(4)#集合,自动去重p.append(p0)
p.append(p1)
p.append(p2)print(p)if 3 in p[0]:print("is")

测试结果

求两个集合的并集

https://www.runoob.com/python3/ref-set-union.htmlhttps://www.runoob.com/python3/ref-set-union.html判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。

https://www.runoob.com/python3/ref-set-isdisjoint.htmlhttps://www.runoob.com/python3/ref-set-isdisjoint.html这两个方法也许能用的上……

它返回false……

哦……is——dis——joint,了解了

正式开始

#正式开始重组图元from asyncio.windows_events import NULL
from os import statimport dxfgrabber
import math
import numpy as npfrom OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *inputFilePath='e:/test3-11/Drawing4.dxf'  #输入文件的路径#供读取的数据结构
class Line:def __init__(self,id,start,end):self.id=idself.start=startself.end=end
LINELIST=[]class Arc:def __init__(self,id,center,radius,startAngle,endAngle) -> None:self.id=idself.center=centerself.radius=radiusself.start_angle=startAngleself.end_angle=endAnglepass
ARCLIST=[]VIRTUALLIST=[]SCALE=1.0#用于缩放
DX,DY=0,0#用于移动#读取
dxf = dxfgrabber.readfile(inputFilePath)
lineNum=0
arcNum=0
for e in dxf.entities:if e.dxftype == 'LINE':LINELIST.append(Line(lineNum,e.start,e.end))lineNum+=1elif e.dxftype=='ARC':ARCLIST.append(Arc(arcNum,e.center,e.radius,e.start_angle,e.end_angle))arcNum+=1
#图元重组def intersectionTestLineAndArc(line,arc)->bool:#python怎么解方程——先从简处理吧x=arc.center[0]+arc.radius*math.cos(arc.start_angle/180*math.pi)y=arc.center[1]+arc.radius*math.sin(arc.start_angle/180*math.pi)p0=np.array([x,y])x=arc.center[0]+arc.radius*math.cos(arc.end_angle/180*math.pi)y=arc.center[1]+arc.radius*math.sin(arc.end_angle/180*math.pi)p1=np.array([x,y])p2=np.array(line.start[0:2])p3=np.array(line.end[0:2])d=list(range(4))d[0]=np.sum(np.square(p0-p2))d[1]=np.sum(np.square(p0-p3))d[2]=np.sum(np.square(p1-p2))d[3]=np.sum(np.square(p1-p3))if min(d)<=1:return Truereturn Falsedef intersectionTest()->set:#加入新图元后,与之前加入的图元进行相交测试,返回与之相交的图元集合global VIRTUALLISTresult=set()#空集合if len(VIRTUALLIST)==1:return resultentity=VIRTUALLIST[-1]#列表的最后一个就是新加入的图元for virtualEntity in VIRTUALLIST[0:-1]:#目前,只能处理直线和弧的关系,排列组合……2*2if type(entity)==Line and type(virtualEntity)==Line:passelif type(entity)==Line and type(virtualEntity)==Arc:pass        elif type(entity)==Arc and type(virtualEntity)==Arc:passelif type(entity)==Arc and type(virtualEntity)==Line:#本例中,只会用到这个分支if intersectionTestLineAndArc(virtualEntity,entity):result.add(virtualEntity)result.add(entity)passelse:passpasselse: passreturn resultINTERSECTIONLIST=[]for line in LINELIST:VIRTUALLIST.append(line)result=intersectionTest()for arc in ARCLIST:VIRTUALLIST.append(arc)result=intersectionTest()if len(result)!=0:newCluster=True#是否是新的一簇图形if len(INTERSECTIONLIST)==0:INTERSECTIONLIST.append(result)newCluster=Falseelse:for iL in INTERSECTIONLIST:if not iL.isdisjoint(result):#双重否定,等于肯定temp=iL.union(result)#获取下标index=INTERSECTIONLIST.index(iL)#修改list中的指定set:INTERSECTIONLIST[index]=tempnewCluster=Falseif newCluster:INTERSECTIONLIST.append(result)else:continue#按照相交关系,重组完成
print(INTERSECTIONLIST)#显示——OpenGL def init():glClearColor(0.3, 0.3, 0.3, 1.0)gluOrtho2D(0, 400.0, 0, 400)#窗口坐标系的大小,左下角是原点def drawFunc():glClear(GL_COLOR_BUFFER_BIT)glPushMatrix()glScale(SCALE,SCALE,1.0)#缩放——OpenGL里没有鼠标滚轮.pyQT里有吗?glTranslatef(DX,DY,0)#绘制所有直线glBegin(GL_LINES)for line in LINELIST:glVertex2f(line.start[0],line.start[1])glVertex2f(line.end[0],line.end[1])glEnd()#用描点的形式绘制所有弧线glBegin(GL_POINTS)for arc in ARCLIST:start_angle=arc.start_angle/180.0*math.piend_angle=arc.end_angle/180*math.pi#CAD里,圆弧都是从起点到终点,顺时针转的;所以,这里只取正值dAngle=abs(end_angle-start_angle)pointNum=500#一个弧500个点for i in range(0,pointNum):x=arc.center[0]+arc.radius*math.cos(start_angle+dAngle*i/pointNum)y=arc.center[1]+arc.radius*math.sin(start_angle+dAngle*i/pointNum)glVertex2f(x,y)glEnd()glPopMatrix()glFlush()#方向键选择图元
def specialKey(key=0,x=0,y=0):global SCALEif (key==GLUT_KEY_UP):SCALE+=0.1elif(key==GLUT_KEY_DOWN):SCALE-=0.1glutPostRedisplay()mouseX,mouseY=0,0
def mouseClick(button=0,state=0,x=0,y=0):glutPostRedisplay()def mouseDownAndMove(x=0,y=0):global DX,DYglobal mouseX,mouseYDX+=x-mouseXDY+=-(y-mouseY)#因为原点在左上角,Y轴与图形的Y轴颠倒,故取反mouseX=xmouseY=yglutPostRedisplay()def mouseMove(x=0,y=0):global mouseX,mouseYmouseX=xmouseY=yglutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(400, 400)
glutCreateWindow("test")
glutDisplayFunc(drawFunc)#回调函数
glutMouseFunc(mouseClick)#鼠标点击时调用
glutMotionFunc(mouseDownAndMove)#鼠标按下并移动时调用——原点在左上角
glutPassiveMotionFunc(mouseMove)
glutSpecialFunc(specialKey)#键盘交互
init()
glutMainLoop()

结果如下——希望不是只对这一个DXF文件有效……

数据结构,debug,调试,有系统的编程,编着改着改着编着……脑力劳动。

困难,顺利,永远都有。

矛盾的双方,相比较而存在,相斗争而发展。

没有矛盾就没有世界。

下回预告:

怎么用鼠标,交互选择图元呢?

鼠标框选?需要所有图元和框出来矩形求交才行。又涉及到一些数学上的计算。

也许以后还会用到pyqt?

https://maicss.gitbook.io/pyqt-chinese-tutoral/pyqt5/indexhttps://maicss.gitbook.io/pyqt-chinese-tutoral/pyqt5/index

目前,硬件条件良好,暂时不卡,希望能用到六月底吧。

DXF图元数据的组织相关推荐

  1. AutoCAD中扩展图元数据的应用

    1 引 言 autocad有非常强大的图形编辑功能,但是与gis系统软件arc/info.mapinfo相比,其属性库功能相对较弱.在autocad数据库中,只是记录着表示图形元素的几何位置.形状.大 ...

  2. BLOCK层代码分析(1)数据的组织BIO

    对于BLOCK层,表示一个IO的数据结构为BIO和request.对于request在后续的章节中做介绍,这里只介绍与BIO相关的结构体. 1. bio/bio_vec结构体 bio结构体用于表示数据 ...

  3. python表格类型数据的组织维度是_Python数据分析 - Numpy

    原标题:Python数据分析 - Numpy 前言 NUMPY(以下简称NP)是Python数据分析必不可少的第三方库,np的出现一定程度上解决了Python运算性能不佳的问题,同时提供了更加精确的数 ...

  4. 业务、数据和组织:阿里巴巴的中台不只是技术战略

    马爸爸果断地掀起了中台战事 2019年被称为"中台元年",部分企业初尝中台甜头.各大机构"你方唱罢我登场",争相加入这场"马爸爸掀起的中台战事&quo ...

  5. 中央集权制和分封制对数据部门组织绩效的影响

    编 辑:彭文华 来 源:大数据架构师(ID:bigdata_arch) 彭友们好,我是你的老彭友.今天我们聊聊公司的数据组织. 嗯,今天有福利,送5本书,具体见文末. 网上经常会传出这样的新闻:某公司 ...

  6. 网络训练需要的混合类型数据的组织方式

    在准备神经网络模型需要的训练数据时,经常需要构造顺手的数据形式,如下 特征1 特征2 特征3 - 特征n 标签 37.584 37.632 38.045 - 38.902 'a' 33.216 39. ...

  7. 大数据部门组织架构以及相关团队职能分析

    数据相关分成五大体系 数据研发团队: 研发/执行 分析师辅助: 纯粹技术需求,ETL之类: 分析做实施执行工作: 工程化团队: 实现中台.数据平台等业务的技术实现: 突击团队 快速更新迭代出预期的一个 ...

  8. 大数据部门组织架构(通用型)

    数据平台组 集群运维.性能调优: 基础服务开发 搭建Hadoop.Spark等框架等组件: 基于Hadoop.Spark等的二次开发: 调研.对比服务升级等: 数据仓库组 数据建模 数据分析 ETL ...

  9. 第9章:群体类和群体数据的组织

    第1关:实现链表结点 任务描述 本关任务:编写程序实现节点类 Node,实现链表的基本操作. 编程要求 根据提示,在右侧编辑器补充 Node 类代码,实现 main 函数里调用的成员函数. 测试说明 ...

最新文章

  1. 前端开发应届生面试指南(含各大公司具体指南及面试真题)
  2. 文件服务器错误用友,用友U8.60用友服务器登陆不了,提示文件错误
  3. 人工机器:机器人模块化和双足机器人被动行走
  4. Cordova插件中JavaScript代码与Java的交互细节介绍
  5. 载winpcap4.1.1_最常用的11个电缆载流量数据表,建议收藏备用
  6. FineReport 11.0 全新大屏模式,打开3D视界,大屏制作更快
  7. oracle输出一天所有秒数,Oracle函数通过秒数或分钟数获取时间段
  8. MongoDB常用使用场景介绍
  9. 【BZOJ2818】Gcd,数论练习之欧拉筛
  10. Android学习资料整理:流行框架网站书籍推荐---博客推荐
  11. 【详解】BiLSTM+CRF模型
  12. CorelDRAW2020下载使用教程详解
  13. complicated用法
  14. Jieba分词的准确率提升:使用paddle模式进行分词(使用百度飞桨深度学习模型进行分词)
  15. 资料搜集-JAVA系统的梳理知识3-面试篇
  16. 随机森林python
  17. 潜在语义索引(LSI)
  18. 计算机病毒防治的工作原理,计算机病毒原理及防治.pdf
  19. 前端无法反序列化START\u数组标记-JSONCannot deserialize instance of `java.lang.String` out of START_ARRAY toke
  20. PYTHON模块openpyxl在导出EXCEL文件时设置自动列宽

热门文章

  1. 为什么选择软件测试这个岗位?(面经)
  2. threejs-纹理贴图
  3. 记录四川移动盒子打开adb命令的方法 型号:UNT401H
  4. DBCO-PEG-TAT DBCO-聚乙二醇-TAT
  5. 您可以在Windows PC或Android手机上使用iMessage吗?
  6. 中电海康校招面试数据存储与处理事业部
  7. mysql数据库总是自动关闭_急求关于mysql数据库自动停止的问题
  8. Python 自动识别图片文字—OCR实战教程
  9. Python+OpenCV 识别银行卡卡号
  10. 中国传媒大学GPA算法