python-CAD绘制等高线

基于python的CAD等高线绘制 这是我本科在做《路基工程课程设计》挡土墙设计的时候,老师只给了原始地面数据点,因为疫情在家时间充裕,我就摸索了python画CAD,最终实现了绘制不同等高距的等高线绘制。 python面向对象编程。 基础知识 我这个代码只适合地面趋势简单的,通过差值得到固定整数高程点,然后将相同高程点依次连接。 note: 当时是在windows先写的代码,因为要用到win32com.client这个库,所以我估计 Mac下应该用不了,但可以修改代码绘制dxf文件,不调用CAD。 后续我再补充 Excel文件、输出CAD的文件及效果图 源代码 # _*_ coding:utf-8- _*_ from pyautocad import APoint, Autocad, aDouble import win32com.client import numpy as np dgj = 0.5 # 等高距 ctfs = 10 # 放大倍数,本身采取m为单位绘制,可能放大10倍后输出效果好些 """ 等高线计算 """ #连接excel读取数据,这个地方可以做一个前处理,直接把excel数据作为数组或者numpy数组进行处理 xlapp = win32com.client.Dispatch("Excel.Application") wb = xlapp.ActiveWorkbook ws = xlapp.ActiveWorkbook.ActiveSheet """ K58+70向右走为前进方向,绘制在 """ """ First 定义一个类,输入 list,其元素为APoint 内部函数得到插值的数据点,打印点数据 """ class nei_cha: def __init__(self, pnts = [APoint(0,1)], dgj = 0.5, gu_ding_cha_zhi = "X" ): # gu_ding_cz = "X" 意思是不进行固定插值操作 self.pnts = pnts self.dgj = dgj self.gu_ding_cha_zhi = gu_ding_cha_zhi # 输入两个三维坐标,x/y是相等的,内插得到所需高程 # 返回的是,该区间内得到的点组成的list def do_two_points(self, p1 = APoint(0), p2 = APoint(0)): if self.gu_ding_cha_zhi == "X": nmax = int(max(p1.z, p2.z) // self.dgj) nmin = int(min(p1.z, p2.z) // self.dgj) if nmax == nmin: # 这两个点之间内插不出来 return 0 else: nmax = self.gu_ding_cha_zhi nmin = self.gu_ding_cha_zhi - 1 if (p1.z - nmax) * (p2.z - nmin) > 0: # 固定插值不在区间内 return 0 if p1.x == p2.x: # x坐标一样,需要内插Z到y """ 求直线方程,y """ k = (p1.y - p2.y)/(p1.z - p2.z) b = p1.y - k * p1.z if self.gu_ding_cha_zhi == "X": ni = np.array(range(nmin, nmax)).reshape(int(nmax - nmin), 1) zi = (ni + 1) * self.dgj else: ni = np.array([self.gu_ding_cha_zhi]).reshape(int(nmax - nmin), 1) zi = ni yi = np.around(k * zi + b, 3) #yi = np.interp(zi, [p1.z, p2.z], [p1.y, p2.y]) xi = np.full((len(yi), 1), p1.x) pts_np = np.hstack((xi, yi, zi)) return pts_np else: # y坐标一样,需要内插Z得到x return 0 def do_it(self): pnts_np = np.array([]) for i in range(len(self.pnts) - 1): p_np_i = self.do_two_points(self.pnts[i], self.pnts[i+1]) if type(p_np_i) != type(0): try: pnts_np = np.vstack((pnts_np, p_np_i)) except: pnts_np = p_np_i if len(pnts_np) != len(np.array([])): return pnts_np else: return 0 # points是原始地面点高程 ground_points = [] row = 2 while row <= 20: i = 6 # 左侧数据 j = 8 # 右侧数据 # 桩号点绘图坐标 x0 = ((row - 2) / 3) * 10 + 70 y0 = 0 z0 = ws.cells(row, 7).value p0 = APoint(x0, y0, z0) pts = [] pts.append(p0) # 拾取左侧点数据 while i >= 1: try: z_ = ws.cells(row, i).value y_ = ws.cells(row + 1, i).value pti = pts[-1] + (0, y_, z_) pts.append(pti) except: pass i -= 1 # 拾取右侧点数据 while ws.cells(row, j).value: try: z_ = ws.cells(row, j).value y_ = - ws.cells(row + 1, j).value ptj = pts[0] + (0, y_, z_) pts.insert(0, ptj) except: print("右侧点拾取失败了:cells(%d,%d)"% (row, j)) pass j += 1 ground_points.append(pts) for i in pts: print(i) print("") row = row + 3 # 利用上方点开始使用类进行,插值 all_np = [] for i in ground_points: cha_zhi_la = nei_cha(i, dgj) a = cha_zhi_la.do_it() try: all_np = np.vstack((all_np, a)) except: all_np = a pts_all = [APoint(list(i)) for i in all_np] pts_all.sort(key = lambda x:x.z) del all_np h_min = pts_all[0].z h_max = pts_all[-1].z zzzi = h_min sorted_pts = [] while zzzi <= h_max: _ = [i for i in pts_all if i.z == zzzi] _.sort(key = lambda x:x[0]) sorted_pts.append(_) zzzi += dgj del pts_all for i in sorted_pts: elevation = i[0].z print("高程为 %s 的数据点"% elevation) for l_ in i: print(l_) # 连接cad,并输出结果 del sorted_pts[0:11] del sorted_pts[-10:-1] acad = Autocad(create_if_not_exists=True) acad.prompt("connect with the Autocad successfully.") print("connect with the Autocad successfully.") dwg = acad.ActiveDocument # 定义等高线图层 dgx = acad.doc.layers.add("等高线") dgx.LineWeight = 25 dwg.ActiveLayer = dgx dgxbz = acad.doc.layers.add("等高线标注") for m in range(len(sorted_pts)): i = sorted_pts[m] elevation = i[0].z print("高程为 %s 的数据点"% elevation) for l_ in i: print(l_) try: for j in i: j.z = 0 pt = aDouble([j for _ in i for j in _ * ctfs]) hl = acad.model.AddPolyLine(pt) hl.LineWeight = 25 hl.Elevation = elevation hl.Thickness = 900 if m % 5 == 0: hl.LineWeight = 100 hl.color = 1 text_string = elevation insertpt = i[0] * ctfs textobj = acad.model.addMtext(insertpt, 26, text_string) textobj.Height = 8 textobj.BackgroundFill = True textobj.color = 1 textobj.layer = "等高线标注" except: print('*' * 10, "高程为 %s 的数据点不足,跳过绘制此等高线"% elevation) pass

