development of

Tieghaに関する備忘録とおまけ

【IJCAD】ポリラインの図心座標を取得する

AutoCADでの図心の取得方法

領域を持つポリラインの図心座標を取得する方法として、広く認知されているのはポリラインからリージョンを作成して、Region.AreaPropertiesメソッドを使用してRegionAreaPropertiesオブジェクトを取得して、リージョンの中心を取得する方法があります。

ただ、残念ながら IJCAD の Region クラスには、AreaProperties メソッドが実装されていません。(ObjectGRX には OdDbRegion::getAreaProp メソッドがあります)
そのため、IJCAD では自力でポリラインの各頂点から重心を計算する必要がありますが、ポリラインなら別の方法でも図心座標を取得できたりします。

IJCADではオブジェクトスナップを活用しよう

Entity クラスには GetObjectSnapPoints というメソッドが存在します。
このメソッドを使用することで、指定したオブジェクトスナップモードと入力座標点で、エンティティにスナップされたときのスナップ点の座標を取得できます。
つまり、ポリラインに対して図心のオブジェクトスナップが有効な時の座標を取得できるということです。

サンプルコード

var db = Application.DocumentManager.MdiActiveDocument.Database;
var ed = Application.DocumentManager.MdiActiveDocument.Editor;

var opt = new PromptEntityOptions("\nポリラインを選択");
opt.SetRejectMessage("\n選択したエンティティはポリラインではありません。");
opt.AddAllowedClass(typeof(Polyline), true);
opt.AddAllowedClass(typeof(Polyline2d), true);
opt.AddAllowedClass(typeof(Polyline3d), true);
var res = ed.GetEntity(opt);
if (res.Status != PromptStatus.OK) return;

using (var tr = db.TransactionManager.StartTransaction())
{
    using (var pline = tr.GetObject(res.ObjectId, OpenMode.ForRead) as Entity)
    {
        var snapPts = new Point3dCollection();
        var geoIds = new IntegerCollection();
        pline.GetObjectSnapPoints((ObjectSnapModes)11, 0, res.PickedPoint, Point3d.Origin, Matrix3d.Identity, snapPts, geoIds);

        ed.WriteMessage($"\nポリライン[{pline.Handle}]の図心は、{snapPts[0]}です。");
    }
}

※サンプルコードについての補足

snapMode には、ObjectSnapModes 列挙体の列挙子を指定します。
例えば、 ObjectSnapModes.ModeCenter の場合は円や円弧の中心、ObjectSnapModes.ModeEnd の場合はエンティティの端点を探します。

ObjectSnapModes 列挙体の詳細は次の表の通りです。

メンバー 対象
ModeEnd 終点
ModeMid 中点
ModeCenter 中心
ModeNode ノード
ModeQuad 四半円点
ModeIntersection 交差点
ModeIns 挿入点
ModePerpendicular 垂線
ModeTangent 接線
ModeNear 近接点
ModeApparentIntersection 仮想交点
ModeParallel 平行
ModeStartpoint 開始点

ここで気になると思われるのが、サンプルコードでは上記の表に存在しない値を使用しています。これは、AcDb::OsnapMode::kOsModeCentroid に該当する値が、 .NET APIObjectSnapModes 列挙体に実装されていないのでこのように引数として渡しています。
ですが、この指定方法でも特に問題なく、ポリラインの図心にスナップされたときの、スナップ点の座標を取得できます。