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

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

プログラミングについて
ホームページについて
キャドについて
電子カタログについて
書籍・雑誌
イベント
リンク集
CADを考える:弧長寸法
前頁は、構造化要素の「直線寸法」について述べましたので今回は、SXF仕様書の次の構造化要素の「弧長寸法」について考えてみます。
 
弧長寸法は、平行に引き出しをする場合と放射状に引き出しをする場合がありますが、SXF仕様では、放射状に引き出すことを想定しているようです。また、弧長であることを示すために寸法値の上に円弧を作図しますが、それについては触れられていません。
寸法値は円弧状に描画する必要はなく、普通の文字と同様にまっすぐ描画すれば良いようです。まぁ、寸法値を円弧状に描画するCADソフトは少ないと思いますが、寸法値が長くなる場合は、寸法線とのバランスがいまひとつの状態になるかもしれません(円弧状に寸法値を描画すると、寸法値が長すぎて円を一回りすると寸法値の最初と最後が重なってしまう事になりますが)。
 
ここでは、SXF仕様に従った表現方法での「弧長寸法」を実装する事とします。これも修正したい場合は後で行えばいいと割り切っておきます。
 
SXF仕様書では以下のように記載されています。
構造化要素|弧長寸法

※SXF Ver.3.1仕様書より
パラメータ説明範囲
LayerIntレイヤコード
ColorInt色コード
TypeInt線種コード
line_widthInt線幅コード
sun_xdouble寸法線原点X座標 double(64bits)の
範囲(有効桁15桁)
sun_ydouble寸法線原点Y座標 double(64bits)の
範囲(有効桁15桁)
sun_radiusdouble寸法線半径0<半径<1.0×1015
sun_angle0double寸法線始角0≦ 度 <360
sun_angle1double寸法線終角0≦ 度 <360
flg2Int補助線1の有無フラグ(0:無、1:有)
ho1_x0double補助線1基点X座標 double(64bits)の
範囲(有効桁15桁)
ho1_y0double補助線1基点Y座標 double(64bits)の
範囲(有効桁15桁)
ho1_x1double補助線1始点X座標 double(64bits)の
範囲(有効桁15桁)
ho1_y1double補助線1始点Y座標 double(64bits)の
範囲(有効桁15桁)
ho1_x2double補助線1終点X座標 double(64bits)の
範囲(有効桁15桁)
ho1_y2double補助線1終点Y座標 double(64bits)の
範囲(有効桁15桁)
flg3Int補助線2の有無フラグ(0:無、1:有)
ho2_x0double補助線2基点X座標 double(64bits)の
範囲(有効桁15桁)
ho2_y0double補助線2基点Y座標 double(64bits)の
範囲(有効桁15桁)
ho2_x1double補助線2始点X座標 double(64bits)の
範囲(有効桁15桁)
ho2_y1double補助線2始点Y座標 double(64bits)の
範囲(有効桁15桁)
ho2_x2double補助線2終点X座標 double(64bits)の
範囲(有効桁15桁)
ho2_y2double補助線2終点Y座標 double(64bits)の
範囲(有効桁15桁)
arr1_code1Int始点側矢印コード
arr1_code2Int始点側矢印内外コード(0:なし,1:外向き,2:内向き)
arr1_xdouble始点側矢印配置点X座標 double(64bits)の
範囲(有効桁15桁)
arr1_ydouble始点側矢印配置点Y座標 double(64bits)の
範囲(有効桁15桁)
arr1_rdouble始点側矢印配置倍率0<倍率<1.0×1015
arr2_code1Int終点側矢印コード
arr2_code2Int終点側矢印内外コード(0:なし,1:外向き,2:内向き)
arr2_xdouble終点側矢印配置点X座標 double(64bits)の
範囲(有効桁15桁)
arr2_ydouble終点側矢印配置点Y座標 double(64bits)の
範囲(有効桁15桁)
arr2_rdouble終点側矢印配置倍率0<倍率<1.0×1015
flg4Int寸法値の有無フラグ(0:無、1:有)
FontInt文字フォントコード
str[257]Char文字列0<文字列長≦256バイト
text_xdouble文字列配置基点X座標 double(64bits)の
範囲(有効桁15桁)
text_ydouble文字列配置基点Y座標 double(64bits)の
範囲(有効桁15桁)
Heightdouble文字範囲高0<高さ<1.0×1015
Widthdouble文字範囲幅0< 幅 <1.0×1015
Spcdouble文字間隔0≦間隔<1.0×1015
Angledouble文字列回転角0≦ 度 <360
Slantdoubleスラント角度-85≦ 度 ≦85
b_pntInt文字配置基点(1:左下,2:中下,3:右下,4:左中,5:中中,6:右中,7:左上,8:中上,9:右上)
DirectInt文字書出し方向(1:横書き, 2:縦書き)
備考
・矢印コードは、1: blanked arrow, 2: blanked box, 3: blanked dot, 4: dimension origin, 5: filled box, 6: filled arrow, 7: filled dot, 8: integral symbol, 9: open arrow, 10: slash, 11: unfilled arrowから選ぶ。矢印の形状は直線寸法の補足を参照のこと。
・矢印の大きさは、用紙座標系で解釈する。
・補助線の基点、始点、終点は一直線上に存在しなければならない。
・角度は水平右側が0度、反時計廻りが正、単位は度とする。
・寸法線始角と寸法線終角が同じときは円周を示す寸法線とする。
・個別に、寸法線(狭義)、補助線、文字、矢印の色、線幅、線種を設定することはできない。
 
