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

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

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
CADを考える:ハッチング(2)
前頁の続きで、ハッチングについて考えます。
前頁でのハッチング領域図形は閉じた連続線でしたが、SXF仕様でのハッチングフィーチャでは複合曲線=円弧・楕円弧・折線・スプライン曲線の集まりで構成されるとなっています。折線はそのままだから良いとして、スプライン曲線も分割数指定による線分の集まりとして表示していますからそれを使用すれば良いのですが、円弧・楕円弧については少し考えねばなりません。つまり、円弧・楕円弧として計算を行うのか、それとも、補間線分の集まりとして計算を行うのか、です。前者の場合は当然、直線と円(円弧)の交点計算、直線と楕円(楕円弧)の交点計算が必須となってきます。そうすると当然、プログラムは複雑化します。ただ、正確に計算を行えばハッチング線は正しい座標で表示されるでしょう。けれども円弧・楕円弧は多角形状態で表示されるので、ハッチング線ははみ出て表示されてしまう可能性はあります。

 
後者の場合は、円弧・楕円弧の分割数が一定であれば、はみ出て表示される事は無いでしょうけれども、複数の補間線分として扱うため、計算量は多くなります。仮に円弧分割数を72とすれば、72本の線分での交点計算となります。しかし厳密に、どれくらいの速度差があるのか?というのは実際にはよく分かりません。ここで注意すべきなのは、円弧・楕円弧は現状、画面倍率によって分割数が変わるため、画面の拡大・縮小をする都度、ハッチング計算を行わないといけない、という事です。ハッチング領域図形が複雑な状態だったりデータ項目内容が複雑な状態だった場合、画面を表示するたびに ハッチング計算をやりなおしして表示、という事になると、データ量が多くなればなるほど、遅くなっていくかもしれない、という不安はあります。となれば、メモリ使用量は増えてしまいますが、ハッチング要素データに、計算後のハッチング線の集まりのデータを格納するようにしておき、ハッチング要素データを作成・変更した場合にその内容を更新するようにして、ハッチング要素データを表示する場合には何度も計算するのではなく、その計算済の線分の集まりを表示するようにしておけば、速度的に 想定外の遅れ というのはおそらく発生しないだろうと思われます。
 
そうなってくると、円弧・楕円弧が画面倍率によって分割数が変わってしまうというのは不味いという事になりますので、円弧・楕円弧の要素データ内に分割数のデータ項目を追加し、それを参照するようにする、という事にならざるを得なくなります。分割数を変更=複合曲線定義要素の変更=それに関わるハッチング要素データの変更=ハッチング線の算出→画面の再作図、という事にはなるだろうと思われます。
 
という訳で、本プログラムでは、複合曲線定義された円弧・楕円弧を指定分割数での補間線分として扱い、ハッチング計算を行うものとします。そのため、円弧・楕円弧要素データに分割数のデータ項目を追加します。仕様が異なるとおかしいので円・楕円・弧長/角度寸法・バルーン要素データも同様にしておきます。
 
