


 
 
 
 
 
 
 |
前頁は、シンボル、構造化要素の「既定義シンボル」について述べました。SXF仕様書の次は構造化要素の「直線寸法」となっていますが、その前に、寸法線等で利用する矢印について考えておきます。
SXF仕様書では、矢印データ要素というものはありません。寸法線データ要素でも「矢印コード」とあるだけです。矢印の形状は固定化されていますが。しかしながら幾つかのCADソフトでは、矢印データ要素というものを実装しているものはあります。例えば、Jw_cadでは点マーカとして実装しています。またAutoCADでは、ブロック図形として実装しているようです。矢印形状は寸法線だけで使う訳ではありません。単なる矢印の線というのは、例えば、フローチャートやグラフ等でよく利用します。
例えば、矢印線作図コマンドを作った場合、線分と先端の矢印を作図させる事になりますが、矢印が「<」であるとすれば、線分2本を作図すれば可能です。「○」の場合には円を作図すれば可能です。が、最初から矢印データ要素というものがあれば、それを利用したほうが遥かに簡単です。また、矢印を使うコマンドが他にも幾つかある場合には、プログラミングの省力化や、仕様の統一化を図れます。
という訳で、SXF仕様とは独自に、表記要素/幾何要素と同じレベルで矢印データ要素というのを実装する事にします。ただ、SXFファイル等として保存する場合には、線分・円・円弧・ハッチング(塗り)に分解され、それを開いた場合には、矢印データ要素として認識出来なくなるであろう、という事は想定しておきます。複合図形化するとしても同様です。
SXF仕様書では下図のように記載されています。
※SXF Ver.3.1仕様書より
矢印コードは上記の1〜11をそのまま使います。矢印の大きさは SXF仕様の直線寸法等の備考で
とありますのでこれを考慮します。
矢印の角度は「<」の状態を角度0°とします(上図は角度180°状態)。
独自に定義するのだから、上記以外の矢印も利用出来るようにする、というパターンもありますが、それをすると直線寸法等での矢印の利用がSXF仕様ネイティブ的に出来なくなります。矢印を無し状態にして、別途、拡張した矢印を作図させるという手法も有り得ますが、寸法線と矢印がバラバラ状態になってしまうので、それは避けたい、というのがあるかもしれません。また、何らかの関連付けを行い、バラバラにならないようにする、という手法もあるかもしれません。
色々と考えられますが、ここではシンプルに行きます。
それでは矢印のデータ構造を決めます。
UnitData.pas |
type
・・・
TDataArrow = record // 独自|幾何要素/表記要素|矢印
exf : Boolean ; // 存在フラグ(True:有り False:無し)
Layer : Integer ; // レイヤ(1〜256)
Color : Integer ; // 色 (0:レイヤ色 1〜256)
start_x : double ; // 配置点X座標
start_y : double ; // 配置点Y座標
arrow_code : Integer ; // 矢印コード
rotate_angle : double ; // 回転角[°]
Scale : double ; // 尺度
end; |
データ追加用の関数は
function AddDataArrow(s:string;lay,col,ac:integer;
px,py,an,sc:double) : Boolean; |
のようにします。線分・折線等と同様、最初に「データ追加先の複合図形名(幾何要素) null:用紙へ追加(表記要素)」を指定するようにしています。点マーカの登録用関数を少し修正すれば出来上がりです。
UnitData.pas |
// 矢印 データ項目の追加登録
function TDataClass.AddDataArrow(s:string;lay,col,ac:integer;px,py,an,sc:double) : Boolean;
var
m : integer ;
begin
Result := False;
if (lay < 1) or (lay > zLayN) then lay := 1 ;
if (col < 0) or (col > zColN) then col := 0 ;
if (ac < 1) or (ac > 11) then ac := 9 ; // open arrow
an := SetAngle(an);
if (sc < LIMIT8) then sc := 1.0;
if (s = '') then begin
// 用紙へ追加
if (AddDataOrder(0,13,dArwN)) then begin
try
Inc(dArwN);
if ((dArwN mod 200) = 1) then SetLength(dArw, dArwN+199);
with dArw[dArwN-1] do begin
exf := True ;
Layer := lay ;
Color := col ;
start_x := px ;
start_y := py ;
arrow_code := ac ;
rotate_angle:= an ;
Scale := sc ;
end;
Result := True ;
AddLayerCnt(lay,col,-1,-1,-1);
except
Dec(dArwN);
Dec(dOrdN);
end;
end;
end
else begin
m := FZukeiNameCheck(0,s);
if (m > 0) then begin
with fDef[m-1] do begin
if (AddDataOrder(m,13,mArwN)) then begin
try
Inc(mArwN);
if ((mArwN mod 200)=1) then SetLength(mArw, mArwN+199);
with mArw[mArwN-1] do begin
exf := True ;
Layer := lay ;
Color := col ;
start_x := px ;
start_y := py ;
arrow_code := ac ;
rotate_angle:= an ;
Scale := sc ;
end;
Result := True ;
AddLayerFCnt(lay,col,-1,-1,-1);
except
Dec(mArwN);
Dec(mOrdN);
end;
end;
end;
end
else if (m < 0) then begin
with sDef[-m-1] do begin
if (AddDataOrder(m,13,mArwN)) then begin
try
Inc(mArwN);
if ((mArwN mod 200)=1) then SetLength(mArw, mArwN+199);
with mArw[mArwN-1] do begin
exf := True ;
Layer := lay ;
Color := col ;
start_x := px ;
start_y := py ;
arrow_code := ac ;
rotate_angle:= an ;
Scale := sc ;
end;
Result := True ;
except
Dec(mArwN);
Dec(mOrdN);
end;
end;
end;
end;
end;
end; |
これで矢印データの登録は出来るようになりましたので次は矢印の描画についてです。UnitClipping.pas に大まかなクリッピングテストをするための関数 Clip1xyaPoint() を追加しています。また、塗り潰し図形の描画のために、UnitGraph.pasに G_Polygon()手続きを追加しています。本来はこの手続きで描画する前にクリッピング処理を施さないといけないのですが今回は省略しています。
円の塗り潰しは、24分割の内接正多角形として描画をするようにしています。
UnitDataGraph.pas |
// 矢印の表示
// an : 回転角[rad]
procedure DisplayArrow(lay,col,ac:integer;px,py,an,sc:double);
var
sx,sy : double ;
c,cc : integer ;
w1,w2,w3,w4,w5,w6 : double ;
pt : array of TPointD ;
i : integer ;
begin
// クリッピングチェック
w1 := px ;
w2 := py ;
sx := 2.5*sc ;
sy := sx ;
if (ac = 1)or(ac = 6)or(ac = 9)or(ac = 11) then begin
w1 := px + 7.5/2.0*sc*Cos(an);
w2 := py + 7.5/2.0*sc*Sin(an);
sx := 7.5*sc ;
end
else if (ac = 8)or(ac = 10) then begin
sx := 2.5*Sqrt(2.0);
sy := sx ;
end;
if (Clip1xyaPoint(w1,w2,sx,sy,an, WndX1,WndY1,WndX2,WndY2) = 2) then exit;
//
DisplayLayCol1(lay,col,c,cc); // 色
gp.G_SetWidth(1);
//
case(ac)of
1: begin // blanked arrow
SetLength(pt,4);
pt[0].x := px ;
pt[0].y := py ;
w5 := px + 7.5 *sc ;
w6 := py + 1.25*sc ;
Rev(pt[1].x,pt[1].y, w5,w6, px,py, an);
w5 := px + 7.5 *sc ;
w6 := py - 1.25*sc ;
Rev(pt[2].x,pt[2].y, w5,w6, px,py, an);
pt[3].x := pt[0].x ;
pt[3].y := pt[0].y ;
gp.G_SetPen(BackCol);
DisplayPolygon(3,pt);
gp.G_SetPen(cc);
for i:=0 to 2 do
DisplayLineSub1(pt[i].x,pt[i].y, pt[i+1].x,pt[i+1].y);
pt := nil;
end;
2: begin // blanked box
SetLength(pt,5);
w5 := px - 1.25*sc ;
w6 := py - 1.25*sc ;
Rev(pt[0].x,pt[0].y, w5,w6, px,py, an);
w5 := px + 1.25*sc ;
w6 := py - 1.25*sc ;
Rev(pt[1].x,pt[1].y, w5,w6, px,py, an);
w5 := px + 1.25*sc ;
w6 := py + 1.25*sc ;
Rev(pt[2].x,pt[2].y, w5,w6, px,py, an);
w5 := px - 1.25*sc ;
w6 := py + 1.25*sc ;
Rev(pt[3].x,pt[3].y, w5,w6, px,py, an);
pt[4].x := pt[0].x ;
pt[4].y := pt[0].y ;
gp.G_SetPen(BackCol);
DisplayPolygon(4,pt);
gp.G_SetPen(cc);
for i:=0 to 3 do
DisplayLineSub1(pt[i].x,pt[i].y, pt[i+1].x,pt[i+1].y);
pt := nil;
end;
3: begin // blanked dot
SetLength(pt,25);
w1 := 2.0*Pi/24 ;
for i:=0 to 24 do begin
pt[i].x := px + 1.25*sc*Cos(i*w1);
pt[i].y := py + 1.25*sc*Sin(i*w1);
end;
gp.G_SetPen(BackCol);
DisplayPolygon(23,pt);
gp.G_SetPen(cc);
for i:=0 to 23 do
DisplayLineSub1(pt[i].x,pt[i].y, pt[i+1].x,pt[i+1].y);
pt := nil;
end;
4: begin // dimension origin
SetLength(pt,25);
w1 := 2.0*Pi/24 ;
for i:=0 to 24 do begin
pt[i].x := px + 1.25*sc*Cos(i*w1);
pt[i].y := py + 1.25*sc*Sin(i*w1);
end;
for i:=0 to 23 do
DisplayLineSub1(pt[i].x,pt[i].y, pt[i+1].x,pt[i+1].y);
pt := nil;
end;
5: begin // filled box
SetLength(pt,5);
w5 := px - 1.25*sc ;
w6 := py - 1.25*sc ;
Rev(pt[0].x,pt[0].y, w5,w6, px,py, an);
w5 := px + 1.25*sc ;
w6 := py - 1.25*sc ;
Rev(pt[1].x,pt[1].y, w5,w6, px,py, an);
w5 := px + 1.25*sc ;
w6 := py + 1.25*sc ;
Rev(pt[2].x,pt[2].y, w5,w6, px,py, an);
w5 := px - 1.25*sc ;
w6 := py + 1.25*sc ;
Rev(pt[3].x,pt[3].y, w5,w6, px,py, an);
pt[4].x := pt[0].x ;
pt[4].y := pt[0].y ;
DisplayPolygon(4,pt);
for i:=0 to 3 do
DisplayLineSub1(pt[i].x,pt[i].y, pt[i+1].x,pt[i+1].y);
pt := nil;
end;
6: begin // filled arrow
SetLength(pt,4);
pt[0].x := px ;
pt[0].y := py ;
w5 := px + 7.5 *sc ;
w6 := py + 1.25*sc ;
Rev(pt[1].x,pt[1].y, w5,w6, px,py, an);
w5 := px + 7.5 *sc ;
w6 := py - 1.25*sc ;
Rev(pt[2].x,pt[2].y, w5,w6, px,py, an);
pt[3].x := pt[0].x ;
pt[3].y := pt[0].y ;
DisplayPolygon(3,pt);
for i:=0 to 2 do
DisplayLineSub1(pt[i].x,pt[i].y, pt[i+1].x,pt[i+1].y);
pt := nil;
end;
7: begin // filled dot
SetLength(pt,25);
w1 := 2.0*Pi/24 ;
for i:=0 to 24 do begin
pt[i].x := px + 1.25*sc*Cos(i*w1);
pt[i].y := py + 1.25*sc*Sin(i*w1);
end;
DisplayPolygon(23,pt);
for i:=0 to 23 do
DisplayLineSub1(pt[i].x,pt[i].y, pt[i+1].x,pt[i+1].y);
pt := nil;
end;
8: begin // integral symbol
SetLength(pt,25);
w1 := Pi/2.0/12 ;
for i:=0 to 12 do begin
w5 := px-sx/2.0 + sx/2.0*Cos(1.5*Pi+i*w1);
w6 := py + sx/2.0*Sin(1.5*Pi+i*w1);
Rev(pt[i].x,pt[i].y, w5,w6, px,py, an);
end;
for i:=1 to 12 do begin
w5 := px+sx/2.0 + sx/2.0*Cos(Pi-i*w1);
w6 := py + sx/2.0*Sin(Pi-i*w1);
Rev(pt[i+12].x,pt[i+12].y, w5,w6, px,py, an);
end;
for i:=0 to 23 do
DisplayLineSub1(pt[i].x,pt[i].y, pt[i+1].x,pt[i+1].y);
pt := nil;
end;
9: begin // open arrow
w1 := px ;
w2 := py ;
w5 := px + 7.5 *sc ;
w6 := py + 1.25*sc ;
Rev(w3,w4, w5,w6, px,py, an);
DisplayLineSub1(w1,w2, w3,w4);
w5 := px + 7.5 *sc ;
w6 := py - 1.25*sc ;
Rev(w3,w4, w5,w6, px,py, an);
DisplayLineSub1(w1,w2, w3,w4);
end;
10:begin // slash
w5 := px - sx/2.0 ;
w6 := py - sx/2.0 ;
Rev(w1,w2, w5,w6, px,py, an);
w5 := px + sx/2.0 ;
w6 := py + sx/2.0 ;
Rev(w3,w4, w5,w6, px,py, an);
DisplayLineSub1(w1,w2, w3,w4);
end;
11:begin // unfilled arrow
SetLength(pt,4);
pt[0].x := px ;
pt[0].y := py ;
w5 := px + 7.5 *sc ;
w6 := py + 1.25*sc ;
Rev(pt[1].x,pt[1].y, w5,w6, px,py, an);
w5 := px + 7.5 *sc ;
w6 := py - 1.25*sc ;
Rev(pt[2].x,pt[2].y, w5,w6, px,py, an);
pt[3].x := pt[0].x ;
pt[3].y := pt[0].y ;
for i:=0 to 2 do
DisplayLineSub1(pt[i].x,pt[i].y, pt[i+1].x,pt[i+1].y);
pt := nil;
end;
end;
end; |

それでは、ここまでのテストプログラムです。実行ファイル、gdiplus.dll、gdipフォルダは入っていません。ソースのみです。
|
|
CAD装置(1)
CAD装置(2)
メディア
AutoCADの
DIESELマクロ
CSV
DXF
PCES
IGES
STEP
数学とCAD
CAD作ろ!
CADを考える
▲PREV
▼NEXT
M7
Jw_cad
|