AFsoft WebSite(エーエフソフト・ウェブサイト)
 

オペレーティング・システムについて

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
CADを考える:複合図形定義と複合図形配置(3)
前頁では構造化要素のツリーデータを作成し、座標変換の簡単なテストを作ってみましたが、ここでは、ツリーデータの各項目にそれぞれの変換行列を保持するようにしてみます。
 
type
 ・・・
 TFukugoZukeiTree = record  // 複合図形ツリー構造
  name : string ;      // 複合図形名
  level : integer ;     // 階層レベル(0:Root=用紙 1〜)
  par : integer ;      // 親No
  mtx : TMatrix ;      // 変換行列
 end;
・・・
 zFzt : array of TFukugoZukeiTree;  // 複合図形ツリー構造
 zFztN: Integer ;
// 複合図形ツリー構造 生成
// 複合図形内の複合図形を取得する再帰用サブ
// no : 親の複合図形定義 番号(1〜)
// lv : 階層レベル(0:root(用紙) 1〜) 無限ループ回避のため最大100
// pa : 親のツリー番号(0〜)
procedure TDataClass.MakeFZukeiTreeSub(no,lv,pa:integer) ;
var
 i,j : integer ;
 t,t1 : TMatrix ;
begin
 if (lv > 100) then exit ;
 for i:=0 to fDef[no-1].mFzkN-1 do begin
  if not(fDef[no-1].mFzk[i].exf) then continue ;
  j := FZukeiNameCheck(0,fDef[no-1].mFzk[i].name) ;
  if (j = 0) then continue;
  Inc(zFztN);
  if ((zFztN mod 200) = 1) then SetLength(zFzt,zFztN+199);
  with zFzt[zFztN-1] do begin
   name := fDef[no-1].mFzk[i].name;
   level := lv;
   par := pa;
   //
   MtxScale(t, fDef[no-1].mFzk[i].ratio_x,fDef[no-1].mFzk[i].ratio_y);
   MtxRotD(t1, fDef[no-1].mFzk[i].Angle);
   t := MtxMult(t, t1);
   MtxMove(t1, fDef[no-1].mFzk[i].X,fDef[no-1].mFzk[i].Y);
   t := MtxMult(t, t1);
   t1:= zFzt[pa].mtx ; // 親の変換行列
   mtx := MtxMult(t, t1);
  end;
  MakeFZukeiTreeSub(j,lv+1,zFztN-1);
 end;
end;
 
// 複合図形ツリー構造 生成
//  zFztN、zFzt
procedure TDataClass.MakeFZukeiTree ;
var
 i,j : integer ;
 t : TMatrix ;
begin
 zFzt := nil;
 zFztN := 0;
 for i:=0 to dFzkN-1 do begin
  if not(dFzk[i].exf) then continue ;
  j := FZukeiNameCheck(0,dFzk[i].name) ;
  if (j = 0) then continue;
  Inc(zFztN);
  if ((zFztN mod 200) = 1) then SetLength(zFzt,zFztN+199);
  with zFzt[zFztN-1] do begin
   name := dFzk[i].name;
   level := 1 ;
   par :=-1;
   //
   if (fDef[j-1].Flag = 2) then
    MtxSetYX(mtx) // 部分図YX座標系
   else
    MtxSetE(mtx);
   MtxScale(t, dFzk[i].ratio_x,dFzk[i].ratio_y);
   mtx := MtxMult(mtx, t);
   MtxRotD(t, dFzk[i].Angle);
   mtx := MtxMult(mtx, t);
   MtxMove(t, dFzk[i].X,dFzk[i].Y);
   mtx := MtxMult(mtx, t);
  end;
  MakeFZukeiTreeSub(j,2,zFztN-1);
 end;
 SetLength(zFzt,zFztN);
end;
UnitFunc.pasには、
// YXをXYに置き換える行列にする
procedure MtxSetYX(var t:TMatrix);
begin
 t.t11:=0.0; t.t12:=1.0; t.t13:=0.0;
 t.t21:=1.0; t.t22:=0.0; t.t23:=0.0;
 t.t31:=0.0; t.t32:=0.0; t.t33:=1.0;
