It is more like the intersection of the poly’s or splines with a plane i.e., where a curve crosses Z = 15000.
I have to say it is not an easy task in VBA (without the Curve Functions). I could have tried it in C#, but I have no way of testing .NET code against 2006.
Here (and in my original post) I used a Mirror3D and then IntersectWith to get the appropriate intersections.
To use load and run PointsAtElevation
To run a VBA routine:
http://www.cadtutor.net/forum/showthread.php?t=30608
Option ExplicitSub PointsAtElevation()Dim dblPt(2) As DoubleDim ent As AcadEntityDim entMirror As AcadEntityDim varMin As VariantDim varMax As VariantDim dblThird(2) As DoubleDim dblElevation As DoubleDim varElevPt As VariantDim varReturn As VariantDim intCount As IntegerDim i As IntegerDim entPt As AcadPointDim objSS As AcadSelectionSetDim strKeyWordList As StringDim intAxis As IntegerDim strTemp As StringDim dblElev As DoubleDim varFilter As VariantDim strKeyWord As StringDim blnErase As BooleanWith ThisDrawing strKeyWordList = "X x Y y Z z" .Utility.InitializeUserInput 1, strKeyWordList On Error Resume Next strKeyWord = .Utility.GetKeyword("Enter axis of interest [X, Y, Z]: ") If Err Then Exit Sub If UCase(strKeyWord) = "X" Then intAxis = 0 ElseIf UCase(strKeyWord) = "Y" Then intAxis = 1 ElseIf UCase(strKeyWord) = "Z" Then intAxis = 2 Else .Utility.Prompt (vbCr & "Invalid input!") Exit Sub End If strKeyWordList = "*" .Utility.InitializeUserInput 128, strKeyWordList varElevPt = .Utility.GetPoint(, "Select target elevation, or input elevation value: ") strTemp = .Utility.GetInput() If UBound(varElevPt) 2 Then Err.Clear dblElev = CDbl(strTemp) If Err Then Exit Sub Else dblElev = varElevPt(intAxis) End If On Error GoTo 0 varFilter = LoadFilterArray(intAxis) If SoSSS(varFilter(0), varFilter(1)) > 0 Then For Each ent In .SelectionSets("TempSSet") If TypeOf ent Is AcadLWPolyline Then Set ent = ProcessPoly(ent) blnErase = True End If ent.GetBoundingBox varMin, varMax varMin(intAxis) = dblElev varMax(intAxis) = dblElev dblThird(0) = varMin(0) + 1# dblThird(1) = varMin(1) + 1# dblThird(2) = varMin(2) + 1# Set entMirror = ent.Mirror3D(varMin, varMax, dblThird) varReturn = entMirror.IntersectWith(ent, acExtendNone) intCount = ((UBound(varReturn) + 1) / 3) - 1 For i = 0 To intCount dblPt(0) = varReturn(3 * i) dblPt(1) = varReturn(3 * i + 1) dblPt(2) = varReturn(3 * i + 2) ThisDrawing.ModelSpace.AddPoint (dblPt) Next If blnErase Then ent.Delete: blnErase = False entMirror.Delete Next End IfEnd WithEnd SubPrivate Sub SSClear()Dim SSS As AcadSelectionSets Set SSS = ThisDrawing.SelectionSets If SSS.Count > 0 Then Dim objSS As AcadSelectionSet For Each objSS In SSS If objSS.Name = "TempSSet" Then objSS.Delete: Exit Sub Next Else Exit Sub End IfEnd SubFunction SoSSS(Optional grpCode As Variant, Optional dataVal As Variant) As Integer Dim TempObjSS As AcadSelectionSet SSClear Set TempObjSS = ThisDrawing.SelectionSets.Add("TempSSet") 'pick selection set If IsMissing(grpCode) Then TempObjSS.SelectOnScreen Else TempObjSS.SelectOnScreen grpCode, dataVal End If SoSSS = TempObjSS.CountEnd FunctionFunction LoadFilterArray(intAxis As Integer) As VariantDim intCode(21) As IntegerDim varData(21) As VariantDim varArray(1) As VariantDim dblAxis1(2) As DoubleDim dblAxis2(2) As DoubleDim dblAxis3(2) As DoubleDim dblAxis4(2) As Double dblAxis1((intAxis + 1) Mod 3) = 1# dblAxis2((intAxis + 2) Mod 3) = 1# dblAxis3((intAxis + 1) Mod 3) = -1# dblAxis4((intAxis + 2) Mod 3) = -1# intCode(0) = -4: varData(0) = "" varArray(0) = intCode varArray(1) = varData LoadFilterArray = varArrayEnd FunctionFunction ProcessPoly(ent As AcadLWPolyline) As Acad3DPolylineDim dblNormal() As DoubleDim varPLCoord As VariantDim dblCoords() As DoubleDim intUbound As IntegerDim i As IntegerDim varDummy As VariantDim dblElev As DoubleDim dblTransfer(2) As DoubledblNormal = ent.NormaldblElev = ent.ElevationintUbound = ((UBound(ent.Coordinates) + 1) / 2) - 1ReDim dblCoords((((intUbound + 1) * 3) - 1))For i = 0 To intUbound varPLCoord = ent.Coordinate(i) dblTransfer(0) = varPLCoord(0) dblTransfer(1) = varPLCoord(1) dblTransfer(2) = dblElev varPLCoord = ThisDrawing.Utility.TranslateCoordinates(dblTransfer, acOCS, acWorld, 0, dblNormal) dblCoords(i * 3) = varPLCoord(0) dblCoords(i * 3 + 1) = varPLCoord(1) dblCoords(i * 3 + 2) = varPLCoord(2)NextSet ProcessPoly = ThisDrawing.ModelSpace.Add3DPoly(dblCoords)End Function
Ahh, maybe the code I posted was not the best suited then
I had a look at using the curve functions in VL, but couldn't think how to get a point on the curve at some user defined elevation without using some iterative process by which one would move along the curve at small intervals until you get close enough by some tolerance to the required elevation
I didn't like this method and so didn't pursue it.
You mention that you used "mirror3d" followed by "intersectWith", just curious (and I am not too conversant with VBA), how did the "mirror3d" come into it
The OP stated that all the Curves in question would be planar and aligned to one of the three main orthographic planes. Because of that a Bounding Box call will return essentially a planar expanse and, if the target elevation is substituted for the appropriate coordinate of min and max, it would create a nice line across the curve.
My original notion was to use that line to IntersectWith the curve. For some reason (which I have yet to figure out) that was not giving me any intersections. For the hell of it, I tried to use identical entities, and figured one was readily available if I 3Dmirrored the original curve about that elevation line and calc’ed point (see Sample).
Ahh, I see - so how I understand it is that "intersectwith" seems to only work in the x-y plane.
Thats funny, because, if you try my posted LISP to find the intersections between the splines and the polylines in the OP's posted drawing, it returns nil until you try it on a spline and pline in the x-y plane.
IntersectWith does seem a bit spotty. The same mirror method does not work with Lightweight polylines. *
I guess with polylines, in particular, their planar quality is virtually a core component of their entity type. It sort of makes sense that their implementation of IntersectWith is extremely sensitive to common planes. Have you tried IntersectWith between a poly and spline on a common plane other than WCS’s XY? It may work if they were both on the XZ, for instance.
Splines are not required to be planar, thus may have gotten a little more attention from the boys at Autodesk with regard to intersections between planes.
* I had to provide a conversion to splines to get my routine to work with LWPolys. In fact, if the polys are too coarse, there may be significant error to the calculated elevation points.
Ahh good thinking Sean, they may have only accommodated intersecting Plines within the same plane.
Tbh, I haven't spent much time on the IntersectWith method ~ I wrote a couple of LISPs a while back though, just messing around with it, could be worth some experimentation with them to see where we stand
They both do pretty much the same thing - find all intersections in a selection set. But the second approach the selection set as a list of entities, whereas the first just hits the set head on.
I was just experimenting with different ways to accomplish the same goal - could be useful though, for testing with IntersectWith.
Nice. Those will help determine where and when intersections can be acquired.
Now that we’ve talked about it, I wonder if 3DPoly’s are more or less capable of finding Intersections. Next time I’m in front of AutoCAD, I’ll use your routine to test them. That alternative may help me reduce the Spline induced error I mentioned previously.