【テクニカル・上級編】【実務中級】座標変換の極意:UCS(ユーザー座標系)とWCS(世界座標系)をTranslateCoordinatesで相互変換する – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する極限の知見:UCSとWCSの呪縛を断つ『TranslateCoordinates』完全調律

AutoCAD VBAによる自動化の現場において、多くの開発者が途中で直面し、そして静かに敗北していく壁がある。それが「座標系(UCSとWCS)の不一致」に起因する図形の位置ズレである。

平面図であればモデル空間のワールド座標系(WCS)をそのまま叩けば事足りる。しかし、プラント配管のアイソメ図、傾斜した敷地の意図されたユーザー座標系(UCS)、あるいはブロック参照内部のネストされたローカル空間が絡み合った瞬間、コードが吐き出す座標は使い物にならないゴミへと変貌する。

今回は、AutoCADのオブジェクトモデルの深層に潜み、この座標の魔術を完全にコントロールするための唯一にして最強のメソッド、`Utility.TranslateCoordinates`の極限の知見を授ける。レガシーなAutoCAD VBA環境であっても、正確無比な幾何学計算を実現するためのアーキテクチャを解説しよう。

1. なぜ「座標変換」でエンジニアは絶望するのか?

AutoCADのAPI(ActiveX Automation)において、私たちが扱う図形(AcadEntity)の頂点データや挿入起点は、原則として「その図形が属する空間の定義」に依存している。

  • WCS (World Coordinate System): AutoCADが持つ絶対的な基準座標系。
  • UCS (User Coordinate System): ユーザーが任意に原点と軸の傾きを設定した作業用座標系。

VBAから図形を生成・操作する際、`AddLine` や `AddCircle` などのメソッドに渡す座標値は、暗黙的に「現在のActiveなUCS」として解釈されることが多い。しかし、これは危険な思い込みだ。ビューポートやコードの実行タイミング、あるいはブロックのコンテキストによって、AutoCAD内部の解釈は揺らぐ。

特に、傾度を持ったUCS上で「特定のUCS上の点を、WCS上の絶対座標に変換してデータベースに書き込む」「あるいはその逆」という処理を自前の三角関数(sin/cos)で実装しようとすると、マトリックス計算の破綻や浮動小数点の誤差により、必ず実務レベルで破綻する。

ここで登場するのが、AutoCADのGeometoric Engineに直接座標変換を依頼する `AcadUtility.TranslateCoordinates` である。

2. `TranslateCoordinates` の解剖学

このメソッドのシグネチャと仕様を正確に理解しているエンジニアは意外と少ない。まずはその本質を確認する。

RetVal = object.TranslateCoordinates(Point, FromType, ToType, Disp [, DispAxis])

引数の極意

  • Point (Variant): 変換元の3要素(または2要素)の座標配列(Double)。
  • FromType (AcCoordinateSystem): 変換元の座標系。
  • ToType (AcCoordinateSystem): 変換先の座標系。
  • Disp (Boolean):
  • `False`: 変換対象を「位置(Location)」として扱う(原点移動の影響を受ける)。
  • `True`: 変換対象を「変位・ベクトル(Displacement)」として扱う(原点移動の影響を受けない)。実務ではここを取り違えてバグらせる事例が後を絶たない。
  • DispAxis (Variant, オプション): ベクトル変換時の軸方向指定など。通常は省略可能。

座標系定数 (`AcCoordinateSystem`) の選択肢

1. `acWorld` (0): 世界座標系 (WCS)
2. `acUCS` (1): ユーザー座標系 (UCS)
3. `acDisplayDCS` (2): 表示DCS(ディスプレイ座標系)
4. `acPaperSpace` (3): ペーパー空間DCS
5. `acOCS` (4): オブジェクト座標系 (OCS) ※押し出し方向を持つ図形固有の座標系

実務で最も酷使するのは、`acUCS` と `acWorld` の相互変換、そして押し出しを伴う図形を扱う際の `acOCS` の制御である。

3. 【実務実装】UCSとWCSを安全に往復するプロダクションコード

以下のコードは、現在のUCS上でユーザーが選択した点、あるいは指定したローカル座標を、確実にWCSへ変換し、さらにそこから正確なジオメトリを構築するための実践的なモジュールである。

メモリリークやオートメーションエラーを排除するため、オブジェクトのライフサイクル管理も厳格に行う。

Option Explicit

‘ ==============================================================================
‘ 担当領域: AutoCAD VBA 幾何学・座標変換エンジン
‘ 概要: 指定されたUCS上の座標をWCSに安全に変換し、意図した空間に図形を配置する
‘ ==============================================================================
Public Sub ExecutePreciseCoordinateTransformation()
Dim acadApp As AcadApplication
Dim acadDoc As AcadDocument
Dim acadUtil As AcadUtility

On Error GoTo ErrorHandler

‘ アプリケーションコンテキストの取得(早期バインディングによるパフォーマンス最大化)
Set acadApp = ThisDrawing.Application
Set acadDoc = acadApp.ActiveDocument
Set acadUtil = acadDoc.Utility

