TheSwamp
Code Red => VB(A) => Topic started by: David Hall on November 17, 2006, 02:52:08 PM
-
OK, i have stumped myself again. Im trying to define a new ucs and draw a cylinder in that ucs, not the wcs. here is my code so far
Public Sub ucstest()
Dim ucsObj As AcadUCS
Dim origin As Variant
Dim xAxisPnt(0 To 2) As Double
Dim yAxisPnt(0 To 2) As Double
Dim ucsorigion(0 To 2) As Double
' Define the UCS
origin = Null
origin = ThisDrawing.Utility.GetPoint
xAxisPnt(0) = origin(0): xAxisPnt(1) = origin(1): xAxisPnt(2) = origin(2) - 1
yAxisPnt(0) = origin(0): yAxisPnt(1) = origin(1) + 1: yAxisPnt(2) = origin(2)
' Add the UCS to the UserCoordinatesSystems collection
Set ucsObj = ThisDrawing.UserCoordinateSystems.Add(origin, xAxisPnt, yAxisPnt, "New_UCS")
ThisDrawing.ActiveUCS = ucsObj
ThisDrawing.ModelSpace.AddCylinder origin, 1, 3
End Sub
I think I need to transform my coords somehow, but I have never done that, so any ideas what I should do?
-
the cylinder uses this
RetVal = object.AddCylinder(Center, Radius, Height)
Object
ModelSpace Collection, PaperSpace Collection, Block
The object or objects this method applies to.
Center
Variant (three-element array of doubles); input-only
A 3D WCS coordinates specifying the center of the bounding box.
Radius
Double; input-only
The cylinder radius. Must be a positive number.
Height
Double; input-only
The cylinder height. Must be a positive number.
RetVal
3DSolid object
A 3DSolid object as the newly created cylinder.
the variant is in WCS, and i think that is my problem
-
Or for those that want the big picture, what I really need to do is
1-draw a circle
2-rotate3d the circle to horizontal or vertical based on extrude direction
3-extrude circle along a path
-
When you insert the circle it is inserted in world coordinates but it will assume the normal of the currnt ucs. Set the circle.normal to 0,0,1 then transform the circle using your ucsmatrix
-
If you just wanna draw a circle and extrude, carry on...
... but
There is the cylinder command that asks for the first end center and radius, then prompts for "height of cylinder or [Center of other end]" and it allows you to place the center of the other end anywhere in space regardless of UCS. Might be worth an investigation.
-
its really dirty, but my brain is shutting down.
This works, but there are a few quirks:
1-you pick a line that defines where the cylinder goes
2-you pick the midpoint of the line b/c the cylinder gets placed by the centroid
3-you have to pick a third point perp to the line (ortho/polar on is a good thing)
Public Sub ucstest()
Dim origin As Variant
Dim xAxisPnt As Variant
Dim yAxisPnt(0 To 2) As Double
Dim ucsorigion(0 To 2) As Double
Dim objcyl As Acad3DSolid
Dim dblLength As Double
Dim objLine As AcadLine
Dim varpick As Variant
Dim obje As AcadEntity
ThisDrawing.Utility.GetEntity obje, varpick
Set objLine = obje
dblLength = objLine.Length
origin = Null
origin = ThisDrawing.Utility.GetPoint
xAxisPnt = ThisDrawing.Utility.GetPoint(origin)
Set objcyl = ThisDrawing.ModelSpace.AddCylinder(origin, 1, dblLength)
Dim ang As Double
ang = 90
ang = ang * 3.141592 / 180#
objcyl.Rotate3D origin, xAxisPnt, ang
End Sub
More cleanup required on Monday
-
Here's a couple of examples.
The first 2 work with the normal and the third uses a ucs
Public Sub CylinderFromLine()
Dim oCyl As Acad3DSolid
Dim oCircle As AcadCircle
Dim oLine As AcadLine
Dim varpick As Variant
Dim Ent As AcadEntity
Dim N, oReg
Dim RegEnt(0) As AcadEntity
Dim V(2) As Double
Dim Unit As Double
Dim Vn(2) As Double
Dim P1, P2
ThisDrawing.Utility.GetEntity Ent, varpick
If Not TypeOf Ent Is AcadLine Then Exit Sub
Set oLine = Ent
' V = oLine.Delta 'Don't use the treacherous delta
P1 = oLine.StartPoint: P2 = oLine.EndPoint
V(0) = P2(0) - P1(0): V(1) = P2(1) - P1(1): V(2) = P2(2) - P1(2)
'Normalise the vector(It's length=1)
Unit = Sqr(V(0) * V(0) + V(1) * V(1) + V(2) * V(2))
Vn(0) = V(0) / Unit: Vn(1) = V(1) / Unit: Vn(2) = V(2) / Unit
Set oCircle = ThisDrawing.ModelSpace.AddCircle(oLine.StartPoint, 1)
oCircle.Normal = Vn
Set RegEnt(0) = oCircle
oReg = ThisDrawing.ModelSpace.AddRegion(RegEnt)
Set oCyl = ThisDrawing.ModelSpace.AddExtrudedSolid(oReg(0), oLine.Length, 0)
End Sub
Public Sub CylinderFromPoints()
'this mimics the Cylinder command
Dim oCyl As Acad3DSolid
Dim oCircle As AcadCircle
Dim Rad As Double
Dim P1, P2
Dim N, oReg
Dim dLength As Double
Dim RegEnt(0) As AcadEntity
Dim Util As AcadUtility
Set Util = ThisDrawing.Utility
P1 = Util.GetPoint(, "Specify center point for base of cylinder:")
Rad = Util.GetDistance(ToUcs(P1), "Specify radius for base of cylinder:")
P2 = ThisDrawing.Utility.GetPoint(ToUcs(P1), "Specify center of other end of cylinder:")
Dim V(2) As Double
V(0) = P2(0) - P1(0): V(1) = P2(1) - P1(1): V(2) = P2(2) - P1(2)
Dim Unit As Double
Dim Vn(2) As Double
'Normalise the vector(It's length=1)
Unit = Sqr(V(0) * V(0) + V(1) * V(1) + V(2) * V(2))
Vn(0) = V(0) / Unit: Vn(1) = V(1) / Unit: Vn(2) = V(2) / Unit
dLength = Sqr(V(0) ^ 2 + V(1) ^ 2 + V(2) ^ 2)
Set oCircle = ThisDrawing.ModelSpace.AddCircle(P1, Rad)
oCircle.Normal = Vn
Set RegEnt(0) = oCircle
oReg = ThisDrawing.ModelSpace.AddRegion(RegEnt)
Set oCyl = ThisDrawing.ModelSpace.AddExtrudedSolid(oReg(0), dLength, 0)
End Sub
Public Sub CylinderFromUcs()
Dim oUcs As AcadUCS
Dim Orig As Variant
Dim xAxisPnt(0 To 2) As Double
Dim yAxisPnt(0 To 2) As Double
Dim oCyl As Acad3DSolid
Orig = ThisDrawing.Utility.GetPoint
Set oCyl = ThisDrawing.ModelSpace.AddCylinder(Zero, 1, 3)
' Define the UCS
xAxisPnt(0) = 0: xAxisPnt(1) = 0: xAxisPnt(2) = -1
yAxisPnt(0) = 0: yAxisPnt(1) = 1: yAxisPnt(2) = 0
Set oUcs = ThisDrawing.UserCoordinateSystems.Add(Zero, xAxisPnt, yAxisPnt, "New_UCS")
oUcs.origin = Orig
oCyl.TransformBy oUcs.GetUCSMatrix
End Sub
Function ToUcs(pt As Variant) As Variant
ToUcs = ThisDrawing.Utility.TranslateCoordinates(pt, acWorld, acUCS, False)
End Function
-
Bryco, those work perfectly. :-D :-) :-D
Now, can you explain what is happening so I know what is happening so I can use that in the future? Great job.
-
Thanks CmdrDuh. I was going to try an article on this stuff but it's going to take a little while.
Beware of the Ucs method for objects other than cylinders, for some reason a cylinder works a little different than other entities.
Help says "Creates a 3D solid cylinder whose base is on the XY plane of the WCS." Usually you insert something in world, make sure the normal is 0,0,1, then transform it to the ucs (or matrix) you want.
-
Bryco, I enjoyed with your code again
Thanks for elegance
(Ya da ..)
:)
Fatty
>'J'<
-
Couple of things, on the last example, it bombs on using "Zero' as undefined. Probably a snippet from somewhere else.
on to better things:
I think I have figured out part of the math. The P2-P1 part is calculating the delta X, delta Y and Z right? I drew some lines using known XYZ coordinates, and that's what looks like is happening.
now here is where I am not entirely sure whats going on 'Normalise the vector(It's length=1)
Unit = Sqr(V(0) * V(0) + V(1) * V(1) + V(2) * V(2))
Vn(0) = V(0) / Unit: Vn(1) = V(1) / Unit: Vn(2) = V(2) / Unit
After talking with the resident math guru here at work, my question is wouldn't the oCircle.Normal work with V or Vn? I tried it, and it does in fact work. So, my final question is why did you have to normalize the vector?
-
CmdrDuh, Zero is a property that I use that I am very proud of (Some people are easy)
Property Get Zero() As Variant
Dim Z2(2) As Double
Zero = Z2
End Property
this is public so I never have to write
dim insPt(2) as double
Now all my insertion points are just Zero.
Normals, normals are rather finicky so I guess I just normalise them as habit.
When you use the normal in making a transformation matrix you need to normalise it as well.
But you are right no need to do unnecessary math.
Fatty, thanks mate.