UnitData.pas
 ・・・
 TDataCircle = record   // 幾何要素/表記要素|円
  exf : Boolean ;    // 存在フラグ(True:有り False:無し)
  Layer : Integer ;   // レイヤ(1〜256)
  Color : Integer ;   // 色 (0:レイヤ色  1〜256)
  Ltype : Integer ;   // 線種 (0:レイヤ線種 1〜32)
  line_width: Integer ; // 線幅 (0:レイヤ線幅 1〜16)
  sep : Integer ;    // 分割数(3〜3600)
  Center_x : double ;  // 中心点X座標
  Center_y : double ;  // 中心点Y座標
  Radius : double ;   // 半径
 end;
 
 TDataArc = record    // 幾何要素/表記要素|円弧
  exf : Boolean ;    // 存在フラグ(True:有り False:無し)
  Layer : Integer ;   // レイヤ(1〜256)
  Color : Integer ;   // 色 (0:レイヤ色  1〜256)
  Ltype : Integer ;   // 線種 (0:レイヤ線種 1〜32)
  line_width: Integer ; // 線幅 (0:レイヤ線幅 1〜16)
  sep : Integer ;    // 分割数(3〜3600)
  Center_x : double ;  // 中心点X座標
  Center_y : double ;  // 中心点Y座標
  Radius : double ;   // 半径
  Direction : Integer ; // 向き (0:反時計廻り,1:時計廻り)
  start_angle : double ; // 始角[°]
  end_angle : double ;  // 終角[°]
 end;
 
 TDataEllipse = record  // 幾何要素/表記要素|楕円
  exf : Boolean ;    // 存在フラグ(True:有り False:無し)
  Layer : Integer ;   // レイヤ(1〜256)
  Color : Integer ;   // 色 (0:レイヤ色  1〜256)
  Ltype : Integer ;   // 線種 (0:レイヤ線種 1〜32)
  line_width: Integer ; // 線幅 (0:レイヤ線幅 1〜16)
  sep : Integer ;    // 分割数(3〜3600)
  Center_x : double ;  // 中心点X座標
  Center_y : double ;  // 中心点Y座標
  Radius_x : double ;  // X方向半径
  Radius_y : double ;  // Y方向半径
  rotation_angle:double; // 回転角[°]
 end;
 
 TDataEllipseArc = record // 幾何要素/表記要素|楕円弧
  exf : Boolean ;    // 存在フラグ(True:有り False:無し)
  Layer : Integer ;   // レイヤ(1〜256)
  Color : Integer ;   // 色 (0:レイヤ色  1〜256)
  Ltype : Integer ;   // 線種 (0:レイヤ線種 1〜32)
  line_width: Integer ; // 線幅 (0:レイヤ線幅 1〜16)
  sep : Integer ;    // 分割数(3〜3600)
  Center_x : double ;  // 中心点X座標
  Center_y : double ;  // 中心点Y座標
  Radius_x : double ;  // X方向半径
  Radius_y : double ;  // Y方向半径
  Direction: Integer ;  // 向き (0:反時計廻り,1:時計廻り)
  rotation_angle:double; // 回転角[°]
  start_angle : double ; // 始角[°]
  end_angle : double ;  // 終角[°]
 end;
 ・・・
 TDataDimArc = record   // 構造化要素|弧長寸法・角度寸法
  exf : Boolean ;    // 存在フラグ(True:有り False:無し)
  Layer : Integer ;   // レイヤ(1〜256)
  Color : Integer ;   // 色 (0:レイヤ色  1〜256)
  Ltype : Integer ;   // 線種 (0:レイヤ線種 1〜32)
  line_width: Integer ; // 線幅 (0:レイヤ線幅 1〜16)
  sep : Integer ;    // 分割数(3〜3600)
  sun_x : double ;    // 寸法線原点X座標
  sun_y : double ;    // 寸法線原点Y座標
  sun_radius : double ; // 寸法線半径
  sun_angle0 : double ; // 寸法線始角[°]
  sun_angle1 : double ; // 寸法線終角[°]
  ・・・
 end;
 ・・・
 TDataDimBalloon = record // 構造化要素|バルーン
  exf : Boolean ;    // 存在フラグ(True:有り False:無し)
  Layer : Integer ;   // レイヤ(1〜256)
  Color : Integer ;   // 色 (0:レイヤ色  1〜256)
  Ltype : Integer ;   // 線種 (0:レイヤ線種 1〜32)
  line_width: Integer ; // 線幅 (0:レイヤ線幅 1〜16)
  sep : Integer ;    // 分割数(3〜3600)
  vertex_number :integer; // 頂点数 (2〜)
  vertex_x : array of double ; // 頂点X座標
  ・・・
 end;
 ・・・
データ構造を変更しましたので、各データ追加用関数も変更しておきます。
UnitData.pas
function AddDataCircle(s:string;lay,col,ltp,wid,sp:integer;
 cx,cy,cr:double) : Boolean;
function AddDataArc(s:string;lay,col,ltp,wid,sp,dir:integer;
 cx,cy,cr,sa,ea:double) : Boolean;
