座標を変換する(.NET)

TransformBy メソッドは、点または変位を別の座標系に変換します。AlignCoordinateSystem メソッドを使用して、変換元の座標系と変換先の座標系を指定します。AlignCoordinateSystem メソッドには、以下を指定する必要があります。

WCS

ワールド座標系。これは、基準座標系です。その他のすべての座標系は、決して変わることのない WCS を基準にして定義されます。WCS を基準にして計測した値は、他の座標系が変更されても一定です。.NET API のメソッドやプロパティで受け渡しされる点はすべて、特に指定のない限り WCS で表現されます。

UCS

ユーザ座標系。これは、作業座標系です。ユーザは図面の作成作業を簡単にするために UCS を指定します。AutoLISP のルーチンや外部関数から返される点など、AutoCAD のコマンドに渡されるすべての点は、現在の UCS における点です(ただし、ユーザがコマンド プロンプトでその前に * を付けた場合は除きます)。アプリケーションが AutoCAD のコマンドに WCS、OCS、または DCS の座標を送る場合は、まず座標を UCS に変換した後、TransformBy メソッドを使用して座標値を表す Point3d または Point2d オブジェクトを変換する必要があります。

OCS

オブジェクト座標系(図形座標系または ECS とも呼ばれる)。Polyline2d および Polyline オブジェクトの特定のメソッドおよびプロパティで指定された点の値は、オブジェクトを基準とした、この座標系で表されます。通常、これらの点はオブジェクトの用途に応じて WCS、現在の UCS、または現在の DCS に変換されます。逆に、WCS、UCS、または DCS の点は、同じプロパティを使ってデータベースに書き込む前に OCS に変換しておかなければなりません。

OCS との座標変換を行う場合は、OCS の法線を考慮する必要があります。

DCS

ディスプレイ座標系。表示前にオブジェクトを変換する座標系です。DCS の原点は AutoCAD のシステム変数 TARGET に格納されている点で、その Z 軸は視線方向です。言い換えれば、ビューポートは常にその DCS のプラン ビューということです。これらの座標を使用すると、ユーザに対する表示位置を決めることができます。

PSDCS

ペーパー空間 DCS。この座標系は、モデル空間のビューポートの DCS との間だけで変換されます。これは基本的に 2D 変換で、X と Y の各座標の尺度は常に変更されます。したがって、2 種類の座標系の間の尺度係数を検出できます。PSDCS は、モデル空間ビューポートにしか変換できません。

OCS 座標から WCS 座標へ変換する

次の例では、ポリラインをモデル空間に作成します。ポリラインの最初の頂点を OCS と WCS の両方の座標で表示します。

C# の例

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();
    }
}