‘ 1. ユーザーからUCS上の点を取得(例として画面上で1点指定させる)
Dim ucsPoint As Variant
On Error Resume Next
ucsPoint = acadUtil.GetPoint(, “【座標変換】基準となるUCS上の点を指定してください: “)
If Err.Number <> 0 Then
‘ ユーザーキャンセル時の処理
Exit Sub
End If
On Error GoTo ErrorHandler

‘ 2. 厳密な配列チェック(Variant型安全性の担保)
If Not IsArray(ucsPoint) Then
MsgBox “有効な座標が取得できませんでした。”, vbCritical
Exit Sub
End If

‘ 3. TranslateCoordinatesによる極限の変換処理 (UCS -> WCS)
‘ 引数: 変換元配列, From(=acUCS), To(=acWorld), Disp(=False: 位置として変換)
Dim wcsPoint As Variant
wcsPoint = acadUtil.TranslateCoordinates(ucsPoint, acUCS, acWorld, False)

‘ 4. 変換されたWCS座標を使って、モデル空間に正確に図形を描画する
Dim modelSpace As AcadModelSpace
Set modelSpace = acadDoc.ModelSpace

Dim targetCircle As AcadCircle
‘ WCS上の絶対座標を渡すことで、UCSの傾きに依存せず常に正しい位置に円を生成
Set targetCircle = modelSpace.AddCircle(wcsPoint, 50.0)

‘ プロパティの確実な更新
targetCircle.Update

MsgBox “変換完了:” & vbCrLf & _
“UCS: X=” & ucsPoint(0) & “, Y=” & ucsPoint(1) & vbCrLf & _
“WCS: X=” & wcsPoint(0) & “, Y=” & wcsPoint(1) & “, Z=” & wcsPoint(2), _
vbInformation, “座標変換エンジン”

CleanUp:
‘ オブジェクト参照の明示的解放(VBAにおけるCOMメモリ管理の鉄則)
Set targetCircle = Nothing
Set modelSpace = Nothing
Set acadUtil = Nothing
Set acadDoc = Nothing
Set acadApp = Nothing
Exit Sub

ErrorHandler:
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical, “System Error”
Resume CleanUp
End Sub

4. シニアエンジニアが知るべき「見落としがちな罠」

上記のコードで基本は網羅できるが、さらに高度なエンタープライズ環境やレガシーCADデータとの統合においては、以下の点に留意しなければならない。

① OCS(オブジェクト座標系)の罠

線分(`AcadLine`)や円(`AcadCircle`)の頂点データは、単純なWCSやUCSではなく、OCS(オブジェクト座標系)で保持されている場合がある。特に図形がZ軸方向に傾いている、あるいは「押し出し(Extrusion)」プロパティを持つ場合、`TranslateCoordinates` の第2・第3引数に `acOCS` を指定し、さらに必要に応じて `DispAxis` に図形の押し出しベクトルを渡す必要がある。
これを怠ると、3D空間における微小なズレが蓄積し、大規模なプラント図面や意匠図の干渉チェックで致命的な手戻りが発生する。

② Disp(変位)フラグの厳格な使い分け

座標そのものを変換したいのか、それとも「ある点から別の点へのベクトル(距離と方向)」を変換したいのかで、第4引数 `Disp` の真偽値を厳密に切り替えよ。

  • 位置 (Location / `Disp = False`): UCSの「原点オフセット」の移動量が計算に含まれる。
  • 変位 (Displacement / `Disp = True`): 空間の傾き(回転マトリックス)のみが適用され、原点の位置違いによるオフセットは無視される。これを間違えると、座標移動量が全くデタラメな値になる。

③ COMオブジェクトの解放とメモリリーク対策

AutoCAD VBAにおいて、`ThisDrawing.ModelSpace` や `AcadUtility` などのCOMオブジェクトの参照をローカル変数に保持したままプロシージャを抜けると、AutoCADのプロセス内に参照カウントが残り続け、図面を閉じた際にメモリリークや不意のクラッシュを引き起こす。
上記のサンプルコードの `CleanUp` ラベルのように、すべてのオブジェクト変数に対して `Set xxx = Nothing` を明示的に実行することは、プロフェッショナルなVBAエンジニアにとっての絶対の義務である。

5. 総括

座標変換は、AutoCADカスタマイズの成否を分ける羅針盤である。

泥臭い三角関数による自前計算という幻想を捨て、AutoCADが内部に持つ幾何学エンジン(`TranslateCoordinates`)の正確なインターフェースをVBAから叩くこと。そして、座標系(WCS / UCS / OCS)のコンテキストを常に意識すること。

この極限の知見をあなたのコードに実装した瞬間から、どんなにねじ曲がった複雑なユーザー座標系を持つ図面であっても、自動化スクリプトは寸分の狂いもなく正確な図形を描き出すようになる。レガシーと言われようとも、基盤のメカニズムを完璧に掌握したコードは、世代を超えて最高峰のパフォーマンスを発揮し続けるのだ。

タイトルとURLをコピーしました