function AddDataEllipse(s:string;lay,col,ltp,wid,sp:integer;
 cx,cy,rx,ry,ra:double) : Boolean;
function AddDataEllipseArc(s:string;lay,col,ltp,wid,sp,dir:integer;
 cx,cy,rx,ry,ra,sa,ea:double) : Boolean;
・・・
function AddDataDimArc(s,st:string;lay,col,ltp,wid,sp,f2,f3,f4,
 ar11,ar12,ar21,ar22,fnt,bp,dir:integer;
 sx,sy,sr,sa0,sa1, h1x0,h1y0,h1x1,h1y1,h1x2,h1y2,
 h2x0,h2y0,h2x1,h2y1,h2x2,h2y2, ar1x,ar1y,ar1r, ar2x,ar2y,ar2r,
 tx,ty,th,tw,ts,an,sl:double) : Boolean ;
function AddDataDimAngle(s,st:string;lay,col,ltp,wid,sp,f2,f3,f4,
 ar11,ar12,ar21,ar22,fnt,bp,dir:integer;
 sx,sy,sr,sa0,sa1, h1x0,h1y0,h1x1,h1y1,h1x2,h1y2,
 h2x0,h2y0,h2x1,h2y1,h2x2,h2y2, ar1x,ar1y,ar1r, ar2x,ar2y,ar2r,
 tx,ty,th,tw,ts,an,sl:double) : Boolean ;
・・・
function AddDataDimBalloon(s,st:string;lay,col,ltp,wid,sp,fl,
 num,ar,fnt,bp,dir:integer;vx,vy:array of double;
 cx,cy,cr,arr, tx,ty,th,tw,ts,an,sl:double) : Boolean ;
・・・
function AddCCrvDataArc(id,sp,dir:integer;
 cx,cy,cr,sa,ea:double) : Boolean;
function AddCCrvDataEllipseArc(id,sp,dir:integer;
 cx,cy,rx,ry,ra,sa,ea:double) : Boolean;
勿論、関数内部で
with dCir[dCirN-1] do begin
 exf    := True ;
 Layer   := lay ;
 Color   := col ;
 Ltype   := ltp ;
 line_width := wid ;
 sep    := sp ;
 Center_x  := cx ;
 Center_y  := cy ;
 Radius   := cr ;
end;
のように追加するようにします。次に、画面表示のほうも変更します。
UnitDataGraph.pas
procedure DisplayCircle(lay,col,ltp,wid,sp:integer;
 px,py,pr:double;t:TMatrix);
procedure DisplayArc(lay,col,ltp,wid,sp,dir:integer;
 px,py,pr,sa,ea:double;t:TMatrix);
procedure DisplayEllipse(lay,col,ltp,wid,sp:integer;
 px,py,rx,ry,ra:double;t:TMatrix);
procedure DisplayEllipseArc(lay,col,ltp,wid,sp,dir:integer;
 px,py,rx,ry,ra,sa,ea:double;t:TMatrix);
 
procedure DisplayDimArc(lay,col,ltp,wid,sp,f2,f3,f4,
 ar11,ar12,ar21,ar22,fnt,bp,dir:integer;
 sx,sy,sr,sa0,sa1, h1x0,h1y0,h1x1,h1y1,h1x2,h1y2,
 h2x0,h2y0,h2x1,h2y1,h2x2,h2y2, ar1x,ar1y,ar1r, ar2x,ar2y,ar2r,
 tx,ty,th,tw,ts,an,sl:double;st:string;t:TMatrix);
procedure DisplayDimAngle(lay,col,ltp,wid,sp,f2,f3,f4,
 ar11,ar12,ar21,ar22,fnt,bp,dir:integer;
 sx,sy,sr,sa0,sa1, h1x0,h1y0,h1x1,h1y1,h1x2,h1y2,
 h2x0,h2y0,h2x1,h2y1,h2x2,h2y2, ar1x,ar1y,ar1r, ar2x,ar2y,ar2r,
 tx,ty,th,tw,ts,an,sl:double;st:string;t:TMatrix);
 