end;
という手続きを追加し、部分図・測地座標系(YX座標系)を利用する場合に使用しています。倍率行列を掛け、回転行列を掛け、移動行列を掛けています。Subのほうでは、複合図形配置の変換行列を計算したあと、後ろに親の変換行列を掛けています。アフィン変換ですね。これにより、そのツリーの項目(ノード)での変換行列を生成・利用することによって、部分図・作図グループ・作図部品を表現することが出来ます。
 
なお、各複合図形配置のパラメータを変更した場合には、変換行列を再計算する必要があります。
 
複合図形定義と複合図形配置は下記のような感じで行います。複合図形配置の引数は、親の複合図形名、レイヤ指定、複合図形名、X位置、Y位置、角度、X尺度、Y尺度です。親の複合図形名を指定しない場合は、用紙上に配置、ということになります。
with CData do begin
 ・・・
 AddFZukeiDef('部分図A',1);  // XY座標系
 AddFZukeiDef('部分図B',2);  // YX座標系
 AddFZukeiDef('作図グループC',3);
 AddFZukeiDef('作図部品D',4);
 AddFZukeiDef('作図部品E',4);
 
 AddDataFZukei('',0,'部分図A',200.0,250.0,30.0,1.5,1.2);
 AddDataFZukei('部分図A',0,'作図グループC',50.0,50.0,30,1.0,1.0); // 作図グループは引数を指定しても無効化される
 AddDataFZukei('作図グループC',0,'作図部品D',50.0,50.0,30,0.5,0.5);
 AddDataFZukei('',0,'部分図B',400.0,250.0,0.0,1.0,1.0);
 AddDataFZukei('部分図B',0,'作図部品D',10.0,20.0,0.0,2.0,1.0);
 AddDataFZukei('部分図B',0,'作図部品E',10.0,20.0,0.0,1.0,2.0);
 AddDataFZukei('作図部品D',0,'作図部品E',10.0,20.0,0.0,0.5,0.5);
end;
 
複合図形定義と複合図形配置を行ったら、複合図形ツリー生成を行います。
// 表示ツリー生成
CData.MakeFZukeiTree ;
 
まだ何もデータ化していませんので、テストとして、変換行列を使って線分を作図するプログラムを作っています。赤色の四角形(0,0)〜(200,150)を用紙上に描画します。
// テスト描画 四角を描画
gp.G_SetPen(clRed);
lx1 := 0.0 ;
ly1 := 0.0 ;
lx2 := 200.0 ;
ly2 := 150.0 ;
 x1 := Trunc(ox + (lx1 - CData.zp.x/2.0)*mm_dot) ;
 y1 := Trunc(oy - (ly1 - CData.zp.y/2.0)*mm_dot) ;
 x2 := Trunc(ox + (lx2 - CData.zp.x/2.0)*mm_dot) ;
 y2 := Trunc(oy - (ly2 - CData.zp.y/2.0)*mm_dot) ;
 gp.G_Line(x1,y1,x2,y1);
 gp.G_Line(x2,y1,x2,y2);
 gp.G_Line(x2,y2,x1,y2);
 gp.G_Line(x1,y2,x1,y1);
 gp.G_Line(x1,y1,x2,y2);
 
部分図Aに緑色の四角形(0,0)〜(200,150)を描画します。上記で算出した変換行列を利用して、座標変換を行っています(手続き MtxXY())。CData.zFzt[0]は複合図形ツリーの一番上の項目データです。つまり、部分図Aとなります。座標変換を行った後は、用紙上に直接描画するコードと同じです。5本の線を描画していますので、5回分行っています。
// 部分図Aに 同じ四角を描画
gp.G_SetPen(clGreen);
MtxXY(lx3,ly3, lx1,ly1, CData.zFzt[0].mtx);
MtxXY(lx4,ly4, lx2,ly1, CData.zFzt[0].mtx);
 x1 := Trunc(ox + (lx3 - CData.zp.x/2.0)*mm_dot) ;
 y1 := Trunc(oy - (ly3 - CData.zp.y/2.0)*mm_dot) ;
 x2 := Trunc(ox + (lx4 - CData.zp.x/2.0)*mm_dot) ;
 y2 := Trunc(oy - (ly4 - CData.zp.y/2.0)*mm_dot) ;
 gp.G_Line(x1,y1,x2,y2);
