乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 23|回复: 19

[编程交流] 在e处创建垂直线

[复制链接]

14

主题

29

帖子

15

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
70
发表于 2022-7-6 12:09:11 | 显示全部楼层 |阅读模式
大家好,
 
我需要一个VBA代码在每个交点处创建线。直线的起点应为交点(通常为两条直线的交点),终点位于第三条直线的垂线处。
 
有数百个这样的点,所以我真的需要一个VBA代码。
 
谢谢和问候,
普里扬卡
回复

使用道具 举报

10

主题

973

帖子

909

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
118
发表于 2022-7-6 12:15:28 | 显示全部楼层
这听起来是一个有趣的问题,尤其是当它需要3D兼容性时。不幸的是,我今天没有时间调查。
 
如果您可以发布一个示例文件,以更好地说明参数,我将看看明天或周末可以做些什么。
回复

使用道具 举报

14

主题

29

帖子

15

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
70
发表于 2022-7-6 12:18:08 | 显示全部楼层
我附上了一个截图。手动操作很容易,但当你有数百个这样的点时就不行了。
 
请帮忙,
 
谢谢和问候,
普里扬卡
130914dhbhjddxj3wwu7jg.jpg
回复

使用道具 举报

3

主题

136

帖子

133

银币

初来乍到

Rank: 1

铜币
15
发表于 2022-7-6 12:19:52 | 显示全部楼层
如果符号的大小和间距始终相同,那么“测量”命令可能会更好地工作?您可以插入较高的集合,从其起点拉伸直线以匹配两者之间的间距,然后插入第二个集合。
 
编辑:没关系,我看他们不是。
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

铜币
543
发表于 2022-7-6 12:22:05 | 显示全部楼层
我假设您可以使用Lisp,在其中用户将选择第三条线(所有其他连接线垂直的线),然后用户将依次选择每个十字-Lisp每次添加垂直线。但这当然意味着用户将有选择所有十字架的繁琐任务。。。我只是不明白o e怎么能让ACAD认识到每一对线都是一个十字架,需要一条线。。。但是VBA也许可以完成这样的任务。。。
回复

使用道具 举报

10

主题

973

帖子

909

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
118
发表于 2022-7-6 12:26:45 | 显示全部楼层
我假设从屏幕截图来看,我们严格处理的是2D几何。这很幸运,因为3D解决方案可能要复杂得多。
 
即使是平面几何,计算也非常多。交叉点的可能数量随着选择集的大小呈几何级数增加(Lee Mac提到的情况)。
 
下面的例程并不比标准的“暴力”方法好多少,因此任何可以将行数限制为仅与之相关的行数的方法都将有助于提高速度。
 