procedure DisplayDimBalloon(lay,col,ltp,wid,sp,fl,
 num,ar,fnt,bp,dir:integer;vx,vy:array of double;
 cx,cy,cr, arr, tx,ty,th,tw,ts,an,sl:double;st:string;t:TMatrix);
点マーカの円は、72分割で表示するようにしておきます。
 
例えば円の描画は下記のようになり、以前に比べシンプルになっています。
UnitDataGraph.pas
// 円の表示
procedure DisplayCircle(lay,col,ltp,wid,sp:integer;
 px,py,pr:double;t:TMatrix);
var
 c,cc,l,w, i,j : integer ;
 ww, d1, a,aa, x1,y1,x2,y2,x3,y3,x4,y4 : double ;
 fl : Boolean ;
begin
 // 円・クリッピングチェック
 x1 := px-pr; y1 := py-pr; MtxXY(x1,y1, x1,y1, t);
 x2 := px+pr; y2 := py-pr; MtxXY(x2,y2, x2,y2, t);
 x3 := px+pr; y3 := py+pr; MtxXY(x3,y3, x3,y3, t);
 x4 := px-pr; y4 := py+pr; MtxXY(x4,y4, x4,y4, t);
 if (Clip4Point(x1,y1,x2,y2,x3,y3,x4,y4,
         WndX1,WndY1,WndX2,WndY2) = 2) then exit;
 
 a := 2.0*Pi/sp ;
 
 DisplayLayCol2(lay,col,ltp,wid, c,cc,l,w,ww);
 //
 fl := False ;
 if (CData.zLtp[l-1].Segment = 0)
  or(CData.zLtp[l-1].SpaceMax * mm_dot < 2.0)
  or(CData.zLtp[l-1].SpaceMax * mm_dot < ww ) then
  fl := True ;
 
 i := 0 ;
 d1 := 0.0 ;
 aa := 0.0 ;
 x1 := px + pr*Cos(aa);
 y1 := py + pr*Sin(aa);
 MtxXY(x1,y1, x1,y1, t);
 for j:=1 to sp do begin
  aa := aa + a;
  x2 := px + pr*Cos(aa);
  y2 := py + pr*Sin(aa);
  MtxXY(x2,y2, x2,y2, t);
  if (fl) then
   DisplayLineSub1(x1,y1,x2,y2)
  else
   DisplayLineSub2(l,i,d1, x1,y1,x2,y2) ;
  x1 := x2 ;
  y1 := y2 ;
 end;
end;
 
以上により、円・円弧・楕円・楕円弧・弧長寸法・角度寸法・バルーンの各要素データを作図する際には、分割数を追加して指定するようになりました。
 
次に、ハッチング領域図形はSXF・構造化要素の「複合曲線定義」で行われますが、複合曲線定義された折線・円弧・楕円弧・スプライン曲線がちゃんと接続されているかどうか?のチェックを行った方が良いと思われますので、そのチェック用関数を作成する事にします。
 
要素データ登録順にチェックをするのでしたら、始点・終点の座標がちゃんと合っているかどうかを順にチェックしていくだけですのでそんなに難しくありません。「SXF Ver.3.1実装規約.pdf」にて以下のように記述されています。
1-11 複合曲線定義
(1)複合曲線の閉合判定
データ保持
・複合曲線の閉合を判定する際の閾値は、
 実寸で±0.0001 o(二点間の距離)までとする。
【趣旨】
・複合曲線が、閉じた領域を構成しているか否かの判定が
 CADソフト毎に異なっていると、データ交換時に不都合が生じる。
とありますので、距離ですから、
 √(終点X−次要素の始点X)2+(終点Y−次要素の始点Y)2
の値が0.001以下であればOK、とすれば良いでしょう。なお、平方根の計算で遅くなるかもしれないので
 (終点X−次要素の始点X)2+(終点Y−次要素の始点Y)2
の値が0.000001以下であればOK、でも良いでしょう。
 
複合曲線定義を1つずつ行う際にチェックをするという事でも良いかもしれませんが、ここでは、登録をしてしまってから最後にチェックを行う、という事にします。
 
