Hi everybody,
I 'm looking for a function to find a point from a start point giving a distance and an angle like the polar command in Autolisp for AutoCAD?
Thank you!
André
Solved! Go to Solution.
Solved by RPTHOMAS108. Go to Solution.
There are many ways of doing this
You can do it via Transform.CreateRotationAtPoint and then use Tranform.OfPoint
i.e.
TransformR = Tranform.CreateRotationAtPoint(XYZ.BasisZ, Angle, Pt_A)
PtB = TranformR.OfPoint(Pt_A + (XYZ.BasisX * Distance))
You could use Transform.CreateRotation with Tranform.OfVector:
i.e.
TransformR = Tranform.CreateRotation(XYZ.BasisZ, Angle)
Vec = TranformR.OfVector(XYZ.BasisX)
PtB = PtA + (Vec * Distance)
You can also work out X,Y location via trigonometry but then you have to adjust for quadrant of angle and would also have to consider 0 (horizontal) & 90 (vertical) special cases separately.
Thank you for your answer, unfortunately it's not working.
Both solutions are not working on all orientations (see the image, I'm trying to draw walls along the green lines with a length of 10' using endpoints in both direction. The bottom walls are correct but not the upper ones).
Here's my code:
//Get points and set distance
XYZ startPoint = uidoc.Selection.PickPoint("Start point:");
XYZ direction = uidoc.Selection.PickPoint("Pick another point for the direction:");
double distance= 10;
//Get angle between points
XYZ vector_from_pt1_to_pt2 = direction - startPoint;
double angle = vector_from_pt1_to_pt2.AngleTo(XYZ.BasisX);
//Transform
Transform transformR = Transform.CreateRotation(XYZ.BasisZ, angle);
XYZ vec = transformR.OfVector(XYZ.BasisX);
XYZ endPoint = startPoint + (vec * distance);
//Creating walls
Line geomLine = Line.CreateBound(startPoint, endPoint);
Wall aWall = Wall.Create(doc, geomLine, doc.ActiveView.GenLevel.Id, false);
Thank you,
André
Now it's working,
The problem was the angle, AngleTo always return shortest angle so when Y of the direction point is lower then the start point I have to recalculate the angle,
Here's my revised code:
//Get points and set distance
XYZ startPoint = uidoc.Selection.PickPoint("Start point:");
XYZ direction = uidoc.Selection.PickPoint("Pick another point for the direction:");
double distance= 10;
//Get angle between points
XYZ vector_from_pt1_to_pt2 = direction - startPoint;
double angle = vector_from_pt1_to_pt2.AngleTo(XYZ.BasisX);
if (direction.Y < startPoint.Y) angle = 2 * Math.PI - angle;
//Transform
Transform transformR = Transform.CreateRotation(XYZ.BasisZ, angle);
XYZ vec = transformR.OfVector(XYZ.BasisX);
XYZ endPoint = startPoint + (vec * distance);
//Creating walls
Line geomLine = Line.CreateBound(startPoint, endPoint);
Wall aWall = Wall.Create(doc, geomLine, doc.ActiveView.GenLevel.Id, false);
Thank you,
André
To be honest you don't need to involve angles at all for this task. They just add a complication you don't need.
If you are picking two points then you have the direction vector and the first point is the origin. If you normalise the direction vector you can multiple it by the length you want along that vector from the origin.
Similarly if you are picking lines to draw wall along then you have:
Nearest endpoint of line picked, furthest line end from pick to form direction, then just normalise vector and multiple by length you want from end nearest pick.
Below forms 10ft line in direction from Pt0 to Pt1 (three lines of code for what you need):
Dim V As XYZ = (Pts(1) - Pts(0)).Normalize
Dim Length As Double = 10
Dim L As Line = Line.CreateBound(Pts(0), Pts(0) + V * Length)
When using PickPoint it will pick the points on the current work plane for the view. If no such plane is set then an exception will be thrown (InvalidOperationException). Sections and elevations will generally not have a plane set.
Full example
Public Function Obj_220624a(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result
Dim IntUIApp As UIApplication = commandData.Application
Dim IntUIDoc As UIDocument = commandData.Application.ActiveUIDocument
Dim IntDoc As Document = IntUIDoc.Document
Dim IntAcView As View = IntUIDoc.ActiveGraphicalView
'Set sketch plane (required for picking points if no plane set).
Dim SKP As SketchPlane = Nothing
Using tx As New Transaction(IntDoc, "Sketch plane")
If tx.Start = TransactionStatus.Started Then
SKP = SketchPlane.Create(IntDoc,
Plane.CreateByNormalAndOrigin(IntAcView.ViewDirection, IntAcView.Origin))
IntAcView.SketchPlane = SKP
tx.Commit()
End If
End Using
Dim Pts As XYZ() = New XYZ(1) {}
Try
For i = 0 To 1
Pts(i) = IntUIDoc.Selection.PickPoint()
Next
Catch ex As Exception
Return Result.Cancelled
End Try
Dim V As XYZ = (Pts(1) - Pts(0)).Normalize
Dim Length As Double = 10
Dim L As Line = Line.CreateBound(Pts(0), Pts(0) + V * Length)
Using tx As New Transaction(IntDoc, "Line")
If tx.Start = TransactionStatus.Started Then
IntDoc.Create.NewModelCurve(L, SKP)
tx.Commit()
End If
End Using
Return Result.Succeeded
End Function
Can't find what you're looking for? Ask the community or share your knowledge.