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

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

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
CADを考える:折線
前頁では、幾何要素/表記要素フィーチャの線分について見ましたのでここでは、同じく幾何要素/表記要素フィーチャの折線について見ていく事にします。折線は、「連続線」や「ポリライン」と呼ばれる場合が多いと思います。CADソフトによっては、複数の線分要素の集まりであるかもしれません。しかしここでは、複数の頂点を持つ1本の折線という扱いになります。
 
幾何要素/表記要素|折線

頂点数:3
X座標:(1.0, 3.0, 6.0)
Y座標:(1.0, 3.0, 0.0)
パラメータ説明範囲
LayerIntレイヤコード
ColorInt色コード
TypeInt線種コード
line_widthInt線幅コード
NumberInt頂点数2≦数<int(32bits)の最大値
X CArray
<double
,double>
X座標(配列) double(64bits)の
範囲(有効桁15桁)
Y CArray
<double
,double>
Y座標(配列) double(64bits)の
範囲(有効桁15桁)
備考
・となり合わせた点に同一の点は指定できない。
SXF Ver.3.1実装規約では、線分同様、折線についても何も無さそうです。
 
それでは折線のデータ構造を決めます。
UnitData.pas
type
 ・・・
 TDataLines = 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)
  Number : Integer ;  // 頂点数
  X : array of double ; // 頂点X座標
  Y : array of double ; // 頂点Y座標
 end;
 
 TFukugoZukeiDef = record  // 構造化要素|複合図形定義
  exf : Boolean ;     // 存在フラグ(True:有り False:無し)
  name : string ;     // 複合図形名
  Flag : Integer ;     // 種別フラグ
  cnt : Integer ;     // 配置数
  ・・・
  mLns : array of TDataLines;    // 幾何要素|折線
  mLnsN : Integer ;         // 数
  mFzk : array of TDataFukugoZukei; // 構造化要素|複合図形配置
  mFzkN : Integer ;         // 数
 end;
 
 TDataClass = class
  public
  { Public 宣言 }
  ・・・
  dLns : array of TDataLines;    // 表記要素|折線
  dLnsN: Integer ;         // 数
  ・・・
 
データ追加用の関数は
function AddDataLines(s:string;lay,col,ltp,wid,num:integer;vx,vy:array of double) : Boolean;
のようにします。点マーカ・線分と同様、最初に「データ追加先の複合図形名(幾何要素) null:用紙へ追加(表記要素)」を指定するようにしています。
 
UnitData.pas
// 折線 データ項目の追加登録
function TDataClass.AddDataLines(s:string;lay,col,ltp,wid,num:integer;vx,vy:array of double) : Boolean;
var
 m,i : integer ;
begin
 Result := False;
 if (lay < 1) or (lay > zLayN) then lay := 1 ;
 if (col < 0) or (col > zColN) then col := 0 ;
 if (ltp < 0) or (ltp > zLtpN) then ltp := 0 ;
 if (wid < 0) or (wid > zWidN) then wid := 0 ;
 if (num < 0) then num := 0 ;
 
 if (s = '') then begin
  // 用紙へ追加
  try
   Inc(dLnsN);
   if ((dLnsN mod 100) = 1) then SetLength(dLns, dLnsN+99);
   with dLns[dLnsN-1] do begin
    exf := True ;
    Layer := lay ;
    Color := col ;
    Ltype := ltp ;
    line_width := wid ;
    Number := num ;
    SetLength(X, num);
    SetLength(Y, num);
    for i:=0 to num-1 do begin
     X[i] := vx[i];
     Y[i] := vy[i];
    end;
   end;
   Result := True ;
   AddLayerCnt(lay,col,ltp,wid,-1);
  except
   Dec(dLnsN);
  end;
 end
 else begin
  m := FZukeiNameCheck(0,s);
  if (m = 0) then exit ; // 追加先の複合図形名は無いのでエラー
  with fDef[m-1] do begin
   try
    Inc(mLnsN);
    if ((mLnsN mod 100) = 1) then SetLength(mLns, mLnsN+99);
    with mLns[mLnsN-1] do begin
     exf := True ;
     Layer := lay ;
     Color := col ;
     Ltype := ltp ;
     line_width := wid ;
     Number := num ;
     SetLength(X, num);
     SetLength(Y, num);
     for i:=0 to num-1 do begin
      X[i] := vx[i];
      Y[i] := vy[i];
     end;
    end;
    Result := True ;
    AddLayerFCnt(lay,col,ltp,wid,-1);
   except
    Dec(mLnsN);
   end;
  end;
 end;
end;
 
 
さて、これで折線データの登録は出来るようになりました。
 
次に、折線の描画についてですが、折線は線分の集まりですから単純に線分描画ルーチンを複数回数呼び出して実行すれば、可能です。実線の場合はそれでも良いのですが、破線等の場合だと、各頂点間のたびにピッチがリセットされてしまって綺麗ではなくなってしまいます。下図は、左上→右上→右下→左下→左上の四角形を一点鎖線で描画する例ですが、

線と線の接続部が綺麗でなかったり、指定した線種のようには見えなかったりしますし、折線データにする意味も半減してしまうので、やはり、線種状態を保持するように描画させた方が良いでしょう。

 
UnitData.pas
// 折線の表示
procedure TForm1.DisplayLines(lay,col,ltp,wid,num:integer;vx,vy:array of double);
var
 c,w,ww,l,i,j : integer ;
 x1,y1,x2,y2 : integer ;
 a,sa,ca,d,d1,p,wx1,wy1,wx2,wy2 : double ;
 fl : Boolean ;