なお、複合曲線定義内の要素データが順序よく並んでおらずバラバラ状態の場合は?となれば、どこかで並べ替えの処理が必要になってくると思われますが、現実的に、CAD操作として複合曲線定義を行うとすれば、どのような操作をするでしょうか? おそらくは、1つずつ要素をクリックしていく方法と、範囲選択をする方法があるでしょう。そうすれば、その時にチェック&並べ替えを行って登録をすれば良い、としてしまえば、現段階のデータレベルでの並べ替えは必要無いでしょう。それに、複合曲線定義内の要素データの並びがバラバラの場合、他CADへもっていったときに正常に処理されるかどうか?という不安もあります。
UnitData.pas
// 複合曲線定義内データの接続チェック
// id : ID番号(1-)
// (ret) True:OK False:NG
function TDataClass.CCrvDataCheck(id:integer) : Boolean ;
 
複合曲線定義でデータ登録出来るのは、折線・円弧・楕円弧・スプライン曲線ですが、例えば線分を扱いたい場合には、2頂点の折線に変換する、という処理が必要でしょうし、円や楕円を扱いたい場合は、2つの円弧・2つの楕円弧に変換する処理は必要になるだろうと思われます。
 
 
次に、複合曲線定義により表現されるハッチング領域図形は連続線分として表現される訳ですが、ハッチング領域を示す変数は先に述べたように
zHAr : array of TWorkHatchArea ; // 作業用|ハッチング領域
zHArN: Integer ;
ですが、これは1つのハッチングを描画する際に利用する一時的な作業用変数で、1つの図面データ内には1つのハッチングのみ存在、という事は極めて稀ですので、この変数内に永続的に図形データが保持されるという事はありません。
 
複合曲線定義を行い、接続チェックを行い、連続線分データ化を行い、自己交差チェックを行い、ハッチング計算を行い、ハッチング描画を行う、という流れの中で、連続線分データ化をしたものをどこに入れるのか、という事で、複合曲線定義データ毎に変数を用意してそこに入れておき、ハッチングで利用する場合にはその都度、データ受け渡しをする、という手法があります。また、作業用ハッチング領域に直接入れるようにする手法があります。
前者は管理しやすい事・複合曲線定義データを複数回利用する場合には有効である事(例えば、異なるハッチングを重ねて描画する場合や、中抜きの中に更にハッチングを掛ける場合など)というメリットはありますが、メモリを消費する事・データ受け渡しをする必要がある事というデメリットもあります。
後者は逆に、複合曲線定義データを複数回利用する場合は、その都度、連続線分データを生成しなおす必要がある事・そうなると自己交差チェックも再度行われてしまう可能性もある事というデメリットはある反面、連続線分データ用メモリとして必要はないというメリットはあります。
要するに、可能性・頻度の問題なのですが、各ハッチングデータ毎にハッチング線分用のメモリも別途必要になってきますし、あまりにメモリを消費し過ぎても問題になりますので、ここは、後者のパターンをとる事にします。
 
その作業を行う前に、円弧・楕円弧・スプライン曲線を連続線分データに変換する手続きについて考えます。これらは既に、UnitDataGraph.pasでの Display〜という手続きで描画できるようになっていますが、描画そのものと直結しているため、描画はしないけれども連続線分データが欲しいという場合にはそのまま利用出来ません。円弧程度ならその都度プログラムコードを書いても大した作業ではありませんが流石にスプライン曲線ともなると作業効率が落ちてしまいます。後々利用しやすいようにそれ用のユニット UnitFuncCurve.pas として作っておきます。
 
