前頁から構造化要素のハッチング(パターン)について考えていますが、今回はその続きです。
ハッチング(パターン)で使用するシンボル図形は自分で作成するのですが、SXF仕様では、SXFで定義されている既定義シンボルがあります。「SXF Ver.3.1仕様書・同解説共通既定義要素編.pdf」のP.6「1 既定義要素の仕様〜1-5 既定義シンボル」に記載されている、「馬踏み sxf_hatch_style_7_symbol」及び「45度重ねあじろ sxf_hatch_style_8_symbol」です。
1 既定義要素の仕様
1-5 既定義シンボル
シンボル名 | 値(name) | 説明 |
馬踏み | sxf_hatch_style_7_symbol | |
45度
重ねあじろ | sxf_hatch_style_8_symbol | |
備考 | |
・「部分図及び作図部品」に含まれる場合、その「尺度と回転角」の影響を受ける。
・上記シンボル(シンボルコードを含む)は、ハッチング(パターン)としての用途のみを想定して例示したものである。
・この他のシンボルについては、将来的に各分野で策定されることが予想され、用途に応じた適切なシンボルコードの交換機能、及びシンボル・ハッチングとしての表示機能を有していることが望ましい。 |
|
2つしか無いのに何故,値が_7_、_8_となっているのか?については、ハッチング(5)にも記載しましたが、少し古い仕様である SXF仕様 Ver.2の頃の文書ファイル「sxfv2shiyouR541extra1.pdf」でのハッチング(既定義(外部定義))にて、sxf_hatch_style_1〜sxf_hatch_style_6が定義されていて、「煉瓦模様 sxf_hatch_style_7」「布織模様 sxf_hatch_style_8」が定義されており、そのためのシンボル定義 sxf_hatch_style_7_symbol、sxf_hatch_style_8_symbol であるという事が分かります。新しい仕様だけをぱっと見ても分からない、以前からの経緯を知ってみると理解出来る、というのは、こういう規格の話ではよくある事のようです。
ここではまず、上記2つの既定義シンボルを定義する事から考えます。まずは下記のコードを追加します。
UnitData.pas |
// シンボル定義データ 初期値セット
procedure TDataClass.DataInitSymbol ;
var
a : double ;
begin
sDef := nil;
sDefN := 0;
AddSymbolDef('sxf_hatch_style_7_symbol');
AddDataLine( 'sxf_hatch_style_7_symbol',
1,0,0,0, 0.0, 0.0, 200.0, 0.0);
AddDataLine( 'sxf_hatch_style_7_symbol',
1,0,0,0, 200.0, 0.0, 200.0,100.0);
AddDataLine( 'sxf_hatch_style_7_symbol',
1,0,0,0, 200.0,100.0, 0.0,100.0);
AddDataLine( 'sxf_hatch_style_7_symbol',
1,0,0,0, 100.0,100.0, 100.0,200.0);
a := 100.0*Cos(45.0/180.0*Pi);
AddSymbolDef('sxf_hatch_style_8_symbol');
AddDataLine( 'sxf_hatch_style_8_symbol',
1,0,0,0, 0.0 ,0.0 , a, a);
AddDataLine( 'sxf_hatch_style_8_symbol',
1,0,0,0, 2.0*a,0.0 , 0.0 ,2.0*a);
AddDataLine( 'sxf_hatch_style_8_symbol',
1,0,0,0, 0.0 ,2.0*a, 2.0*a,4.0*a);
AddDataLine( 'sxf_hatch_style_8_symbol',
1,0,0,0, 2.0*a,4.0*a, 3.0*a,3.0*a);
AddDataLine( 'sxf_hatch_style_8_symbol',
1,0,0,0, 3.0*a,3.0*a, 4.0*a,4.0*a);
AddDataLine( 'sxf_hatch_style_8_symbol',
1,0,0,0, 4.0*a,0.0 , 1.0*a,3.0*a);
AddDataLine( 'sxf_hatch_style_8_symbol',
1,0,0,0, 3.0*a,1.0*a, 4.0*a,2.0*a);
end; |
Unit1.pasにて下記を追加します。これは DataClearSymbolで 既定義シンボルも消してしまうので、再定義するためです。
UnitData.pas |
// [描画]
procedure TForm1.Button8Click(Sender: TObject);
・・・
with CData do begin
・・・
// シンボル定義
DataClearSymbol ;
DataInitSymbol ;
AddSymbolDef('シンボルA');
・・・ |
利用例です。
UnitData.pas |
// パターン
CData.AddDataHatch4('' ,'sxf_hatch_style_7_symbol',
1,2, 50.0,50.0, 20,0, 20,90, 0.1,0.1,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','sxf_hatch_style_7_symbol',
1,2, 50.0,50.0, 20,0, 20,90, 0.1,0.1,0.0, 1,3,[2,3,4]); |
「馬踏み sxf_hatch_style_7_symbol」のパターンの大きさは 200×200で、このテストでは大きいため、縦横0.1倍にしています。パターンベクトルの大きさもそれに合わせて20,20にしています。実行すると下記のような感じになります。
UnitData.pas |
// パターン
lx1 := 20.0*Sqrt(2.0);
CData.AddDataHatch4('' ,'sxf_hatch_style_8_symbol',
1,2, 50.0,50.0, lx1,0, lx1,90, 0.1,0.1,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','sxf_hatch_style_8_symbol',
1,2, 50.0,50.0, lx1,0, lx1,90, 0.1,0.1,0.0, 1,3,[2,3,4]); |
「45度重ねあじろ sxf_hatch_style_8_symbol」のパターンの大きさは 200√2×200√2で、このテストでは大きいため、縦横0.1倍にしています。パターンベクトルの大きさもそれに合わせて20√2,20√2にしています。実行すると下記のような感じになります。
次に、シンボル図形内の折線・円・円弧・楕円・楕円弧・スプライン曲線・クロソイド曲線について、それぞれ線分に分解を行った状態にして、描画を出来るようにします。但しこれらを使用した場合、線数がかなり多くなりますので使用については注意が必要となります(前頁で述べたように、線数が多くなり過ぎて完全にハッチング出来ない状態になる可能性があります)。また、線分に分解されるため線種の連続性は失われます。そのため、線種を指定しているのに思ったように描画されない、という事になりますので注意して下さい。
UnitData.pas |
// ハッチング(パターン) ハッチング線の算出
// n : パターン=シンボル図形 番号(-1〜)
// col : 線色コード
// px : ハッチパターン配置位置X座標
// py : ハッチパターン配置位置Y座標
// pv1 : ハッチパターンの繰返しベクトル1の大きさ
// pv1a : ハッチパターンの繰返しベクトル1の角度[°]
// pv2 : ハッチパターンの繰返しベクトル2の大きさ
// pv2a : ハッチパターンの繰返しベクトル2の角度[°]
// psx : ハッチパターンのX尺度
// psy : ハッチパターンのY尺度
// pa : ハッチパターンの向きの角度[°]
// (ret)
// zHLn, zHLnN
procedure TDataClass.MakeHatch4(n,col:integer;
px,py,pv1,pv1a,pv2,pv2a,psx,psy,pa:double) ;
var
tr,tr1 : TMatrix ;
i,o,o1,o2 : integer ;
wx1,wy1,wx2,wy2 : double ;
n1,n2,w1,w2,w3,w4,w5,w6,lx1,ly1,lx2,ly2 : double ;
ltp,wid : integer ;
begin
zHLn := nil ;
zHLnN:= 0 ;
if (n >= 0) then exit;
// min,maxを取得
with zHAr[0] do begin
wx1 := a[0].x ;
wy1 := a[0].y ;
wx2 := wx1;
wy2 := wy1;
for i:=1 to an-1 do begin
if (wx1 > a[i].x) then wx1 := a[i].x ;
if (wy1 > a[i].y) then wy1 := a[i].y ;
if (wx2 < a[i].x) then wx2 := a[i].x ;
if (wy2 < a[i].y) then wy2 := a[i].y ;
end;
end;
//
w5 := pv1a/180.0*Pi ;
w6 := pv2a/180.0*Pi ;
w1 := pv2*Cos(w6-w5);
w2 := pv2*Sin(w6-w5);
w3 := pv1*Cos(w5-w6);
w4 := pv1*Sin(w5-w6);
//
// 変換行列を作成
MtxScale(tr, psx,psy);
MtxRotD(tr1, pa);
tr := MtxMult(tr,tr1) ;
MtxMove(tr1, px,py) ;
tr := MtxMult(tr,tr1) ;
ltp := 0 ;
wid := 0 ;
//
with sDef[-n-1] do begin
for o:=0 to mOrdN-1 do begin
o1 := mOrd[o].DataType ;
o2 := mOrd[o].DataNo ;
case (o1) of
2: begin
// 線分データ
with mLin[o2] do begin
ltp := Ltype ;
wid := line_width ;
MtxXY(lx1,ly1, start_x,start_y, tr);
MtxXY(lx2,ly2, end_x ,end_y , tr);
end;
MakeHatch4sub(col,ltp,wid, lx1,ly1,lx2,ly2,
wx1,wy1,wx2,wy2, pv1,w5,pv2,w6,w2,w4) ;
end;
3: begin
// 折線データ表示
with mLns[o2] do begin
ltp := Ltype ;
wid := line_width ;
TransLinesToLines(Number,X,Y,tr);
end;
end;
4: begin
// 円データ表示
with mCir[o2] do begin
ltp := Ltype ;
wid := line_width ;
TransCircleToLines(sep,Center_x,Center_y,Radius,tr);
end;
end;
5: begin
// 円弧データ表示
with mArc[o2] do begin
ltp := Ltype ;
wid := line_width ;
TransArcToLines(sep,Direction,Center_x,Center_y,Radius,
start_angle,end_angle,tr);
end;
end;
6: begin
// 楕円データ表示
with mEll[o2] do begin
ltp := Ltype ;
wid := line_width ;
TransEllipseToLines(sep,Center_x,Center_y,Radius_x,Radius_y,
rotation_angle,tr);
end;
end;
7: begin
// 楕円弧データ表示
with mEAr[o2] do begin
ltp := Ltype ;
wid := line_width ;
TransEllipseArcToLines(sep,Direction,Center_x,Center_y,
Radius_x,Radius_y,rotation_angle,start_angle,end_angle,tr);
end;
end;
9: begin
// ベジェ曲線データ表示
with mBez[o2] do begin
ltp := Ltype ;
wid := line_width ;
TransBezierToLines(sep,Number,X,Y,tr);
end;
end;
10:begin
// Bスプライン曲線データ表示
with mBsp[o2] do begin
ltp := Ltype ;
wid := line_width ;
TransBsplineToLines(open_close,sep,Number,X,Y,tr);
end;
end;
11:begin
// スプライン曲線データ表示
with mSpl[o2] do begin
ltp := Ltype ;
wid := line_width ;
TransSplineToLines(Stype,open_close,sep,Number,Aval,X,Y,tr);
end;
end;
12:begin
// クロソイド曲線データ表示
with mClo[o2] do begin
ltp := Ltype ;
wid := line_width ;
TransClothoidToLines(Direction,sep, base_x,base_y,Aval,
Angle,start_length,end_length,tr);
end;
end;
end;
if (o1 >= 3)and(o1 <= 7)or(o1 >= 9)and(o1 <= 12) then begin
if (tLnsN > 0) then begin
for i:=0 to tLnsN-2 do begin
MakeHatch4sub(col,ltp,wid,
tLns[i].x,tLns[i].y, tLns[i+1].x,tLns[i+1].y,
wx1,wy1,wx2,wy2, pv1,w5,pv2,w6,w2,w4) ;
end;
end;
TransLnsClear ; // 連続線分データクリア
end;
end;
end;
SetLength(zHLn, zHLnN);
zHCp := nil;
zHCpN:= 0;
end; |
それでは、ハッチング(パターン)の登録・描画のテストです。
Unit1.pas |
CData.AddSymbolDef('シンボルB');
CData.AddDataLines('シンボルB', 1,1,1,1, 4, [0,10,5,0],[0,0,8,0]);
CData.AddDataHatch4('' ,'シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]); |
Unit1.pas |
CData.AddSymbolDef('シンボルB');
CData.AddDataCircle('シンボルB', 1,1,1,1, 36, 0.0,0.0,5.0);
CData.AddDataHatch4('' ,'シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]); |
Unit1.pas |
CData.AddSymbolDef('シンボルB');
CData.AddDataArc('シンボルB', 1,1,1,1, 18,0, 0.0,0.0,5.0,0.0,180.0);
CData.AddDataHatch4('' ,'シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]); |
Unit1.pas |
CData.AddSymbolDef('シンボルB');
CData.AddDataEllipse('シンボルB', 1,1,1,1, 36, 0.0,0.0,6.0,4.0,30.0);
CData.AddDataHatch4('' ,'シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]); |
Unit1.pas |
CData.AddSymbolDef('シンボルB');
CData.AddDataEllipseArc('シンボルB',
1,1,1,1, 18, 0, 0.0,0.0,6.0,4.0,30.0,0.0,180.0);
CData.AddDataHatch4('' ,'シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]); |
Unit1.pas |
CData.AddSymbolDef('シンボルB');
CData.AddDataBezier('シンボルB', 1,1,1,1, 10, 4,[0,3,6,9],[0,8,-8,0]);
CData.AddDataHatch4('' ,'シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]); |
Unit1.pas |
CData.AddSymbolDef('シンボルB');
CData.AddDataBspline('シンボルB', 1,1,1,1, 10,4, [0,3,6,9],[0,8,-8,0]);
CData.AddDataHatch4('' ,'シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]); |
Unit1.pas |
CData.AddSymbolDef('シンボルB');
CData.AddDataSpline('シンボルB',
1,1,1,1, 3,10,5, 0.0, [0,3,6,9,0],[0,6,-6,0,0]);
CData.AddDataHatch4('' ,'シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]); |
Unit1.pas |
CData.AddSymbolDef('シンボルB');
CData.AddDataClothoid('シンボルB', 1,1,1,1,0,30, 0,0,10,0.0, 10.0,50.0);
CData.AddDataHatch4('' ,'シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]);
CData.AddDataHatch4('部分図A','シンボルB',
1,10, 50.0,50.0, 15,0, 15,90, 1.0,1.0,0.0, 1,3,[2,3,4]); |
それでは、ここまでのテストプログラムです。実行ファイル、gdiplus.dll、gdipフォルダは入っていません。ソースのみです。
|