维德发现,至少对我来说:点有维度!
我有了这个发现,至少对我来说,我开始了一个新的程序,用块填充一个封闭的区域。It#039;这只是一个更大的事情的开始,但通常我第一次尝试VBA,因为我发现开发速度更快下面的代码创建了一个样本闭合区域,然后检查一个点(在我的例子中是块的插入点)是否在该区域内;有不同解决方案的常见问题。在我的例子中,a只是创建了一个临时点,并检查它是否在我的区域内,如果结果是真的,那么…插入块,否则跳到下一个点。通过测试,我发现我认为在AutoCAD中作为图形显示的PointStyle和PointSize变量具有真实尺寸。我改变了点样式,以直观地看到我的点要去哪里。我你运行代码两次,第二次运行PDMODE变量被更改的部分,你';我会看到区别的。此外,如果在测试点是否在内部之前更改缩放部分,则会得到不同的结果。我认为点是一个没有维度的位置 
I';我只是分享我的发现,以防有人没有#039;我不知道这件事
Option Explicit
Sub TestPointDimension()
' Draw a closed polyline
Dim points(7) As Double
points(0) = 100#: points(1) = 10#
points(2) = 200#: points(3) = 50#
points(4) = 100#: points(5) = 100#
points(6) = 0#: points(7) = 50#
Dim objLWPoly As AcadLWPolyline
Set objLWPoly = ThisDrawing.ModelSpace.AddLightWeightPolyline(points)
objLWPoly.Closed = True
' Set Spacing of points for the test
' I have set the spacing to 5 just to just to have more false points
' results
Dim XSpacing As Double: XSpacing = 5#
Dim YSpacing As Double: YSpacing = 5#
' Create TestPoint
Dim TestPoint(2) As Double
TestPoint(0) = 0#: TestPoint(1) = 0#: TestPoint(2) = 0#
' Update Viewport
' This is needed to optimize the SelectByPolygon:
' ONLY objects VISIBLE in screen are evaluated
Application.ZoomExtents
Application.Update
' Test with PDMode = 66
ThisDrawing.SetVariable "PDMODE", 66
' I get 419 points Inside the closed area
' and 44 of these are Outside the closed area
' ' Test with PDMode = 0
' ThisDrawing.SetVariable "PDMODE", 0
' ' I get 375 points Inside the closed area
' Star Testing points
Dim objPoint As AcadPoint
' I'm intentionaly going outside the closed area
Do While TestPoint(1)150 Then Exit Do
If TestPoint(0) > 250 Then GoTo UpdatePto
' Insert Points
Set objPoint = ThisDrawing.ModelSpace.AddPoint(TestPoint)
Application.Update
' Check if point is inside the closed area
If Not IsInside(objPoint.Coordinates, objLWPoly) Then
' Delete point
objPoint.Delete
End If
UpdatePto:
' Update Insert Point
TestPoint(0) = TestPoint(0) + XSpacing
Loop
' increment row
TestPoint(0) = 0#
TestPoint(1) = TestPoint(1) + YSpacing
TestPoint(2) = TestPoint(2)
Loop
End Sub
' Checks if a Point is inside a lwPolyline
Function IsInside(ByVal acPoint As Variant, lwPoly As AcadLWPolyline) As Boolean
' Initialize Return value
IsInside = False
Dim objSS As AcadSelectionSet ' temporary SelectionSet
Dim initCodes(2) As Integer ' objSS filter codes
Dim varCodeValues(2) As Variant ' objSS filter values
Dim retCoords As Variant ' lwPoly coordinates
Dim PointsArray() As Double ' Array of 3D Points for objSS crossing polygon
Dim retPto As Variant ' coordinates of found point
Dim ent As AcadEntity ' entity
Dim i As Integer ' counter
Dim j As Integer ' counter
' Create SelectionSet
Set objSS = PowerSet("myPolygon")
' DXF Filter
initCodes(0) = -4
varCodeValues(0) = ""
' Retrieve lwPolyline Coordiantes and fill 3D Points for Crossing Polygon
retCoords = lwPoly.Coordinates
ReDim PointsArray((((UBound(retCoords) + 1) / 2) * 3) - 1)
' get the X coordinates
For i = 0 To UBound(PointsArray)
For j = 0 To UBound(retCoords) Step 2
PointsArray(i) = retCoords(j)
i = i + 3
Next j
Next i
' get the Y coordiantes
For i = 1 To UBound(PointsArray)
For j = 1 To UBound(retCoords) Step 2
PointsArray(i) = retCoords(j)
i = i + 3
Next j
Next i
' fill the Z coordinates with 0, lwPolyline doesn't have Z
For i = 2 To UBound(PointsArray) Step 3
PointsArray(i) = 0
Next i
' Fill the objSS
objSS.SelectByPolygon acSelectionSetCrossingPolygon, PointsArray, _
initCodes, varCodeValues
' get ents in objSS
If objSS.Count >= 1 Then
For Each ent In objSS
retPto = ent.Coordinates
If retPto(0) = acPoint(0) And retPto(1) = acPoint(1) Then
IsInside = True
Exit Function
Else
IsInside = False
End If
Next ent
Else
IsInside = False
End If
End Function
'Restituisce un 'SelectionSet' evitando i nomi duplicati
' Credit goes to Randal Rath's Code Troute I think, I use this since (?)
Function PowerSet(setName As String) As AcadSelectionSet
Dim objSS As AcadSelectionSet
Dim objSSCol As AcadSelectionSets
On Error GoTo ErrorHandler
Set objSSCol = ThisDrawing.SelectionSets
For Each objSS In objSSCol
If objSS.Name = setName Then
objSSCol.Item(setName).Delete
Exit For
End If
Next
Set objSS = objSSCol.Add(setName)
Set PowerSet = objSS
ExitHere:
Exit Function
ErrorHandler:
Select Case Err.Number
Case Else
MsgBox Err.Description
Err.Clear
Resume ExitHere
End Select
End Function
我没有';用lisp或.Net进行计算,但我想它会给出相同的结果。
您是“;检查“;基于使用可见对象的交叉选择集。更改PDMODE时(&M);PDSIZE变量对象以不同的方式显示,从而允许选择能够根据“如何”进行更多/更少的选择;“大”;将显示该点。这就是为什么使用数学计算的另一个IsInside解决方案会给出更好的结果  ; 我同意,我的意思是,我认为屏幕上显示的点只是屏幕上的一个图形,而不是AutoCAD可以做到的;触摸“;因为它改变了缩放。我深信,在选择的时候,即使是交叉,因为它#039;s的矢量图,而不是图像,选择是纯粹的数学。 我认为,除了当前的行为之外,任何其他行为都是不一致的
以C3D点为例,这些点可能也有标签 ;如果我使用交叉窗口,我希望它选择点,即使交叉窗口仅接触标签的一部分 ;如果忽略点,除非我在点节点周围专门放置交叉窗口,那么从用户角度来看,这将更加恼人
这意味着你可以';不要使用这种方法,你试图得到你想要的结果,但我认为这与交叉窗口的工作方式是一致的。  ;我想我';我没有解释我觉得奇怪的事情
如果替换IsInside函数中的此行:
' Fill the objSS
objSS.SelectByPolygon acSelectionSetCrossingPolygon, PointsArray, _
initCodes, varCodeValues
带有:
' Fill the objSS
objSS.SelectByPolygon acSelectionSetWindowPolygon, PointsArray, _
initCodes, varCodeValues
你';re not“;交叉点;,你';重复使用“a”;窗口;,但在这种情况下,该区域充满了孔洞
无论如何,这个方法对我来说已经足够有效了,我只是分享了一些我认为不是的东西;不太为人所知。
页:
[1]