To move an entity in the current UCS Y direction, you have to transform the y displacement vector with the current coodinate system before using this vector with the TransformBy() method.
Example to move the entity (ent) of 10 units in the UCS Y direction:
Vector3d disp = new Vector3d(0.0, 10.0, 0.0); disp = disp.TransformBy(ed.CurrentUserCoordinateSystem); ent.TransformBy(Matrix3d.Displacement(disp));
Private Shared Sub ChangePostionLevel(MySelSet As SelectionSet, BPoint As Point3d, BValue As String) Dim Tr As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction() If MySelSet IsNot Nothing Then For Each BlKID In MySelSet.GetObjectIds() Dim BlkRef As BlockReference = Tr.GetObject(BlKID, OpenMode.ForWrite) Dim objId As ObjectId = BlkRef.AttributeCollection.Item(0) Dim attRef As AttributeReference = Tr.GetObject(objId, OpenMode.ForWrite) Dim OPoint As Point3d = New Point3d(BlkRef.Position.X, BlkRef.Position.Y, BlkRef.Position.Z) Dim NPoint As Point3d If attRef.TextString > BValue Then 'NPoint = New Point3d(BlkRef.Position.X, (BPoint.Y + (Val(attRef.TextString) - Val(BValue)) ), BlkRef.Position.Z) Dim distance As Double = "" ElseIf attRef.TextString < BValue Then NPoint = New Point3d(BlkRef.Position.X, (BPoint.Y - (Val(BValue) - Val(attRef.TextString))), BlkRef.Position.Z) ElseIf attRef.TextString = BValue Then End If BlkRef.TransformBy(Matrix3d.Displacement(OPoint.GetVectorTo(NPoint))) Next End If Tr.Commit() Tr.Dispose() End Sub
this funciton work correctly with normal ucs (world mode) , but doesn't work with other ucs
see this picture to understand what i want
Private Shared Sub ChangePostionLevel(MySelSet As SelectionSet, BPoint As Point3d, BValue As String, Unit As Double) Dim Tr As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction() If MySelSet IsNot Nothing Then For Each BlKID In MySelSet.GetObjectIds() Dim BlkRef As BlockReference = Tr.GetObject(BlKID, OpenMode.ForWrite) Dim objId As ObjectId = BlkRef.AttributeCollection.Item(0) Dim attRef As AttributeReference = Tr.GetObject(objId, OpenMode.ForWrite) Dim OPoint As Point3d = New Point3d(BlkRef.Position.X, BlkRef.Position.Y, BlkRef.Position.Z) Dim NPoint As Point3d If attRef.TextString > BValue Then NPoint = New Point3d(BlkRef.Position.X, (BPoint.Y + (Val(attRef.TextString) - Val(BValue)) * Unit), BlkRef.Position.Z) ElseIf attRef.TextString < BValue Then NPoint = New Point3d(BlkRef.Position.X, (BPoint.Y - (Val(BValue) - Val(attRef.TextString)) * Unit), BlkRef.Position.Z) ElseIf attRef.TextString = BValue Then End If BlkRef.TransformBy(Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem) BlkRef.TransformBy(Matrix3d.Displacement(OPoint.GetVectorTo(NPoint))) Next End If Tr.Commit() Tr.Dispose() End Sub
like this ?????
it doens't work
No, it is not "very hard", it's only some math logic.
You build a displacement vector from 2 points:
- the block reference insertion point (OPoint), BlockReference.Position returns a Point3d defined in WCS coordinates
- a point (NPoint) built from another one passed as argument to your function (BPoint)
The issue is: how is defined BPoint, WCS or UCS coordinates ?
If BPoint is defined in WCS coordinates, the displacement vector OPoint.GetVectorTo(Npoint) is defined too in WCS so you have to transform it:
Dim disp As Vector3d = OPoint.GetVectorTo(Npoint).TransformBy(ed.currentCoordinateSystem)
Esle if BPoint is defined in current UCS (as returned by Editor.GetPoint()), you have to transform OPoint from WCS to UCS before building the displacement vector. In this case, the displacement vector will be defined in UCS coordinates:
Dim disp As Vector3d = OPoint.TransformBy(ed.currentCoordinateSystem.Inverse()).GetVectorTo(Npoint)
Then use this vector to Transform BlkRef...
Private Shared Sub ChangePostionLevel(MySelSet As SelectionSet, BPoint As Point3d, BValue As String, Unit As Double) Dim Tr As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction() If MySelSet IsNot Nothing Then For Each BlKID In MySelSet.GetObjectIds() Dim BlkRef As BlockReference = Tr.GetObject(BlKID, OpenMode.ForWrite) Dim objId As ObjectId = BlkRef.AttributeCollection.Item(0) Dim attRef As AttributeReference = Tr.GetObject(objId, OpenMode.ForWrite) Dim OPoint As Point3d = New Point3d(BlkRef.Position.X, BlkRef.Position.Y, BlkRef.Position.Z) Dim NPoint As Point3d If attRef.TextString > BValue Then NPoint = New Point3d(BlkRef.Position.X, (BPoint.Y + (Val(attRef.TextString) - Val(BValue)) * Unit), BlkRef.Position.Z) ElseIf attRef.TextString < BValue Then NPoint = New Point3d(BlkRef.Position.X, (BPoint.Y - (Val(BValue) - Val(attRef.TextString)) * Unit), BlkRef.Position.Z) ElseIf attRef.TextString = BValue Then End If Dim disp As Vector3d = OPoint.TransformBy(Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem.Inverse()).GetVectorTo(NPoint) BlkRef.TransformBy(Matrix3d.Displacement(disp)) Next End If Tr.Commit() Tr.Dispose() End Sub
also doesn't work
i think you will hit me
i think iam failure , i can't understand ,
if you need the completley code to fix it tell me and i will send it for you
iam so sorry
From your last code, it seems to me that what you want to do is move the block reference about the current UCS Y axis with a value which is equal to:
BPoint.Y + (Val(attRef.TextString) - Val(BValue)) * Unit
Try the code below (I remove some unuseful statements)
Private Shared Sub ChangePostionLevel(MySelSet As SelectionSet, BPoint As Point3d, BValue As String, Unit As Double) Using Tr As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction() If MySelSet IsNot Nothing Then For Each BlKID In MySelSet.GetObjectIds() Dim BlkRef As BlockReference = Tr.GetObject(BlKID, OpenMode.ForWrite) Dim objId As ObjectId = BlkRef.AttributeCollection.Item(0) Dim attRef As AttributeReference = Tr.GetObject(objId, OpenMode.ForRead) Dim yVal As Double = BPoint.Y + (Val(attRef.TextString) - Val(BValue)) * Unit Dim disp As Vector3d = New Vector3d(0.0, yVal, 0.0) disp = disp.TransformBy(Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem) BlkRef.TransformBy(Matrix3d.Displacement(disp)) Next End If Tr.Commit() End Using End Sub
know i know where is the problem
this is my correct code mr _gile
Private Shared Sub ChangePostionLevel(MySelSet As SelectionSet, BPoint As Point3d, BValue As String, Unit As Double) Dim Tr As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction() If MySelSet IsNot Nothing Then For Each BlKID In MySelSet.GetObjectIds() Dim BlkRef As BlockReference = Tr.GetObject(BlKID, OpenMode.ForWrite) Dim objId As ObjectId = BlkRef.AttributeCollection.Item(0) Dim attRef As AttributeReference = Tr.GetObject(objId, OpenMode.ForWrite) Dim OPoint As Point3d = New Point3d(BlkRef.Position.X, BlkRef.Position.Y, BlkRef.Position.Z) ' Dim NPoint As Point3d Dim TDistance As Double = Math.Abs(BlkRef.Position.Y - BPoint.Y) Dim FDistance As Double If Val(attRef.TextString) > BValue Then Dim PDistance As Double = (Val(attRef.TextString) - Val(BValue)) * Unit If TDistance > PDistance Then FDistance = -(TDistance - (PDistance)) Else FDistance = TDistance + (PDistance) End If ElseIf Val(attRef.TextString) < BValue Then Dim PDistance As Double = (Val(attRef.TextString) - Val(BValue)) * Unit If TDistance > PDistance Then FDistance = TDistance + (PDistance) Else FDistance = TDistance - (PDistance) End If Else End If Dim disp As Vector3d = New Vector3d(0.0, FDistance, 0.0) disp = disp.TransformBy(Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem) BlkRef.TransformBy(Matrix3d.Displacement(disp)) Next End If Tr.Commit() Tr.Dispose() End Sub
in the red line , the distance between block and base point in WCS , no problem
but when the code can't calcualte the distance in UCS Correctly
so how can i get the distance between two point in any UCS or WCS Correctly
understand me
It's really difficult to help you if the problem data changes with each message...
As I said, the BlockReference.Position is always defined in WCS coordinates, so if the 'BPoint' is not defined in WCS coordinates, you have to transform one of both so that they're defined in the same coordinate system before getting the distance between them.
The rest of your arithmetic could be simplified which would make the code more readable.
It's really difficult to help you if the problem data changes with each message...
iam so sorry , but i work hard with this code
iam sorry
Can't find what you're looking for? Ask the community or share your knowledge.