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

スポンサーリンク

こんにちは!AutoCAD VBAの世界へようこそ。
マクロの記録ボタンを押すだけのステージから抜け出し、「自分の手でCADを自在に操りたい」と願うあなたなら、きっと今日のテーマにワクワクするはずです。

実務で複雑な図面を扱うとき、こんな壁にぶつかったことはありませんか?
「傾いた部屋(ローカルな空間)の中に、図面全体の基準(グローバルな空間)で計算した座標を使って図形を配置したら、とんでもない明後日の方向に線が描かれてしまった……」

そう、AutoCADにはWCS(世界座標系)UCS(ユーザー座標系)という、2つの異なる「世界のモノサシ」が存在します。ここを制することが、AutoCAD VBAを実務レベルで使いこなすための最初の、そして最大の関門です。

今日は、伝説のチーフアーキテクトである私から、座標変換の極意を優しく、そして深く伝授しましょう。ここをクリアすれば、あなたのVBAスキルは間違いなく一皮むけますよ!

1. 座標の二大巨頭:WCSとUCSの正体を暴く

まずは、私たちが普段使っている「空間のルール」を整理しておきましょう。

  • WCS(World Coordinate System:世界座標系)
  • AutoCADがデフォルトで持っている、絶対に揺るぎない「宇宙の基準軸」です。
  • 図面の原点 $(0,0,0)$ は常にここを指しています。VBAが内部でゴリゴリ計算している生データは、基本的にすべてこのWCSに基づいています。
  • UCS(User Coordinate System:ユーザー座標系)
  • 製図者が作図しやすいように「一時的に原点や傾きを変えたローカルなモノサシ」です。
  • 例えば、斜めを向いた建物の平面図を描くとき、その建物の壁面を基準に座標系を回転させたりしますよね。画面上の「右」が、WCSにとっては斜め右上だったりするわけです。

なぜVBAで問題になるのか?

VBAからAutoCADの図形(`Line` や `Circle` など)に座標を渡すとき、AutoCADは「お前が渡したその数値、WCSのつもりで処理するからな!」と解釈します。
もしあなたが「いま画面で見えているUCSのつもり」で `(100, 100)` と渡してしまうと、UCSが傾いていた場合、とんでもない位置に図形が飛んでいってしまうのです。

ここで登場するのが、今回の主役である `TranslateCoordinates` メソッド です。

2. 救世主 `TranslateCoordinates` メソッドの基本

このメソッドは、ActiveDocumentの `Utility` オブジェクトにひっそりと佇む、極めて強力な座標変換エンジンです。

retCoord = ThisDrawing.Utility.TranslateCoordinates(Point, FromType, ToType, [Disp])

引数の意味を、エンジニアらしく正確に押さえておきましょう。

1. `Point`:変換したい座標(3要素の配列 `Variant`)。
2. `FromType`:変換「元」の座標系を指定する定数。
3. `ToType`:変換「先」の座標系を指定する定数。
4. `[Disp]`(省略可能):これが超重要。座標(点)を変換するのか、ベクトル(距離や方向)を変換するのかを `True/False` で切り替えます。

座標系の指定に使う定数(AcCoordinateSystem)

  • `acWorld` : WCS(世界座標系)
  • `acUCS` : UCS(ユーザー座標系)
  • `acDisplayDCS` : 画面表示座標系(DCS)

実務で圧倒的に使うのは、「UCSで入力された値を、AutoCADが理解できるWCSに変換して図形を描く」というパターン、またはその逆です。

3. 【実践】UCSからWCSへ!安全に図形を配置するコード例

百聞は一見に如かず。実務でそのまま使える、極めて堅牢なプロシージャを書き下ろしました。

このコードは、「ユーザーが現在設定しているUCS上の座標 `(10, 10, 0)` を指定して、そこに正確に円を描く」というものです。もしUCSが回転していても、意図した通りの場所に円が作成されます。

Sub DrawCircleInCurrentUCS()
Dim acadApp As AcadApplication
Dim currDoc As AcadDocument
Dim util As AcadUtility

‘ アプリケーションとドキュメントの参照を取得
Set currDoc = ThisDrawing
Set util = currDoc.Utility