旧:
UnitDataGraph.pas
// 円の表示
procedure DisplayCircle(lay,col,ltp,wid:integer;
 px,py,pr:double;t:TMatrix);
 ・・・
 a := 2.0*Pi / n ;
 
 DisplayLayCol2(lay,col,ltp,wid, c,cc,l,w,ww);
 //
 fl := False ;
 if (CData.zLtp[l-1].Segment = 0)
  or(CData.zLtp[l-1].SpaceMax * mm_dot < 2.0)
  or(CData.zLtp[l-1].SpaceMax * mm_dot < ww ) then
  fl := True ;
 
 i := 0 ;
 d1 := 0.0 ;
 aa := 0.0 ;
 x1 := px + pr*Cos(aa);
 y1 := py + pr*Sin(aa);
 MtxXY(x1,y1, x1,y1, t);
 for j:=1 to Round(n) do begin
  aa := aa + a;
  x2 := px + pr*Cos(aa);
  y2 := py + pr*Sin(aa);
  MtxXY(x2,y2, x2,y2, t);
  if (fl) then
   DisplayLineSub1(x1,y1,x2,y2)
  else
   DisplayLineSub2(l,i,d1, x1,y1,x2,y2) ;
  x1 := x2 ;
  y1 := y2 ;
 end;
end;
               ↓
新:
UnitDataGraph.pas
// 円の表示
procedure DisplayCircle(lay,col,ltp,wid:integer;
 px,py,pr:double;t:TMatrix);
 ・・・
 DisplayLayCol2(lay,col,ltp,wid, c,cc,l,w,ww);
 //
 fl := False ;
 if (CData.zLtp[l-1].Segment = 0)
  or(CData.zLtp[l-1].SpaceMax * mm_dot < 2.0)
  or(CData.zLtp[l-1].SpaceMax * mm_dot < ww ) then
  fl := True ;
 
 TransCircleToLines(sp,px,py,pr,t);
 if (tLnsN = 0) then exit;
 
 i := 0 ;
 d1 := 0.0 ;
 x1 := tLns[0].x ;
 y1 := tLns[0].y ;
 for j:=1 to tLnsN-1 do begin
  x2 := tLns[j].x ;
  y2 := tLns[j].y ;
  if (fl) then
   DisplayLineSub1(x1,y1,x2,y2)
  else
   DisplayLineSub2(l,i,d1, x1,y1,x2,y2) ;
  x1 := x2 ;
  y1 := y2 ;
 end;
 
 TransLnsClear ;
end;
 
UnitFuncCurve.pas
・・・
var
 tLns : array of TPointD ; // 変換した連続線分データ
 tLnsN : integer ;
 
 procedure TransLnsClear ;
 procedure TransCircleToLines(sp:integer;px,py,pr:double;t:TMatrix);
 
implementation
 
// 変換連続線分データのクリア
procedure TransLnsClear ;
begin
 tLns := nil ;
 tLnsN := 0 ;
end;
 
// 円を連続線分に変換
procedure TransCircleToLines(sp:integer;px,py,pr:double;t:TMatrix);
var
 j : integer ;
 a,aa, x1,y1 : double ;
begin
 try
  tLnsN := sp + 1 ;
  SetLength(tLns, tLnsN);
 except
  TransLnsClear ;
  exit ;
 end;
 
 a := 2.0*Pi/sp ;
 aa := 0.0 ;
 for j:=0 to sp do begin
  x1 := px + pr*Cos(aa);
  y1 := py + pr*Sin(aa);
  MtxXY(x1,y1, x1,y1, t);
  tLns[j].x := x1 ;
  tLns[j].y := y1 ;
  aa := aa + a;
 end;
end;
 
end.
2段階となりますので一見面倒かもしれませんが、同じようなプログラムコードを複数書くよりは楽になりますし、同じ円でも、あちこちで異なる式・状態になってしまっているというような事がなくなり共通性も取れます。
 
上記の円と同様に、円弧・楕円・楕円弧・スプライン曲線・クロソイド曲線の処理も行うようにします。なお、スプライン曲線は各頂点に変換行列を掛けてから計算を行って描画を行っていましたが、上記ユニット化により各手続きの引数を共通化するためスプライン曲線にも変換行列を指定するようにしたため、算出される各座標に対して変換行列を掛けるよう仕様変更しています。折線もこれに統一出来るようにしておきます。
 
UnitFuncCurve.pas
unit UnitFuncCurve;
 
interface
 
uses
 Windows, UnitFunc ;
 
