07/18/2013

Aligning entity using 3 points

Here is a sample code to align a selected entity based on three source and their corresponding destination points. The order in which the point are selected is shown in the screenshot and a sample drawing to try the the code snippet.

Document activeDoc = Application.DocumentManager.MdiActiveDocument;

Database db = activeDoc.Database;

Editor ed = activeDoc.Editor;

// Prompt for entity selection

PromptEntityResult per

= ed.GetEntity(new PromptEntityOptions("Select an entity : "));

if (per.Status != PromptStatus.OK)

return;

ObjectId oid = per.ObjectId;

Matrix3d ucs2wcs = ed.CurrentUserCoordinateSystem;

// 3 source points

Point3d srcpt1 = Point3d.Origin;

Point3d srcpt2 = Point3d.Origin;

Point3d srcpt3 = Point3d.Origin;

// 3 destination points

Point3d destpt1 = Point3d.Origin;

Point3d destpt2 = Point3d.Origin;

Point3d destpt3 = Point3d.Origin;

// Source point 1

PromptPointResult ppr1

= ed.GetPoint(new PromptPointOptions("Select src point 1"));

if (ppr1.Status != PromptStatus.OK)

return;

srcpt1 = ppr1.Value.TransformBy(ucs2wcs);

// Destination point 1

ppr1 = ed.GetPoint(new PromptPointOptions("Select dest point 1"));

if (ppr1.Status != PromptStatus.OK)

return;

destpt1 = ppr1.Value.TransformBy(ucs2wcs);

// Display transient line to show the selection of points

IntegerCollection coll = new IntegerCollection();

Line tmpline1 = new Line(srcpt1, destpt1);

TransientManager.CurrentTransientManager.AddTransient

(tmpline1, TransientDrawingMode.DirectShortTerm, 128, coll);

// Source point 2

PromptPointResult ppr2

= ed.GetPoint(new PromptPointOptions("Select src point 2"));

if (ppr2.Status != PromptStatus.OK)

return;

srcpt2 = ppr2.Value.TransformBy(ucs2wcs);

// Destination point 2

ppr2 = ed.GetPoint(new PromptPointOptions("Select dest point 2"));

if (ppr2.Status != PromptStatus.OK)

return;

destpt2 = ppr2.Value.TransformBy(ucs2wcs);

// Display transient line to show the selection of points

Line tmpline2 = new Line(srcpt2, destpt2);

TransientManager.CurrentTransientManager.AddTransient

(tmpline2, TransientDrawingMode.DirectShortTerm, 128, coll);

// Source point 3

PromptPointResult ppr3

= ed.GetPoint(new PromptPointOptions("Select src point 3"));

if (ppr3.Status != PromptStatus.OK)

return;

srcpt3 = ppr3.Value.TransformBy(ucs2wcs);

// Destination point 3

ppr3 = ed.GetPoint(new PromptPointOptions("Select dest point 3"));

if (ppr3.Status != PromptStatus.OK)

return;

destpt3 = ppr3.Value.TransformBy(ucs2wcs);

// Display transient line to show the selection of points

Line tmpline3 = new Line(srcpt3, destpt3);

TransientManager.CurrentTransientManager.AddTransient

(tmpline3, TransientDrawingMode.DirectShortTerm, 128, coll);

try

{

Point3d fromOrigin = srcpt1;

Vector3d fromXaxis = srcpt2 - srcpt1;

Vector3d fromYaxis = srcpt3 - srcpt1;

Vector3d fromZaxis = fromXaxis.CrossProduct(fromYaxis);

Point3d toOrigin = destpt1;

Vector3d toXaxis =

(destpt2 - destpt1).GetNormal() * fromXaxis.Length;

Vector3d toYaxis

= (destpt3 - destpt1).GetNormal() * fromYaxis.Length;

Vector3d toZaxis = toXaxis.CrossProduct(toYaxis);

// Get the transformation matrix for aligning coordinate systems

Matrix3d mat = new Matrix3d();

mat = Matrix3d.AlignCoordinateSystem(

fromOrigin,

fromXaxis,

fromYaxis,

fromZaxis,

toOrigin,

toXaxis,

toYaxis,

toZaxis

);

// Transform the selected entity

using (Transaction tr = db.TransactionManager.StartTransaction())

{

Entity ent = tr.GetObject(oid, OpenMode.ForWrite) as Entity;

ent.TransformBy(mat);

tr.Commit();

}

}

catch (Autodesk.AutoCAD.Runtime.Exception ex )

{

ed.WriteMessage(ex.Message);

}

// Remove the transient lines

TransientManager.CurrentTransientManager.EraseTransient

(tmpline1, coll);

tmpline1.Dispose();

TransientManager.CurrentTransientManager.EraseTransient

(tmpline2, coll);

tmpline2.Dispose();

TransientManager.CurrentTransientManager.EraseTransient

(tmpline3, coll);

tmpline3.Dispose();

The screenshots show the order of selected points and the aligned entity

