Hi,
It has been a while since I worked with transformations so I will need some help.
I want to transform coordinates from world coordinates to a local coordinat system aligned with the green line with origo at the start of the line.
When transforming the middle coordinat from global to local the transformed point should read 0, 5.
I thought I could to something like this but it wont work.
DSegment3d segment = new DSegment3d(lineStartPoint, lineEndPoint); DMatrix3d rotMatrix = DMatrix3d.XYRotation(segment.UnitTangent.AngleXY); Dtransform3d transMatrix = DTransform3d.FromMatrixAndFixedPoint(rotMatrix, lineStartPoint); // Now get the local coordinate transMatrix.Multiply(out transformedPoint, middlePoint);
Best regards,
Krister
Hi Krister Surell ,
Feel free to take a look at our Transforms content who's techniques are applicable across our various supported APIs.Also, this MicroStation CONNECT SDK example may also prove helpful:
Elements\ManagedParametricCellPlacementExample\ParametricCellPlace.cs:185:private bool TransformElement(out DTransform3d transform, DgnButtonEvent ev)
Great resources. But...
Been there, done that. Messed up.
Any help appriciated!
/Krister
Owner consultant at Surell Consulting AB
Hi Krister,
Krister Surell said:I thought I could to something like this but it wont work.
Right now I have no time to investigate it more and to write code, but I think you are on the right way.
What you need is simple transformation, consisting from translation (149769,6575253 > 0,0), rotation (source X is equal to local 0,0 > 0,10 vector) and scale. All these steps can be expressed by one transformation matrix.
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
I think those are the steps I've taken.
The origin is set to the start of the line (149769,6575253) and the rotation is taken from the line segment.
I'll continue the trial process...
I used VBA for testing (it's faster) and the following seems to work:
origoPoint.X = 5 origoPoint.Y = 5 mtrxRotation = Matrix3dFromAxisAndRotationAngle(2, Radians(45)) transRot = Transform3dFromMatrix3dAndFixedPoint3d(mtrxRotation, origoPoint) transMove = Transform3dFromXYZ(origoPoint.X, origoPoint.Y, 0) transFinal = Transform3dFromTransform3dTimesTransform3d(transRot, transMove) transFinal = Transform3dInverse(transFinal) point = Point3dFromTransform3dTimesXYZ(transFinal, 8, 8, 0)
I then tried to move that to C#:
DMatrix3d rotMatrix = DMatrix3d.XYRotation(angle); DTransform3d transRot = DTransform3d.FromMatrixAndFixedPoint(rotMatrix, origoPoint); DTransform3d transMove = DTransform3d.FromTranslation(origoPoint); DTransform3d trans = DTransform3d.Multiply(transRot, transMove); trans.TryInvert(out transInvert); // Get local point transformedPoint = transMatrix.MultiplyPoint (worldPoint.X, worldPoint.Z, worldPoint.Z);
This does not work as far as I can see.
I also found this method wich looks like a winner but could not get that to work either:
DTransform3d.TryZProjectionWithInverse( origoPoint, xDir, yDir, out localToWorld, out worldToLocal, out condition); }
I bet there are someone out there that knows how this work.
This should be easy. I must be missing something.
Is there no Bentley people that could give me a pointer?
So, finally I think I have something that works (for me).
I've created a method that works for orthogonal transformation with a rotation.
public static void MakeTransform(DPoint3d origoPoint, DVector3d unitVector, ref DTransform3d _localToWorld, ref DTransform3d _worldToLocal) { try { DVector3d xDir = unitVector; DVector3d yDir = unitVector.Rotate90CCWXY(); double condition; DTransform3d.TryZProjectionWithInverse( origoPoint, xDir, yDir, out _localToWorld, out _worldToLocal, out condition); } catch (System.Exception ex) { DgnHelper.ShowMessage(OutputMessagePriority.Error, "MakeTransform: " + ex.Message); } }
When you want to transform a point from local to world or world to local you use the returned transformation matrixes and the following method.
localPoint = worldToLocal.MultiplyPoint (worldPoint.X, worldPoint.Y, worldPoint.Z);