2022年5月24日 · 3 分钟 · Vinkey

you-get命令行视频下载工具

you-get介绍 一、安装 更多方式请参考you-get GitHub主页 环境依赖 以下为必要配置: Python 3.5 或更高版本 FFmpeg 1.0 或更高版本 (可选) RTMPDump 方法 1: 通过 pip 安装(Mac/Windows) 首先配置python3环境,然后通过pip命令直接安装you-get,如果电脑只有python3一个版本,则使用pip install you-get即可,如果有python2,则使用pip3命令,即pip3 install you-get The official release of you-get is distributed on PyPI, and can be installed easily from a PyPI mirror via the pip package manager. Note that you must use the Python 3 version of pip: pip3 install you-get 方法 2: Homebrew (Mac only) You can install you-get easily via: ...

2022年5月23日 · 4 分钟 · Vinkey

Excel vba修改数据图表格式

场景描述 修改坐标轴区间及交叉位置 代码 Sub change_pic() ' ' 修改数据图像格式,不需要的可以直接注释或修改参数 ' 'y轴的显示区间,设置为自动,如果输入自定义,使用.MinimumScale进行赋值 ActiveChart.Axes(xlValue).MinimumScaleIsAuto = True ActiveChart.Axes(xlValue).MaximumScaleIsAuto = True 'x轴与y轴对齐的y坐标,这里读取了上一步的y轴最小值,即坐标轴放在下方 ActiveChart.Axes(xlValue).CrossesAt = ActiveChart.Axes(xlValue).MinimumScale End Sub

2022年5月23日 · 1 分钟 · Vinkey