Comments

Here is a sample code to align a selected entity based on three source and their corresponding destination points. The order in which the point are selected is shown in the screenshot and a sample drawing to try the the code snippet.

Document activeDoc = Application.DocumentManager.MdiActiveDocument;

Database db = activeDoc.Database;

Editor ed = activeDoc.Editor;

// Prompt for entity selection

PromptEntityResult per

= ed.GetEntity(new PromptEntityOptions("Select an entity : "));

if (per.Status != PromptStatus.OK)

return;

ObjectId oid = per.ObjectId;

Matrix3d ucs2wcs = ed.CurrentUserCoordinateSystem;

// 3 source points

Point3d srcpt1 = Point3d.Origin;

Point3d srcpt2 = Point3d.Origin;

Point3d srcpt3 = Point3d.Origin;

// 3 destination points

Point3d destpt1 = Point3d.Origin;

Point3d destpt2 = Point3d.Origin;

Point3d destpt3 = Point3d.Origin;

// Source point 1

PromptPointResult ppr1

= ed.GetPoint(new PromptPointOptions("Select src point 1"));

if (ppr1.Status != PromptStatus.OK)

return;

srcpt1 = ppr1.Value.TransformBy(ucs2wcs);

// Destination point 1

ppr1 = ed.GetPoint(new PromptPointOptions("Select dest point 1"));

if (ppr1.Status != PromptStatus.OK)

return;

destpt1 = ppr1.Value.TransformBy(ucs2wcs);

// Display transient line to show the selection of points

IntegerCollection coll = new IntegerCollection();

Line tmpline1 = new Line(srcpt1, destpt1);

TransientManager.CurrentTransientManager.AddTransient

(tmpline1, TransientDrawingMode.DirectShortTerm, 128, coll);

// Source point 2

PromptPointResult ppr2

= ed.GetPoint(new PromptPointOptions("Select src point 2"));

if (ppr2.Status != PromptStatus.OK)

return;

srcpt2 = ppr2.Value.TransformBy(ucs2wcs);

// Destination point 2

ppr2 = ed.GetPoint(new PromptPointOptions("Select dest point 2"));

if (ppr2.Status != PromptStatus.OK)

return;

destpt2 = ppr2.Value.TransformBy(ucs2wcs);

// Display transient line to show the selection of points

Line tmpline2 = new Line(srcpt2, destpt2);

TransientManager.CurrentTransientManager.AddTransient

(tmpline2, TransientDrawingMode.DirectShortTerm, 128, coll);

// Source point 3

PromptPointResult ppr3

= ed.GetPoint(new PromptPointOptions("Select src point 3"));

if (ppr3.Status != PromptStatus.OK)

return;

srcpt3 = ppr3.Value.TransformBy(ucs2wcs);

// Destination point 3

ppr3 = ed.GetPoint(new PromptPointOptions("Select dest point 3"));

if (ppr3.Status != PromptStatus.OK)

return;

destpt3 = ppr3.Value.TransformBy(ucs2wcs);

// Display transient line to show the selection of points

Line tmpline3 = new Line(srcpt3, destpt3);

TransientManager.CurrentTransientManager.AddTransient

(tmpline3, TransientDrawingMode.DirectShortTerm, 128, coll);

try

{

Point3d fromOrigin = srcpt1;

Vector3d fromXaxis = srcpt2 - srcpt1;

Vector3d fromYaxis = srcpt3 - srcpt1;

Vector3d fromZaxis = fromXaxis.CrossProduct(fromYaxis);

Point3d toOrigin = destpt1;

Vector3d toXaxis =

(destpt2 - destpt1).GetNormal() * fromXaxis.Length;

Vector3d toYaxis

= (destpt3 - destpt1).GetNormal() * fromYaxis.Length;

Vector3d toZaxis = toXaxis.CrossProduct(toYaxis);

// Get the transformation matrix for aligning coordinate systems

Matrix3d mat = new Matrix3d();

mat = Matrix3d.AlignCoordinateSystem(

fromOrigin,

fromXaxis,

fromYaxis,

fromZaxis,

toOrigin,

toXaxis,

toYaxis,

toZaxis

);

// Transform the selected entity

using (Transaction tr = db.TransactionManager.StartTransaction())

{

Entity ent = tr.GetObject(oid, OpenMode.ForWrite) as Entity;

ent.TransformBy(mat);

tr.Commit();

}

}

catch (Autodesk.AutoCAD.Runtime.Exception ex )

{

ed.WriteMessage(ex.Message);

}

// Remove the transient lines

TransientManager.CurrentTransientManager.EraseTransient

(tmpline1, coll);

tmpline1.Dispose();

TransientManager.CurrentTransientManager.EraseTransient

(tmpline2, coll);

tmpline2.Dispose();

TransientManager.CurrentTransientManager.EraseTransient

(tmpline3, coll);

tmpline3.Dispose();

The screenshots show the order of selected points and the aligned entity