MtxXY(lx3,ly3, lx2,ly1, CData.zFzt[0].mtx);
MtxXY(lx4,ly4, lx2,ly2, CData.zFzt[0].mtx);
 x1 := Trunc(ox + (lx3 - CData.zp.x/2.0)*mm_dot) ;
 y1 := Trunc(oy - (ly3 - CData.zp.y/2.0)*mm_dot) ;
 x2 := Trunc(ox + (lx4 - CData.zp.x/2.0)*mm_dot) ;
 y2 := Trunc(oy - (ly4 - CData.zp.y/2.0)*mm_dot) ;
 gp.G_Line(x1,y1,x2,y2);
MtxXY(lx3,ly3, lx2,ly2, CData.zFzt[0].mtx);
MtxXY(lx4,ly4, lx1,ly2, CData.zFzt[0].mtx);
 x1 := Trunc(ox + (lx3 - CData.zp.x/2.0)*mm_dot) ;
 y1 := Trunc(oy - (ly3 - CData.zp.y/2.0)*mm_dot) ;
 x2 := Trunc(ox + (lx4 - CData.zp.x/2.0)*mm_dot) ;
 y2 := Trunc(oy - (ly4 - CData.zp.y/2.0)*mm_dot) ;
 gp.G_Line(x1,y1,x2,y2);
MtxXY(lx3,ly3, lx1,ly2, CData.zFzt[0].mtx);
MtxXY(lx4,ly4, lx1,ly1, CData.zFzt[0].mtx);
 x1 := Trunc(ox + (lx3 - CData.zp.x/2.0)*mm_dot) ;
 y1 := Trunc(oy - (ly3 - CData.zp.y/2.0)*mm_dot) ;
 x2 := Trunc(ox + (lx4 - CData.zp.x/2.0)*mm_dot) ;
 y2 := Trunc(oy - (ly4 - CData.zp.y/2.0)*mm_dot) ;
 gp.G_Line(x1,y1,x2,y2);
MtxXY(lx3,ly3, lx1,ly1, CData.zFzt[0].mtx);
MtxXY(lx4,ly4, lx2,ly2, CData.zFzt[0].mtx);
 x1 := Trunc(ox + (lx3 - CData.zp.x/2.0)*mm_dot) ;
 y1 := Trunc(oy - (ly3 - CData.zp.y/2.0)*mm_dot) ;
 x2 := Trunc(ox + (lx4 - CData.zp.x/2.0)*mm_dot) ;
 y2 := Trunc(oy - (ly4 - CData.zp.y/2.0)*mm_dot) ;
 gp.G_Line(x1,y1,x2,y2);
 
同様に、作図グループCに水色の四角を(※作図グループは座標変換を行わないので部分図Aと同じ状態で作図される=部分図Aの四角に上書きされる)、作図部品Dに灰色の四角を、部分図Bに黄色い四角を、部分図B内の作図部品Dに同じく灰色の四角を描画しています。

 
四角の大きさが違うのは、X尺度・Y尺度を指定しているためです。部分図BはYX座標系ですので、X値とY値が逆状態で描画されています。部分図B内の作図部品Dも同様にYX座標系となります。
 
 
ここまでのテストプログラムです。実行ファイル、gdiplus.dll、gdipフォルダは入っていません。ソースのみです。
 
CAD装置(1)
CAD装置(2)
メディア
AutoCADの
DIESELマクロ
CSV
DXF
PCES
IGES
STEP
数学とCAD
CAD作ろ!
CADを考える
 ▲PREV
 ▼NEXT
M7
Jw_cad
 
お問い合わせ 
本サイトはリンクフリーです
リンクバナー
(C)Copyright 1999-2015 By AFsoft All Rights Reserved.