begin
 c := col ;
 if (c = 0) then c := CData.zLay[lay-1].Color ;
 c := RGB(CData.zCol[c-1].Red,CData.zCol[c-1].Green,CData.zCol[c-1].Blue);
 gp.G_SetPen(c);
 w := wid ;
 if (w = 0) then w := CData.zLay[lay-1].Width ;
 ww:= Round(CData.zWid[w-1].Width * mm_dot) ;
 if (ww < 1) then ww := 1 ;
 gp.G_SetWidth(ww);
 l := ltp ;
 if (l = 0) then l := CData.zLay[lay-1].Ltype ;
 //
 if (CData.zLtp[l-1].Segment = 0)
  or(CData.zLtp[l-1].SpaceMax * mm_dot < 2.0)
  or(CData.zLtp[l-1].SpaceMax < CData.zWid[w-1].Width) then begin
  Z2D(x1,y1, vx[0],vy[0]);
  for i:=1 to num-1 do begin
   Z2D(x2,y2, vx[i],vy[i]);
   gp.G_Line(x1,y1,x2,y2);
   x1 := x2 ;
   y1 := y2 ;
  end;
 end
 else begin
  i := 0 ;
  d1:= 0.0 ;
  for j:=1 to num-1 do begin
   a := Angle(vx[j]-vx[j-1], vy[j]-vy[j-1]);
   d := Dist(vx[j-1],vy[j-1], vx[j],vy[j]);
   ca:= Cos(a);
   sa:= Sin(a);
   wx1:= vx[j-1] ;
   wy1:= vy[j-1] ;
   fl := True ;
   while(fl) do begin
    p := CData.zLtp[l-1].Pitch[i] - d1 ;
    if (p > d) then p := d ;
    wx2 := wx1 + p*ca ;
    wy2 := wy1 + p*sa ;
    if ((i mod 2) = 0) then begin
     Z2D(x1,y1, wx1,wy1);
     Z2D(x2,y2, wx2,wy2);
     gp.G_Line(x1,y1,x2,y2);
    end;
    wx1 := wx2 ;
    wy1 := wy2 ;
    d := d - p ;
    if (d <= LIMIT8) then begin
     fl := False ;
     d1 := d1 + p ;
    end
    else begin
     d1 := 0.0 ;
     Inc(i);
     if (i >= CData.zLtp[l-1].Segment) then i:=0;
    end;
   end;
  end;
 end;
end;
 
折線データの登録、表示については下記のようにしています。
// 折線データ登録テスト
// 表記要素/用紙上に直接
SetLength(lx,5);
SetLength(ly,5);
lx1 := 0.0 ;
ly1 := 0.0 ;
lx2 := 200.0 ;
ly2 := 150.0 ;
lx[0] := lx1 ; ly[0] := ly1 ;
lx[1] := lx2 ; ly[1] := ly1 ;
lx[2] := lx2 ; ly[2] := ly2 ;
lx[3] := lx1 ; ly[3] := ly2 ;
lx[4] := lx1 ; ly[4] := ly1 ;
CData.AddDataLines('', 1,2,2,1, 5, lx,ly);
 
// 折線データ登録テスト
// 幾何要素/部分図以下に
CData.AddDataLines('部分図A', 1,3,2,1, 5, lx,ly);
 
for i:=0 to 4 do begin
 lx[i] := Random(100);
 ly[i] := Random(100);
end;
CData.AddDataLines('', 1,3,2,1, 5, lx,ly);
 
SetLength(lx,73);
SetLength(ly,73);
lx1 := Random(100) ;
ly1 := Random(100) ;
lx2 := Random(50) + 1 ;
for i:=0 to 72 do begin
 lx[i] := lx1 + lx2*Cos(i*5/180*Pi);
 ly[i] := ly1 + lx2*Sin(i*5/180*Pi);
end;
CData.AddDataLines('', 1,4,4,1, 73, lx,ly);
 
lx := nil;
ly := nil;
 
// 折線データ表示テスト
// 表記要素/用紙上に直接
for i:=0 to CData.dLnsN-1 do begin
 with CData.dLns[i] do begin
  DisplayLines(Layer,Color,Ltype,line_width,Number,X,Y);
 end;
end;
// 折線データ表示テスト
// 幾何要素/部分図以下に
for i:=0 to CData.zFztN-1 do begin
 j := CData.FZukeiNameCheck(0,CData.zFzt[i].name) ;
 if (j = 0) then continue ;
 for k:=0 to CData.fDef[j-1].mLnsN-1 do begin
  with CData.fDef[j-1].mLns[k] do begin
   SetLength(lx,Number);
   SetLength(ly,Number);
   for l:=0 to Number-1 do begin
    MtxXY(lx[l],ly[l], X[l],Y[l], CData.zFzt[i].mtx);
   end;
   DisplayLines(Layer,Color,Ltype,line_width,Number,lx,ly);
  end;
 end;
end;
lx := nil;
ly := nil;
用紙上・部分図上に四角を登録&表示、ランダムな5頂点の折線を登録&表示、ランダムな位置に円状態の図形を登録&表示させているだけです。これをコンパイル(再構築)して実行すると、下図のようになります。

 
よく分かりませんので、用紙サイズを「B6」にして描画してみます。

更に画面を大きくすれば、より分かりやすくなると思いますが、線種の描写もうまく行っているのが分かると思います。
 
 
それでは、ここまでのテストプログラムです。実行ファイル、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.