手順は2ステップ!?AutoCADでブロックを自動配置
こんにちは。
製造建設ソリューションサービス部の村上です。
早速ですが、AutoCADを使ったことある皆さんはこんなこと思ったことありませんか?
- 均等にブロックを並べるのがとても面倒…
- 配置するブロックの数が多くて作業時間が膨大に…
上記のような悩みは、誰でも1回は思ったことがあると思います。
そこで今回、前回(下記リンク参照)説明した内外判定のアルゴリズムを応用して、AutoCAD上でブロックを自動配置するコマンドを作成してみました!
意外と簡単!交差数から見る内外判定
内外判定アルゴリズムの汎用性とAutoCADカスタマイズの利便性の高さを感じていただけたらと思います。
コマンドの動作
ではコマンドの動作を説明する前に、大まかな動作の流れを説明させていただきます。
今回作成したコマンドでブロックを自動配置するためには、以下の操作を必要とします。
- 自動配置するブロックをダイアログで選択する。
- 選択ブロックを自動配置する為の多角形(領域)を指定する。
【ブロックを選択】して、【配置する領域を指定】するだけの2ステップだけです!
多くのブロックを手作業で配置する手間を考えると、圧倒的に簡単になっていることがもう分かると思います。
では、各操作毎に実際のコマンドの動作を交えつつ確認していきたいと思います。
ブロックの選択
まず一つ目の手順であるブロックの選択を行います。
始めに、作成したコマンドである「OfficeLayout」を実行します。
そうすると、以下のようなブロック選択のダイアログが表示されます。
ここで好きなブロックを選択し、ブロックの配置方向を指定して「OK」ボタンを押してみましょう。
そうすると、次は以下のような配置領域の指定操作へと移ります。
配置領域の指定
二つ目の手順である配置領域の指定では、以下の画面の通りに図面上で座標を指定して、選択ブロックを自動配置する為の多角形領域を作成します。
そして多角形領域を指定し終えた時に「Enter」キーを押すと…
指定した多角形領域内に、選択したブロックが自動配置されました!!
ちなみにブロックを「縦配置」ではなく「横配置」するようにダイアログで選択し、以下のように多角形領域を指定したとします。
この状態で「Enter」キーを押すと…
今度は指定した多角形領域内に、選択したブロックが横向きになった状態で自動配置が行われました!!
行った操作は【ブロックを選択】して【配置する領域を指定】するだけ。
AutoCADをカスタマイズすると、とても面倒な作業でもたった2ステップの操作だけで完了してしまいました。
コードの内容
では実際に、前回説明した内外判定アルゴリズムをどのように応用して自動配置コマンドを実装しているのか?
皆さん気になると思います。
しかし、今回の実装ではそこまで大層な応用はしてません。
今回実装した内外判定処理部分のソースコードは以下のような内容です。
/// 閉図形線分に対する指定座標の内外判定を行います。
/// arealineList:図形を構成する線分リスト(閉図形以外の場合は正しく動作しません)
/// point:指定ポイント
/// 処理結果(true:閉図形内、false:閉図形外)
public bool JudgmentInsideAndOutside(List<Line> areaLineList, Point3d point)
{
if (areaLineList == null)
{
throw new ArgumentNullException("引数がnullです。");
}
// 返却値の宣言
bool isInside = false;
// 交差回数の保持
List<Point3d> keepIntersectList = new List<Point3d>();
bool isVerticalJudge = true;
bool isHorizontalJudge = true;
// 縦判定線の生成
// leftUnder:左下座標
// rightUp:右上座標
Point3d leftUnderPoint = SearchLeftUnderPoint(areaLineList);
Point3d rightUpPoint = SearchRightUpPoint(areaLineList);
// 製品下端から領域高さ分だけ下がった点を遠点として判定線を生成する
Point3d farawayPoint = new Point3d(point.X, leftUnderPoint.Y - (Math.Abs(rightUpPoint.Y - leftUnderPoint.Y)), point.Z);
Line judgeLine = new Line(point, farawayPoint);
keepIntersectList = SearchIntersectPoint(areaLineList, judgeLine);
// 閉図形線分と判定線の交差回数が偶数なら、指定座標は閉図形外である
if (keepIntersectList.Count % 2 == 0)
{
isVerticalJudge = false;
}
// 横判定線の生成
farawayPoint = new Point3d(leftUnderPoint.X - (Math.Abs(rightUpPoint.X - leftUnderPoint.X)), point.Y, point.Z);
judgeLine = new Line(point, farawayPoint);
keepIntersectList = SearchIntersectPoint(areaLineList, judgeLine);
// 閉図形線分と判定線の交差回数が偶数なら、指定座標は閉図形外である
if (keepIntersectList.Count % 2 == 0)
{
isHorizontalJudge = false;
}
// 縦横両方向の内外判定で内側判定だった場合のみ、内側と判別する
if(isVerticalJudge == true && isHorizontalJudge == true)
{
isInside = true;
}
// 解放
judgeLine.Dispose();
return isInside;
}
いかかでしょうか?
前回説明した内容との違いとしては、指定ポイントから縦方向のみに線を引っ張って交差回数を見るのではなく、横方向にも線を引っ張って交差回数を見ています。
そして縦と横の両方の交差判定の結果より、内外判定を行ってます。
このように処理している理由については、是非考えてみてください。
きっとすぐ分かると思います。
▼キャパの公式Twitter・FacebookではITに関する情報を随時更新しています!
建築・土木業向け BIM/CIMの導入方法から活用までがトータルで理解できる ホワイトペーパー配布中!
❶BIM/CIMの概要と重要性
❷BIM/CIM導入までの流れ
❸BIM/CIM導入でよくある失敗と課題
❹BIM活用を進めるためのポイント
についてまとめたホワイトペーパーを配布中