var
 tLns : array of TPointD ; // 変換した連続線分データ
 tLnsN : integer ;
 
 procedure TransLnsClear ;
 procedure TransLinesToLines(num:integer;vx,vy:array of double;
   t:TMatrix);
 procedure TransCircleToLines(sp:integer;px,py,pr:double;
   t:TMatrix);
 procedure TransArcToLines(sp,dir:integer;px,py,pr,sa,ea:double;
   t:TMatrix);
 procedure TransEllipseToLines(sp:integer;px,py,rx,ry,ra:double;
   t:TMatrix);
 procedure TransEllipseArcToLines(sp,dir:integer;px,py,rx,ry,ra,
   sa,ea:double;t:TMatrix);
 procedure TransBezierToLines(sp,num:integer;
   vx,vy:array of double;t:TMatrix);
 procedure TransBsplineToLines(oc,sp,num:integer;
   vx,vy:array of double;t:TMatrix);
 procedure TransSplineToLines(stp,oc,sp,num:integer;av:double;
   vx,vy:array of double;t:TMatrix);
 procedure TransClothoidToLines(dir,sp:integer;
   bx,by,av,an,l1,l2:double;t:TMatrix);
 
それでは、複合曲線定義データからハッチング領域図形を生成する関数を作成します。
UnitData.pas
// 複合曲線定義内データからハッチング領域図形へ
//  id : ID番号(1-)
//  no : ハッチング領域図形番号(1-)
// (ret) True:OK False:NG
// ※ハッチング領域図形 zHAr,zHArN は予めセット・メモリ確保
function TDataClass.CCrvDataToHAr(id,no:integer) : Boolean ;
これにより、ハッチング領域図形用の連続線分データを生成することが出来ますので、これを利用してハッチングのテストを行ってみます。
 
Unit1.pas
SetLength(lx,5);
SetLength(ly,5);
CData.AddCCurveDef(1,1,1,1,1); // 複合曲線定義 #1
lx[0] := 40; ly[0] := 40 ;
lx[1] := 140; ly[1] := 40 ;
lx[2] := 140; ly[2] := 140 ;
lx[3] := 40; ly[3] := 140 ;
lx[4] := 40; ly[4] := 40 ;
CData.AddCCrvDataLines(1,5,lx,ly); // 折線
 
CData.AddCCurveDef(2,1,1,1,1); // 複合曲線定義 #2
lx[0] := 60; ly[0] := 60 ;
lx[1] := 60; ly[1] := 100 ;
lx[2] := 100; ly[2] := 100 ;
lx[3] := 100; ly[3] := 60 ;
lx[4] := 60; ly[4] := 60 ;
CData.AddCCrvDataLines(2,5,lx,ly); // 折線
 
CData.AddCCurveDef(3,1,1,1,1); // 複合曲線定義 #3
lx[0] := 110; ly[0] := 50 ;
lx[1] := 130; ly[1] := 90 ;
lx[2] := 110; ly[2] := 130 ;
lx[3] := 110; ly[3] := 50 ;
CData.AddCCrvDataLines(3,4,lx,ly); // 折線
 
CData.AddCCurveDef(4,1,1,1,1); // 複合曲線定義 #4
CData.AddCCrvDataArc(4,36,0, 80,120,15,0,180);
CData.AddCCrvDataArc(4,36,0, 80,120,15,180,0);
 
lx := nil;
ly := nil;
 
// ----- ハッチングテスト -----
 
// ハッチング領域図形のセット
CData.zHArN := 4 ;
SetLength(CData.zHAr,CData.zHArN);
CData.CCrvDataToHAr(1,1); // 複合曲線定義 #1 → 外郭部
CData.CCrvDataToHAr(2,2); // 複合曲線定義 #2 → 中抜1
CData.CCrvDataToHAr(3,3); // 複合曲線定義 #3 → 中抜2
CData.CCrvDataToHAr(4,4); // 複合曲線定義 #4 → 中抜3
// min,maxを取得
・・・
 
ハッチングの作図テストです。まだ要素データ化は行っていません。

 
長くなりますので、取り合えずはここまでにしておきます。
 
 
それでは、ここまでのテストプログラムです。実行ファイル、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.