Fabool Laser Mini が参照している SVGデータ の要素(?)は、すべて「path」になっています。(の様です)
この内容を扱うには座標情報(?)をデコード(?)する必要があるのですが、円弧、、、
(円弧には、円、円弧、楕円、楕円弧が含まれます。のようです)
10分でわかるSVG 基礎編 (2/5)
なんだこれ・・・
中心座標が無いんだ。。。円弧と楕円弧の場合、角度情報も無いんだ。。。ほとんど暗号解析やんか?どうすんのこれ?
SVG pathの楕円を描くコマンドが使いにくい
先人がぼやいているし
2、3日悩みましたね。できるのかよー、って
できませんでした。ティへぺろ
そして、Svg.dll ってライブラリを、てかこれもドキュメントが見つけられなくて、2回くらいスルーしてましたががが。
変数名とかと型名を見ながらデバッグで状況を探った結果、
「System.Drawing.Drawing2D.GraphicsPath」を取得することに成功っっ
下のコードは、上記の後に、平坦化(直線群に変換)して、それの一覧を取得まで行っています。
「PathArcAnal」は自作の処理クラス、「PathArcItem」は自作のオブジェクトクラスです。
/// 円弧を変換する
private string[] ConvArc(string dValue, DValueTypes dValueType, SValueTypes sValueType)
{
// 引数の確認
if (string.IsNullOrEmpty(dValue) == true) { return null; }
if (sValueType == SValueTypes.Delete) { return null; } // 無いはず
// 処理クラスの生成(と解析)
PathArcAnal pathArcAnal = new PathArcAnal(dValue, dValueType);
// 解析結果の確認
if (pathArcAnal.Result == false) { return null; }
// svg.dllの処理クラスの生成
Svg.SvgPath sPath = new Svg.SvgPath();
// 座標で回る
PointF lastPos = pathArcAnal.StartPos;
float minRadius = float.MaxValue;
foreach (PathArcItem pathArcItem in pathArcAnal.PathArcItems)
{
// svg.dllの円弧要素の生成
SvgArcSegment arcSegment = new SvgArcSegment(lastPos,
pathArcItem.Radius.X, pathArcItem.Radius.Y,
pathArcItem.Angle,
pathArcItem.Size,
pathArcItem.Sweep,
pathArcItem.Pos);
// 追加する
sPath.PathData.Add(arcSegment);
// 座標の保存
lastPos = pathArcItem.Pos;
// 最小半径の保持
if (pathArcItem.Radius.X < minRadius) { minRadius = pathArcItem.Radius.X; }
if (pathArcItem.Radius.Y < minRadius) { minRadius = pathArcItem.Radius.Y; }
}
// マトリクス(変換を指示?)の生成
System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix();
// 平滑化(直線で細分化)する
float coeff = (float)0.01;
if (sValueType == SValueTypes.Smooth)
{
coeff = (float)0.001;
}
else if (sValueType == SValueTypes.Rough)
{
coeff = (float)0.1;
}
sPath.Path.Flatten(matrix, (float)(minRadius * coeff));
// 戻り値の生成
List<string> ret = new List<string>();
// 座標群で回る
PointF startPoint = PointF.Empty;
PointF lastPoint = PointF.Empty;
foreach (PointF p in sPath.Path.PathData.Points)
{
// 最初の座標の確認
if (startPoint.IsEmpty || lastPoint.IsEmpty)
{
// 保持して抜ける
startPoint = p;
lastPoint = p;
continue;
}
// 文字列を組み立てて追加する
ret.Add("m " + lastPoint.X.ToString() + "," + lastPoint.Y.ToString() + " " + (p.X - lastPoint.X).ToString() + "," + (p.Y - lastPoint.Y).ToString());
// 保持する
lastPoint = p;
}
// 閉じる確認
if (pathArcAnal.IsZ == true && startPoint.Equals(lastPoint) == false)
{
//-- 閉じる指定があり、実際には閉じていないとき
// 文字列を組み立てて追加する
ret.Add("m " + lastPoint.X.ToString() + "," + lastPoint.Y.ToString() + " " + (startPoint.X - lastPoint.X).ToString() + "," + (startPoint.Y - lastPoint.Y).ToString());
}
// 返す
return ret.ToArray();
}
※動作しているコードの該当箇所をそのままコピーしました
0 件のコメント:
コメントを投稿