座標を変換する(.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 変換で、XY の各座標の尺度は常に変更されます。したがって、2 種類の座標系の間の尺度係数を検出できます。PSDCS は、モデル空間ビューポートにしか変換できません。

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

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

VB.NET

Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
 
<CommandMethod("TranslateCoordinates")> _
Public Sub TranslateCoordinates()
    '' Get the current document and database, and start a transaction
    Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
    Dim acCurDb As Database = acDoc.Database

    Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
        '' Open the Block table for read
        Dim acBlkTbl As BlockTable
        acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, _
                                     OpenMode.ForRead)

        '' Open the Block table record Model space for write
        Dim acBlkTblRec As BlockTableRecord
        acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), _
                                        OpenMode.ForWrite)

        '' Create a 2D polyline with two segments (3 points)
        Dim acPoly2d As Polyline2d = 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
        Dim acPts2dPoly As Point3dCollection = 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))

        For Each acPt3d As Point3d In acPts2dPoly
            Dim acVer2d As Vertex2d = New Vertex2d(acPt3d, 0, 0, 0, 0)
            acPoly2d.AppendVertex(acVer2d)
            acTrans.AddNewlyCreatedDBObject(acVer2d, True)
        Next

        '' Set the normal of the 2D polyline
        acPoly2d.Normal = New Vector3d(0, 1, 2)

        '' Get the first coordinate of the 2D polyline
        Dim acPts3d As Point3dCollection = New Point3dCollection()
        Dim acFirstVer As Vertex2d = Nothing
        For Each acObjIdVert As ObjectId In acPoly2d
            acFirstVer = acTrans.GetObject(acObjIdVert, _
                                           OpenMode.ForRead)

            acPts3d.Add(acFirstVer.Position)

            Exit For
        Next

        '' Get the first point of the polyline and 
        '' use the eleveation for the Z value
        Dim pFirstVer As Point3d = New Point3d(acFirstVer.Position.X, _
                                               acFirstVer.Position.Y, _
                                               acPoly2d.Elevation)

        '' Translate the OCS to WCS
        Dim mWPlane As Matrix3d = Matrix3d.WorldToPlane(acPoly2d.Normal)
        Dim pWCSPt As Point3d = pFirstVer.TransformBy(mWPlane)

        Application.ShowAlertDialog("The first vertex has the following " & _
                                    "coordinates:" & _
                                    vbLf & "OCS: " + pFirstVer.ToString() & _
                                    vbLf & "WCS: " + pWCSPt.ToString())

        '' Save the new objects to the database
        acTrans.Commit()
    End Using
End Sub

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

VBA/ActiveX コード リファレンス

Sub TranslateCoordinates()
    ' Create a polyline in model space.
    Dim plineObj As AcadPolyline
    Dim points(0 To 14) As Double
 
    ' Define the 2D polyline points
    points(0) = 1: points(1) = 1: points(2) = 0
    points(3) = 1: points(4) = 2: points(5) = 0
    points(6) = 2: points(7) = 2: points(8) = 0
    points(9) = 3: points(10) = 2: points(11) = 0
    points(12) = 4: points(13) = 4: points(14) = 0
 
    ' Create a light weight Polyline object in model space
    Set plineObj = ThisDrawing.ModelSpace.AddPolyline(points)
 
    ' Find the X and Y coordinates of the
    ' first vertex of the polyline
    Dim firstVertex As Variant
    firstVertex = plineObj.Coordinate(0)
 
    ' Find the Z coordinate for the polyline
    ' using the elevation property
    firstVertex(2) = plineObj.Elevation
 
    ' Change the normal for the pline so that the
    ' difference between the coordinate systems
    ' is obvious.
    Dim plineNormal(0 To 2) As Double
    plineNormal(0) = 0#
    plineNormal(1) = 1#
    plineNormal(2) = 2#
    plineObj.Normal = plineNormal
 
    ' Translate the OCS coordinate into WCS
    Dim coordinateWCS As Variant
    coordinateWCS = ThisDrawing.Utility.TranslateCoordinates _
                        (firstVertex, acOCS, acWorld, False, plineNormal)
 
    ' Display the coordinates of the point
    MsgBox "The first vertex has the following coordinates:" _
           & vbCrLf & "OCS: (" & firstVertex(0) & "," & _
           firstVertex(1) & "," & firstVertex(2) & ")" & vbCrLf & _
           "WCS: (" & coordinateWCS(0) & "," & _
           coordinateWCS(1) & "," & coordinateWCS(2) & ")"
End Sub