Преобразования координат
Метод TransformBy также может выполнять преобразования координат из одной ПСК в другую, для этого у структуры матрицы трансформации Matrix3d имеется метод AlignCoordinateSystem, требующий указания нескольких аргументов:
- Координаты точки начала исходной системы координат;
- Три вектора в пространстве, задающие оси ПСК по компонентам X, Y, Z исходной системы координат;
- Координаты точки начала целевой системы координат;
- Три вектора в пространстве, задающие оси ПСК по компонентам X, Y, Z целевой системы координат;
В случае плоской матрицы (Matrix2d), векторов будет по два, а точка начала будет представлена плоской точкой, а не трехмерной. Необходимо также ввести некоторые термины по системам координат:
- WCS (World coordinate system, МСК) : Мировая система координат. Все остальные системы координат определяются относительно WCS, она которая никогда не изменяется. Значения, измеренные относительно WCS, остаются постоянными при изменении других систем координат. Все точки, передаваемые в методы и свойства .NET API, выражаются в WCS, если не указано иное;
- UCS (User coordinate system , ПСК) : Пользовательская система координат (UCS). UCS используются для упрощения задач разработки чертежей. Все точки, передаваемые командам AutoCAD, включая точки, возвращаемые различными функциями, являются точками в текущей ПСК (если пользователь не поставил перед ними * в командной строке). Если вы хотите, чтобы ваше приложение отправляло координаты в WCS, OCS или DCS командам AutoCAD, вы должны сначала преобразовать их в UCS (ПСК), вызвав метод преобразования, а затем преобразовать объект Point3d или Point2d с помощью метода TransformBy, представляющего значение компонентов координат;
- OCS (Object coordinate system) :также известная, как система координат элемента или ECS: значения точек, заданные определенными методами и свойствами для объектов Polyline2d и Polyline, выражаются в этой системе координат относительно объекта. Эти точки обычно преобразуются в WCS, текущую UCS или текущую DCS в зависимости от предполагаемого использования объекта. И наоборот, точки в WCS, UCS или DCS должны быть преобразованы в OCS перед записью в базу данных с помощью тех же свойств. При преобразовании координат в OCS или из OCS необходимо учитывать нормаль OCS;
- DCS (Display coordinate system): система координат, в которую объекты преобразуются при отрисовке на экране. Начало DCS находится в точке, хранимой в системной переменной TARGET, а направление оси Z соответствует направлению данного видового экрана (ВЭ). Другими словами, ВЭ всегда является плоским видом для данной DCS.
Для получения матрицы преобразования между мировыми координатами и DCS можно использовать следующий код:
Document acDoc;
Database acCurDb;
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Get the current view
using (ViewTableRecord acView = acDoc.Editor.GetCurrentView())
{
Extents3d eExtents;
// Translate WCS coordinates to DCS
Matrix3d matWCS2DCS;
matWCS2DCS = Matrix3d.PlaneToWorld(acView.ViewDirection);
matWCS2DCS = Matrix3d.Displacement(acView.Target : Point3d.Origin) * matWCS2DCS;
matWCS2DCS = Matrix3d.Rotation(:acView.ViewTwist,
acView.ViewDirection,
acView.Target) * matWCS2DCS;
}
}
- PSDCS (Paper space DCS) : Система координат листа. По сути, это двумерное преобразование, где координаты X и Y отмасштабированы относительно целевой СК (здесь, DCS). Поэтому ее можно использовать для определения коэффициента масштабирования между двумя системами координат. Координаты в данной СК могут быть преобразованы только в DCS модели и аналогично обратно;
Преобразование из OCS в WCS
В примере ниже создается полилиния в пространстве модели. Выводится информация, какие координаты у первой вершины полилинии в системе координат полилинии и в мировой системе координат
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
[CommandMethod("TranslateCoordinates")]
public static void TranslateCoordinates()
{
// Get the current document and database, and start a transaction
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
// Open the Block table record for read
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
OpenMode.ForRead) as BlockTable;
// Open the Block table record Model space for write
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
OpenMode.ForWrite) as BlockTableRecord;
// Create a 2D polyline with two segments (3 points)
using (Polyline2d acPoly2d = new Polyline2d())
{
// Add the new object to the block table record and the transaction
acBlkTblRec.AppendEntity(acPoly2d);
acTrans.AddNewlyCreatedDBObject(acPoly2d, true);
// Before adding vertexes, the polyline must be in the drawing
Point3dCollection acPts2dPoly = new Point3dCollection();
acPts2dPoly.Add(new Point3d(1, 1, 0));
acPts2dPoly.Add(new Point3d(1, 2, 0));
acPts2dPoly.Add(new Point3d(2, 2, 0));
acPts2dPoly.Add(new Point3d(3, 2, 0));
acPts2dPoly.Add(new Point3d(4, 4, 0));
foreach (Point3d acPt3d in acPts2dPoly)
{
Vertex2d acVer2d = new Vertex2d(acPt3d, 0, 0, 0, 0);
acPoly2d.AppendVertex(acVer2d);
acTrans.AddNewlyCreatedDBObject(acVer2d, true);
}
// Set the normal of the 2D polyline
acPoly2d.Normal = new Vector3d(0, 1, 2);
// Get the first coordinate of the 2D polyline
Point3dCollection acPts3d = new Point3dCollection();
Vertex2d acFirstVer = null;
foreach (ObjectId acObjIdVert in acPoly2d)
{
acFirstVer = acTrans.GetObject(acObjIdVert,
OpenMode.ForRead) as Vertex2d;
acPts3d.Add(acFirstVer.Position);
break;
}
// Get the first point of the polyline and
// use the eleveation for the Z value
Point3d pFirstVer = new Point3d(acFirstVer.Position.X,
acFirstVer.Position.Y,
acPoly2d.Elevation);
// Translate the OCS to WCS
Matrix3d mWPlane = Matrix3d.WorldToPlane(acPoly2d.Normal);
Point3d pWCSPt = pFirstVer.TransformBy(mWPlane);
Application.ShowAlertDialog("The first vertex has the following " +
"coordinates:" +
"\nOCS: " + pFirstVer.ToString() +
"\nWCS: " + pWCSPt.ToString());
}
// Save the new objects to the database
acTrans.Commit();
}
}