データ構造は上記の表をそのまま採用し、下記のようにします。
UnitData.pas
type
 ・・・
 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)
  sun_x : double ;     // 寸法線原点X座標
  sun_y : double ;     // 寸法線原点Y座標
  sun_radius : double ;  // 寸法線半径
  sun_angle0 : double ;  // 寸法線始角[°]
  sun_angle1 : double ;  // 寸法線終角[°]
  flg2 : integer ;     // 補助線1の有無フラグ(0:無、1:有)
  ho1_x0 : double ;    // 補助線1基点X座標
  ho1_y0 : double ;    // 補助線1基点Y座標
  ho1_x1 : double ;    // 補助線1始点X座標
  ho1_y1 : double ;    // 補助線1始点Y座標
  ho1_x2 : double ;    // 補助線1終点X座標
  ho1_y2 : double ;    // 補助線1終点Y座標
  flg3 : integer ;     // 補助線2の有無フラグ(0:無、1:有)
  ho2_x0 : double ;    // 補助線2基点X座標
  ho2_y0 : double ;    // 補助線2基点Y座標
  ho2_x1 : double ;    // 補助線2始点X座標
  ho2_y1 : double ;    // 補助線2始点Y座標
  ho2_x2 : double ;    // 補助線2終点X座標
  ho2_y2 : double ;    // 補助線2終点Y座標
  arr1_code1 : integer ;  // 始点側矢印コード(1-11)
  arr1_code2 : integer ;  // 始点側矢印内外コード
  arr1_x : double ;    // 始点側矢印配置点X座標
  arr1_y : double ;    // 始点側矢印配置点Y座標
  arr1_r : double ;    // 始点側矢印配置倍率
  arr2_code1 : integer ;  // 終点側矢印コード(1-11)
  arr2_code2 : integer ;  // 終点側矢印内外コード
  arr2_x : double ;    // 終点側矢印配置点X座標
  arr2_y : double ;    // 終点側矢印配置点Y座標
  arr2_r : double ;    // 終点側矢印配置倍率
  flg4 : integer ;     // 寸法値の有無フラグ(0:無、1:有)
  Font : Integer ;     // 文字フォントコード
  str : string ;      // 文字列 (最大256バイト)
  text_x : double ;    // 文字列配置基点X座標
  text_y : double ;    // 文字列配置基点Y座標
  Height : double ;    // 文字範囲高
  Width : double ;     // 文字範囲幅
  Spc : double ;      // 文字間隔
  Angle : double ;     // 文字列回転角[°]
  Slant : double ;     // スラント角[°]
  b_pnt : Integer ;    // 文字配置基点 (1-9)
  Direct : Integer ;    // 文字書出し方向(1,2)
 end;
 ・・・