On Error GoTo ErrorHandler

‘ 1. UCS上で指定したい座標を定義 (例: X=10, Y=10, Z=0)
Dim ucsPoint(0 To 2) As Double
ucsPoint(0) = 10#
ucsPoint(1) = 10#
ucsPoint(2) = 0#

‘ 2. 魔法のメソッド:UCSからWCSへ座標を変換する!
‘ 第4引数 (Disp) は「座標(点)」を扱うので False (または省略)
Dim wcsPoint As Variant
wcsPoint = util.TranslateCoordinates(ucsPoint, acUCS, acWorld, False)

‘ 3. 変換されたWCS座標を使って、安全に円を作成
‘ AutoCADは内部でWCSを要求するため、これで完全に位置が一致します
Dim centerPoint(0 To 2) As Double
centerPoint(0) = wcsPoint(0)
centerPoint(1) = wcsPoint(1)
centerPoint(2) = wcsPoint(2)

Dim radius As Double
radius = 5#

Dim circObj As AcadCircle
Set circObj = currDoc.ModelSpace.AddCircle(centerPoint, radius)

‘ 画面を更新
currDoc.Regen acActiveViewport

MsgBox “UCS上の (10, 10) に、WCS変換を経て円を配置しました!”, vbInformation
Exit Sub

ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical
End Sub

コードの急所解説

  • 配列の型に注意!

AutoCAD VBAの座標系メソッドに渡す変数は、必ず `Double型` の固定長配列(またはそれを格納した `Variant`)である必要があります。ここを手抜いて `Dim p As Variant: p = Array(10, 10, 0)` などとやると、型不一致エラーの温床になります。プロなら `Dim ucsPoint(0 To 2) As Double` と明示的に宣言しましょう。

  • 戻り値は Variant

`TranslateCoordinates` の戻り値は `Variant`(中身はDouble型の配列)として返ってきます。そのため、一度 `wcsPoint` で受けてから、描画用の配列に詰め替えるのが安全かつ確実な設計です。

4. 陥りやすい罠:点(Point)とベクトル(Displacement)の混同

最後に、中級者が必ずハマる「最大の罠」についてお話します。

先ほどの引数の説明で出てきた、第4引数 `[Disp]`。これを軽視すると、図面が盛大にバグります。

  • `Disp = False`(省略時のデフォルト)「位置(点)」の変換。
  • 原点からの絶対位置を変換します。UCSの原点がWCSのどこにあろうとも、そのオフセットを正確に加味して計算してくれます。
  • `Disp = True`「ベクトル(方向・距離)」の変換。
  • 「長さ10のベクトル」などを変換する場合に使います。これは「原点の移動の影響を受けない(回転とスケールのみ反映される)」という性質を持ちます。

もし「あるオブジェクトから別のオブジェクトへの相対的な距離や移動量」を計算しているのに、`Disp = False` のまま座標変換してしまうと、UCSの原点ズレが二重に足されてしまい、計算結果が全くデタラメになってしまいます。

  • 位置を動かすなら `False`
  • 大きさや向き(差分)を計算するなら `True`

この鉄則さえ頭に入っていれば、どんなに複雑な斜め図面を相手にしようとも、あなたのVBAプログラムは微動だにせず正確な計算をやり遂げるでしょう。

まとめ

今回は、AutoCAD VBAにおける座標変換の極意、`TranslateCoordinates` メソッドについて解説しました。

1. AutoCADには WCS(世界)UCS(ユーザー) の2つのモノサシがある。
2. VBAから図形を配置するときは、原則として WCSに変換 する必要がある。
3. `TranslateCoordinates` を使えば、UCSからWCSへ(またはその逆へ)完璧な変換ができる。
4. 点の変換には `Disp = False`、ベクトルの変換には `Disp = True` を使い分ける。

ここをクリアしたあなたなら、もう「マクロの記録」の枠を超えた、本物のAutoCADプログラミングの領域に足を踏み入れています。
ぜひご自身の開発環境でコードを動かし、その精緻な挙動を体感してみてください。

それでは、次のステップでお会いしましょう。ハッピー・コーディング!

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