我已经完成了有限的测试和错误检查,因此请继续相应的操作。
 
  1. Sub Inters2Perp() 'Main sub
  2. Dim SOS As AcadSelectionSet
  3. Dim objSS As AcadSelectionSet
  4. Dim intCode(1) As Integer
  5. Dim varData(1) As Variant
  6. Dim objEnt As AcadEntity
  7. Dim entBaseLine As AcadLine
  8. Dim colPt As New Collection
  9. Dim ent As AcadEntity
  10. Dim varPt As Variant
  11. With ThisDrawing
  12.   On Error Resume Next
  13.   .Utility.GetEntity ent, varPt, "Select the line to which perpendiculars will land: "
  14.   If Err <> 0 Or Not TypeOf ent Is AcadLine Then
  15.      .Utility.Prompt "Operation aborted!" & vbCr
  16.      Exit Sub
  17.   End If
  18.   On Error GoTo 0
  19.   Set entBaseLine = ent
  20.   
  21.   For Each SOS In .SelectionSets
  22.      If SOS.Name = "MySS" Then
  23.         .SelectionSets("MySS").Delete
  24.      Exit For
  25.      End If
  26.   Next
  27.   
  28.   intCode(0) = 0: varData(0) = "LINE"
  29.   intCode(1) = 8: varData(1) = "*" 'replace * with layer name of crossing lines
  30.   .SelectionSets.Add ("MySS")
  31.   Set objSS = ThisDrawing.SelectionSets("MySS")
  32.   objSS.SelectOnScreen intCode, varData
  33.   
  34.   
  35.   If objSS.Count < 1 Then
  36.      MsgBox "No lines and polylines selected!"
  37.      Exit Sub
  38.   End If
  39.   
  40.   Set colPt = GenCollection(objSS)
  41.   GenLines colPt, entBaseLine
  42.   
  43. End With
  44. End Sub
  45. Function GenCollection(objSS As AcadSelectionSet) As Collection
  46. Dim colPt As New Collection
  47. Dim entPrimary As AcadLine
  48. Dim entSecondary As AcadLine
  49. Dim varPt As Variant
  50. Dim i As Integer
  51. Dim entObj(0) As AcadEntity
  52.   Do While objSS.Count > 1
  53.      Set entPrimary = objSS.Item(0)
  54.      For i = 1 To objSS.Count - 1
  55.         Set entSecondary = objSS.Item(i)
  56.         varPt = entPrimary.IntersectWith(entSecondary, acExtendNone)
  57.         If UBound(varPt) > 1 Then colPt.Add (varPt)
  58.      Next
  59.      Set entObj(0) = entPrimary
  60.      objSS.RemoveItems entObj
  61.   Loop
  62.   Set GenCollection = colPt
  63. End Function
  64. Private Sub GenLines(colPt As Collection, entBaseLine As AcadLine)
  65. Dim dblAngle As Double
  66. Dim varPt As Variant
  67. Dim dblEndPt() As Double
  68. Dim entLine As AcadLine
  69. dblAngle = ThisDrawing.Utility.AngleFromXAxis(entBaseLine.StartPoint, entBaseLine.EndPoint) + 1.5707963268
  70. For Each varPt In colPt
  71.   dblEndPt = ThisDrawing.Utility.PolarPoint(varPt, dblAngle, 1#)
  72.   Set entLine = ThisDrawing.ModelSpace.AddLine(varPt, dblEndPt)
  73.   On Error Resume Next
  74.   entLine.EndPoint = entLine.IntersectWith(entBaseLine, acExtendThisEntity)
  75.   If Err <> 0 Then entLine.Delete
  76.   Err.Clear
  77. Next
  78. End Sub
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

铜币
543
发表于 2022-7-6 12:28:41 | 显示全部楼层
啊,所以这是可以做到的。。。我想这里面有很多“试错法”。。。
回复

使用道具 举报

10

主题

973

帖子

909

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
118
发表于 2022-7-6 12:32:36 | 显示全部楼层
 
绝对地例行程序将检查每个选定行与其他选定行。
 
乍一看,我以为你的帖子在写例行公事的时候说“有很多”尝试和错误“,我想“他怎么知道的?”
回复

使用道具 举报

10

主题

973

帖子

909

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
118
发表于 2022-7-6 12:37:00 | 显示全部楼层
为了便于讨论:
 
假设这是一个经常出现的任务,并且处理非常大的交叉线集(>10000),那么什么是好的优化方案呢?
 
我想为SS生成一个边界框,然后再细分为9或16。基于线条端点的过滤选择集可以分离出一口大小的块。这将避免许多交叉口测试失败,但可能会错过靠近边界的一些目标线。
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

铜币
543
发表于 2022-7-6 12:38:26 | 显示全部楼层
是的,正如你所说,让例行程序比较两行的每一个组合是极其乏味的:
 
例如,如果一个有50行,如果程序执行两行的每个组合,即比较行L1和L2,但也比较L2和L1,则组合的数量如下:
 
[50!/48!] ~ 2450
 
但如果程序知道,如果它已经比较了L1和L2,而不是稍后比较L2和L1,则该数字将减少为:
 
[50!/2(48!)] ~ 1225
 
如果我的数学是正确的(统计数据从来不是我的强项!)
 
但是,将其分开会有所帮助,因为计算的数量将大大减少,但显然例程的准确性也会有所降低。。
 
艰难的决定。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-5 07:08 , Processed in 0.339298 second(s), 74 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表