データ追加用の関数は、少し長いですが
function AddDataDimArc(s,st:string;lay,col,ltp,wid,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 ;
のようにします。線分・折線等と同様、最初に「データ追加先の複合図形名/シンボル名 null:用紙へ追加」を指定するようにしています。
 
UnitData.pas
// 弧長寸法 データ項目の追加登録
function TDataClass.AddDataDimArc(s,st:string;lay,col,ltp,wid,
 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 ;
var
 m : integer ;
 a1,a2,w1,w2 : double ;
begin
 Result := False;
 if (st = '') then
  f4 := 0
 else
  if not(StrCheck(st)) then exit; // 文字列数チェック
 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 (f2 <> 0) then f2 := 1;
 if (f3 <> 0) then f3 := 1;
 if (f4 <> 0) then f4 := 1;
 if (ar11 < 1)or(ar11 > 11) then ar11 := 9;
 if (ar21 < 1)or(ar21 > 11) then ar21 := 9;
 if (ar12 < 0)or(ar12 > 2) then ar12 := 2;
 if (ar22 < 0)or(ar22 > 2) then ar22 := 2;
 if (ar1r < LIMIT8) then ar1r := 1.0;
 if (ar2r < LIMIT8) then ar2r := 1.0;
 if (sr < LIMIT8) then exit ;
 sa0 := SetAngle(sa0);
 sa1 := SetAngle(sa1);
 if (f4 = 1)and( (th < LIMIT10)or(tw < LIMIT10) ) then exit ;
 if (fnt < 0) or (fnt > zFntN) then fnt := 0 ;
 if (bp < 1) or (bp > 9) then bp := 2 ; // 中下
 if (dir <> 1) then dir := 2 ;
 if (ts < 0.0) then ts := 0.0;
 an := SetAngle(an);
 if (sl < -85.0) or (sl > 85.0) then sl := 0.0;
 // 座標チェック
 if (SamePosCheck(h1x1,h1y1, h1x2,h1y2)) then f2 := 0 ;
 if (SamePosCheck(h2x1,h2y1, h2x2,h2y2)) then f3 := 0 ;
 // 補助線の1直線上チェック
 if (f2 = 1) then begin
  a1 := dAngle((h1x1-h1x0),(h1y1-h1y0));
  a2 := dAngle((h1x2-h1x0),(h1y2-h1y0));
  a2 := SetAngle(a1-a2) ;
  if (Abs(a2) > LIMIT10) then begin
   dRev(w1,w2, h1x2,h1y2, h1x0,h1y0, -a1);
   if (Abs(w1-h1x0) < LIMIT10) then
    f2 := 0
   else
    dRev(h1x2,h1y2, w1,h1y0, h1x0,h1y0, a1);
  end;
 end;
 if (f3 = 1) then begin
  a1 := dAngle((h2x1-h2x0),(h2y1-h2y0));
  a2 := dAngle((h2x2-h2x0),(h2y2-h2y0));
  a2 := SetAngle(a1-a2) ;
  if (Abs(a2) > LIMIT10) then begin
   dRev(w1,w2, h2x2,h2y2, h2x0,h2y0, -a1);
   if (Abs(w1-h2x0) < LIMIT10) then
    f3 := 0
   else
    dRev(h2x2,h2y2, w1,h2y0, h2x0,h2y0, a1);
  end;
 end;
 //
 if (s = '') then begin
  // 用紙へ追加
  ・・・
 
これで弧長寸法データの登録は出来るようになりましたので次は描画についてです。これは単純に、円弧1つ・線分2つ・矢印2つ・文字1つ描画するだけですので別段問題は無いでしょう。矢印の傾きは、多少アバウトな算出方法ですが。
 
UnitDataGraph.pas
// 弧長寸法の表示
procedure DisplayDimArc(lay,col,ltp,wid,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);
var
 lx1,ly1,lx2,ly2,lx3,ly3, aa : double ;
begin
 // 寸法線
 DisplayArc(lay,col,ltp,wid, 0, sx,sy,sr,sa0,sa1,t);
 // 補助線1
 if (f2 = 1) then begin
  MtxXY(lx1,ly1, h1x1,h1y1, t);
  MtxXY(lx2,ly2, h1x2,h1y2, t);
  DisplayLine(lay,col,ltp,wid, lx1,ly1,lx2,ly2);
 end;
 // 補助線2
 if (f3 = 1) then begin
  MtxXY(lx1,ly1, h2x1,h2y1, t);
  MtxXY(lx2,ly2, h2x2,h2y2, t);
  DisplayLine(lay,col,ltp,wid, lx1,ly1,lx2,ly2);
 end;
 // 矢印1
 aa := dAngle(ar1x-sx,ar1y-sy);
 if (ar12 = 2) then
  aa := (aa+5.0)/180.0*Pi
 else
  aa := (aa-5.0)/180.0*Pi ;
 if (ar12 > 0) then begin
  MtxXY(lx1,ly1, ar1x,ar1y, t);
  lx2 := sx + sr*Cos(aa);
  ly2 := sy + sr*Sin(aa);
  MtxXY(lx3,ly3, lx2,ly2, t);
  aa := Angle(lx3-lx1,ly3-ly1);
  DisplayArrow(lay,col,ar11,lx1,ly1,aa,ar1r);
 end;
 // 矢印2
 aa := dAngle(ar2x-sx,ar2y-sy);
 if (ar22 = 2) then
  aa := (aa-5.0)/180.0*Pi
 else
  aa := (aa+5.0)/180.0*Pi ;
 if (ar22 > 0) then begin
  MtxXY(lx1,ly1, ar2x,ar2y, t);
  lx2 := sx + sr*Cos(aa);
  ly2 := sy + sr*Sin(aa);
  MtxXY(lx3,ly3, lx2,ly2, t);
  aa := Angle(lx3-lx1,ly3-ly1);
  DisplayArrow(lay,col,ar21,lx1,ly1,aa,ar2r);
 end;
 // 寸法値
 if (f4 = 1) then begin
  DisplayText(lay,col,fnt,bp,dir, tx,ty,th,tw,ts,an,sl,st,t);
 end;
end;
 
※文字の描画で、文字の傾きを表現するのに、左下点を基準にしていましたが、配置点(基点)を基準にしたほうが良いように思えてきましたので、少し修正(パッチ当て)をしておきます。多少強引に修正していますが…
 

 
それでは、ここまでのテストプログラムです。実行ファイル、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.