internal static void SetPreviusPoint(List <SvgPathItem> path, int index, Vector2 p1) { SvgPathItem pre = null; Vector2? pm = null; index--; if (index < 0) { index = path.Count - 1; } pre = path[index]; if (pre.IsM()) { pm = pre.GetPoint(); pre.SetPoint(p1); } if (pre.IsZ()) { index--; pre = path[index]; } if (pm == null) { pre.SetPoint(p1); } else { var p = pre.GetPoint(); if (p == pm) { pre.SetPoint(p1); } } }
/// <summary> /// 現在の座標を指定されたいテムを指定した角度回転した値にセット。 /// </summary> /// <param name="item0"></param> /// <param name="partIndex"></param> /// <param name="center"></param> /// <param name="da"></param> internal void ApplyOtherValue2(SvgPathItem item0, int partIndex, Vector2 center, float da) { switch (Command) { case 'C': case 'c': { if (item0.IsC()) { if (partIndex == 2 || partIndex == 1) { Vector2 p = item0.GetPoint(); Vector2 ps = GetPoint(); p = CalcRotatePosition(p, center, da); points[2] = p; // コントロールポイント2も同様に、 var cp2 = item0.GetControlPoint(true); cp2 = CalcRotatePosition(cp2, center, da); points[1] = cp2; // 隣のコントロールポイント1も同様に var nexti = FindNext(); if (nexti.IsC()) { nexti.ControlRotate(0, center, ps, p); } } else if (partIndex == 0) { /* * SvgPathItem item = item0.FindBefor(); * Vector2 p = item.GetPoint(); * * p = CalcRotatePosition(p, center, da); * var itemb = FindBefor(); * itemb.SetPoint(p); * * // コントロールポイント * var cp1 = item0.GetControlPoint(false); * cp1 = CalcRotatePosition(p, center, da); * points[0] = cp1; */ var p = item0.GetControlPoint(false); p = CalcRotatePosition(p, center, da); points[0] = p; } } break; } case 'M': case 'l': case 'L': { Vector2 p = item0.GetPoint(); p = CalcRotatePosition(p, center, da); points[0] = p; break; } } }
int PathCount(ref SvgPathItem last) { // 先頭を探す var top = FindTop(); // アイテム数を数えるのと最後を見つける last = top; int count = 1; for (; ;) { if (last.Next == null || last.Next.IsZ()) { break; } last = last.Next; count++; } if (last.Next != null) { if (top.GetPoint() == last.GetPoint()) { count--; } } return(count); }
public SvgPathItem(char command, SvgPathItem befor) { this.befor = befor; Command = command; index = 0; points = new List <Vector2>(); beforPoint = befor == null ? new Vector2(0, 0) : befor.GetPoint(); }
internal void AdjustSymmetric(SvgPathItem item) { if (!IsC() || !item.IsC()) { return; } var c = item.GetControlPoint(true); var p = item.GetPoint(); c.X = p.X + (p.X - c.X); c.Y = p.Y + (p.Y - c.Y); points[0] = c; }
private SvgPathItem FindBefor() { var item = befor; if (item == null || item.IsM()) { SvgPathItem last = null; PathCount(ref last); if (item == null) { return(last); } if (item.GetPoint() == last.GetPoint()) { return(last); } } return(item); }
/// <summary> /// item の線対称の値をセット /// </summary> /// <param name="item"></param> /// <param name="partIndex"></param> /// <param name="start"></param> /// <param name="end"></param> internal void ApplyOtherValue(SvgPathItem item, int partIndex, Vector2 start, Vector2 end) { if (item.IsC() || IsC()) { switch (Command) { case 'L': case 'l': case 'M': case 'm': { if (item.IsC()) { // 自分の次はCで無いとつじつまが合わない var next = this.Next; if (next == null || !next.IsC()) { return; } if (partIndex == 2) { points[0] = CalcSymmetricPoint(item.GetPoint(partIndex), start, end); } if (partIndex == 2 || partIndex == 1) { var v = CalcSymmetricPoint(item.GetPoint(1), start, end); next.SetPoint(v, 0); } if (partIndex == 0) { var v = CalcSymmetricPoint(item.GetPoint(1), start, end); next.SetPoint(v, 1); } } break; } case 'c': case 'C': // 自分が C if (item.IsC()) { if (partIndex == 2) //終点 この場合は全体を移動 { { var v = CalcSymmetricPoint(item.GetPoint(), start, end); SetPoint(v, 2); } // 制御点をitemの制御点にあわせる { // item の終点の制御点を next の始点の制御点に var next = this.Next; if (next != null && next.IsC()) { var v = CalcSymmetricPoint(item.GetPoint(1), start, end); next.SetPoint(v, 0); } } { // item の 次の始点の制御点を this の終点の制御点に var next = item.Next; if (next != null && next.IsC()) { var v = CalcSymmetricPoint(next.GetPoint(0), start, end); SetPoint(v, 1); } } } else if (partIndex == 0) { // 相手側の始点制御点の変更 なので、相手側の対象点を自分の次のアイテムの終点制御点へ var next = this.Next; if (next != null && next.IsC()) { var v = CalcSymmetricPoint(item.GetPoint(0), start, end); next.SetPoint(v, 1); } } } else if (item.IsL() || item.IsM()) { // itemの次はCで無いとつじつまが合わない var next = item.Next; if (next == null || !next.IsC()) { return; } { var v = CalcSymmetricPoint(item.GetPoint(), start, end); SetPoint(v, 2); } { var v = CalcSymmetricPoint(next.GetPoint(0), start, end); SetPoint(v, 1); } } break; } } else if (item.IsL() || item.IsM()) { switch (Command) { case 'L': case 'l': case 'M': case 'm': { points[0] = CalcSymmetricPoint(item.GetPoint(), start, end); } break; } } }
/// <summary> /// /// </summary> /// <param name="win2d"></param> /// <param name="scale"></param> internal void DrawAnchor(CanvasDrawingSession win2d, ViewInfo viewInfo, SvgPathData.SvgPathIndex myIndex) { float scale = viewInfo.Scale; switch (Command) { case 'M': case 'h': case 'H': case 'v': case 'V': case 'l': case 'L': int partindex = 0; foreach (Vector2 point in points) { float x = (float)point.X * scale; float y = (float)point.Y * scale; DrawAnchorSub(win2d, viewInfo, myIndex, partindex, x, y); partindex++; } break; case 'c': case 'C': if (points.Count == 3) { Color color = GetColor(); Vector2 point = points[2]; float x = (float)point.X * scale; float y = (float)point.Y * scale; DrawAnchorSub(win2d, viewInfo, myIndex, 2, x, y); Vector2 p0 = befor.GetPoint(); float x0 = (float)p0.X * scale; float y0 = (float)p0.Y * scale; Vector2 p1 = points[0]; float x1 = (float)p1.X * scale; float y1 = (float)p1.Y * scale; win2d.DrawLine(x0, y0, x1, y1, color); DrawAnchorSub(win2d, viewInfo, myIndex, 0, x1, y1); Vector2 p2 = points[1]; float x2 = (float)p2.X * scale; float y2 = (float)p2.Y * scale; win2d.DrawLine(x, y, x2, y2, color); DrawAnchorSub(win2d, viewInfo, myIndex, 1, x2, y2); } break; case 'a': case 'A': foreach (Vector2 point in points) { float x = (float)point.X * scale; float y = (float)point.Y * scale; DrawAnchorSub(win2d, viewInfo, myIndex, 0, x, y); } break; default: break; } }
/// <summary> /// /// </summary> /// <param name="path"></param> /// <param name="index">自分のindex</param> /// <param name="step"></param> /// <returns></returns> internal bool RoundCorner(List <SvgPathItem> path, int index, float step) { SvgPathItem b1 = path[index - 1]; // 自分はCなので最低Mは存在する。 var p1 = b1.GetPoint(); var p3 = GetPoint(); SvgPathItem b2 = null; if (index >= 2) { b2 = path[index - 2]; } else { var item = path[path.Count - 1]; if (item.IsZ()) { b2 = path[path.Count - 2]; var p = b2.GetPoint(); if (p == p1) { if (b2.IsL()) { b2 = null; } } } } if (b2 == null) { return(false); } var p2 = b2.GetPoint(); SvgPathItem n1 = null; if (index <= path.Count - 2) { n1 = path[index + 1]; if (n1.IsZ()) { n1 = path[0]; var p = n1.GetPoint(); if (p == p3) { n1 = path[1]; if (!n1.IsL()) { return(false); } } } } else { return(false); } // 交点求める公式より var p4 = n1.GetPoint(); float dev = (p2.Y - p1.Y) * (p4.X - p3.X) - (p2.X - p1.X) * (p4.Y - p3.Y); if (dev == 0) { return(false); } float d1 = p3.Y * p4.X - p3.X * p4.Y; float d2 = p1.Y * p2.X - p1.X * p2.Y; float x = d1 * (p2.X - p1.X) - d2 * (p4.X - p3.X); x /= dev; float y = d1 * (p2.Y - p1.Y) - d2 * (p4.Y - p3.Y); y /= dev; if (RoundSub(new Vector2(x, y), p2, p4, ref p1, ref p3, step)) { SvgPathData.SetPreviusPoint(path, index, p1); SvgPathData.SetSameNextPoint(path, index); return(true); } return(false); }
internal void SetBefor(SvgPathItem cp) { befor = cp; beforPoint = befor.GetPoint(); }