/// <summary> /// 線対称の位置を計算 /// </summary> /// <param name="v"></param> /// <param name="start">線対称の線の始点</param> /// <param name="end">線対称の線の終点</param> /// <returns></returns> Vector2 CalcSymmetricPoint(Vector2 v, Vector2 start, Vector2 end) { var v0 = end - start; var a0 = MathF.Atan2(v0.Y, v0.X); var v1 = v - start; var a1 = MathF.Atan2(v1.Y, v1.X); var a = a0 - (a1 - a0); var l = CmUtils.Length(v, start); Vector2 vn = new Vector2(l * MathF.Cos(a), l * MathF.Sin(a)); vn += start; return(vn); }
public string GetInfo(int partIndex, bool simple = false) { string label = "座標"; Vector2 p = points[0]; switch (Command) { case 'C': case 'c': { if (points.Count == 3) { p = points[2]; if (partIndex == 2) { label = string.Format("座標 {0} {1:0.00} {2:0.00} ", Command, p.X, p.Y); } else if (partIndex == 0 || partIndex == 1) { if (partIndex == 0) { p = befor.GetPoint(); } Vector2 c = points[partIndex]; c.X = c.X - p.X; c.Y = c.Y - p.Y; // コントロールポイントの長さ float l = MathF.Sqrt(c.X * c.X + c.Y * c.Y); // コントロールポイントのアンカーポイントからの角度 double r = l / 0.5522847; float a = CmUtils.ToAngle(MathF.Atan2(c.Y, c.X)); if (simple) { label = string.Format(" c1 {0:0.00} {1:0.00} r:{2:0.00} (長さ:{3:0.00}角度:{4:0.00})", c.X, c.Y, r, l, a); } else { label = string.Format("座標 {0} {1:0.00} {2:0.00} c1 {3:0.00} {4:0.00} r:{5:0.00} (長さ:{6:0.00}角度:{7:0.00})", Command, p.X, p.Y, c.X, c.Y, r, l, a); } } } break; } default: return(string.Format("座標 {0} {1:0.00} {2:0.00} ", Command, p.X, p.Y)); } return(label); }
/// <summary> /// 直線をベジェに変換、コントロールポイントは直線上に1/3の長さで設定 /// </summary> /// <returns></returns> internal bool ConvertToCurve() { var p0 = befor.GetPoint(); var p1 = GetPoint(); var l = CmUtils.Length(p0, p1) / 3; var rad = MathF.Atan2(p1.Y - p0.Y, p1.X - p0.X); points.Insert(0, CmUtils.Coordinate(p0, l, rad)); points.Insert(1, CmUtils.Coordinate(p1, l, rad + MathF.PI)); Command = 'C'; return(true); }
bool RoundSub(Vector2 pc, Vector2 pb, Vector2 pn, ref Vector2 pb2, ref Vector2 pn2, float step) { var a1 = MathF.Atan2(pc.Y - pb.Y, pc.X - pb.X); //傾き var a2 = MathF.Atan2(pn.Y - pc.Y, pn.X - pc.X); //次の線の傾き var a = (a1 + a2) / 2; a = MathF.Abs(a); if (a > MathF.PI) { a -= MathF.PI; } // a は中線の傾き float lb2 = CmUtils.Length(pc, pb2); float ln2 = CmUtils.Length(pc, pn2); float l = MathF.Min(lb2, ln2); var ac2 = MathF.Abs((a1 - a2) / 2); if (ac2 > MathF.PI) { ac2 -= MathF.PI; } float r = l * MathF.Tan(ac2); r = MathF.Round(r, 1); if (step > 0) { if (r < 2) { step = 0.1f; } else if (r < 2.4) { step = 2.4f - r; } else { step = 0.1f; } } else { if (r <= 2.0f) { step = -0.1f; } else if (r < 2.5) { step = 2.0f - r; } else { step = -0.5f; } } r += step; /// float v = 0; v = r / MathF.Tan(a); // 半径r円の接点の頂点からの距離 float l1 = CmUtils.Length(pb, pc); // 自分の線の長さ float l2 = CmUtils.Length(pc, pn); // 次の線の長さ if (l1 < v || l2 < v) { return(false); } var x = MathF.Cos(a1) * v; var y = MathF.Sin(a1) * v; var p1 = new Vector2(pc.X - x, pc.Y - y); x = MathF.Cos(a2) * v; y = MathF.Sin(a2) * v; var p2 = new Vector2(pc.X + x, pc.Y + y); var c = r * 0.5522847f; // 半径rの円弧に近似するためのコントロールポイントの長さ x = MathF.Cos(a1) * c; y = MathF.Sin(a1) * c; var c1 = new Vector2(p1.X + x, p1.Y + y); x = MathF.Cos(a2) * c; y = MathF.Sin(a2) * c; var c2 = new Vector2(p2.X - x, p2.Y - y); // points[0] = c1; points[1] = c2; points[2] = p2; pb2 = p1; pn2 = p2; // this.points[0] = p1; CmUtils.DebugWriteLine(string.Format("a1:{0:0.00},a2:{1:0.00},ac:{2:0.00},r:{3:0.00}", CmUtils.ToAngle(a1), CmUtils.ToAngle(a2), CmUtils.ToAngle(ac2), r)); return(true); }
/// <summary> /// /// </summary> /// <param name="pn"></param> /// <returns></returns> internal SvgPathItem CreateRoundCorner(Vector2 pn) { var pc = GetPoint(); var pb = befor.GetPoint(); var a1 = MathF.Atan2(pc.Y - pb.Y, pc.X - pb.X); //傾き var a2 = MathF.Atan2(pn.Y - pc.Y, pn.X - pc.X); //次の線の傾き var a = (a1 + a2) / 2; a = MathF.Abs(a); if (a > MathF.PI) { a -= MathF.PI; } float r = 2; float v = 0; v = r / MathF.Tan(a); // 半径r円の接点の頂点からの距離 float l1 = CmUtils.Length(pb, pc); // 自分の線の長さ float l2 = CmUtils.Length(pc, pn); // 次の線の長さ if (l1 < v || l2 < v) { return(null); } var citem = new SvgPathItem('C', this); var x = MathF.Cos(a1) * v; var y = MathF.Sin(a1) * v; var p1 = new Vector2(pc.X - x, pc.Y - y); x = MathF.Cos(a2) * v; y = MathF.Sin(a2) * v; var p2 = new Vector2(pc.X + x, pc.Y + y); var c = r * 0.5522847f; // 半径rの円弧に近似するためのコントロールポイントの長さ x = MathF.Cos(a1) * c; y = MathF.Sin(a1) * c; var c1 = new Vector2(p1.X + x, p1.Y + y); x = MathF.Cos(a2) * c; y = MathF.Sin(a2) * c; var c2 = new Vector2(p2.X - x, p2.Y - y); var points = new List <Vector2>(); points.Add(c1); points.Add(c2); points.Add(p2); citem.SetPoints(points); this.points[0] = p1; CmUtils.DebugWriteLine(string.Format("a1:{0:0.00},a2:{1:0.00},vl:{2:0.00},cl:{3:0.00}", CmUtils.ToAngle(a1), CmUtils.ToAngle(a2), v, c)); return(citem); }
internal string GetInfo(MainPage.PolygonUnit polygonUnitValue) { if (CurrentIndex.IsValid()) { var m_path = Paths[CurrentIndex.BlockIndex]; if (polygonUnitValue == PolygonUnit.Symmetry) { if (CurrentIndex.BlockIndex == Paths.Count - 1) { Vector2 start = m_path[0].GetPoint(); Vector2 end = m_path[1].GetPoint(); var v1 = end - start; var a1 = MathF.Atan2(v1.Y, v1.X); string text = string.Format("始点({0:0.00},{1:0.00}) 終点({2:0.00},{3:0.00}) 角度({4:0.0}) ", start.X, start.Y, end.X, end.Y, CmUtils.ToAngle(a1)); return(text); } else { Vector2 start = new Vector2(); Vector2 end = new Vector2(); var item = m_path[CurrentIndex.ItemIndex]; var p = item.GetPoint(CurrentIndex.PartIndex); if (RulerEnabled) { var ruler = Paths[Paths.Count - 1]; start = ruler[0].GetPoint(); end = ruler[1].GetPoint(); } else { CalcReferenceLine(ref start, ref end); } /* * */ var v1 = end - start; var a1 = MathF.Atan2(v1.Y, v1.X); var v2 = p - start; var a2 = MathF.Atan2(v2.Y, v2.X); var l = MathF.Abs(MathF.Sin(a2 - a1) * MathF.Sqrt(MathF.Pow(v2.X, 2) + MathF.Pow(v2.Y, 2))); var l2 = MathF.Cos(a2 - a1) * MathF.Sqrt(MathF.Pow(v2.X, 2) + MathF.Pow(v2.Y, 2)); string text = string.Format("基準から:{1:0.0} 中心線から:{0:0.0} $$ ", l, l2); string info = item.GetInfo(CurrentIndex.PartIndex, true); return(text + info); } } else if (polygonUnitValue == PolygonUnit.RulerOrigin) { if (RulerVisible) { var ruler = Paths[Paths.Count - 1]; var v = ruler[0].GetPoint(); var item = m_path[CurrentIndex.ItemIndex]; string info = item.GetInfo(CurrentIndex.PartIndex, true); string text = string.Format("原点:{0:0.0} {1:0.0}", v.X, v.Y); var p = item.GetPoint(); var ofy = p.Y - v.Y; var ofx = p.X - v.X; float r = MathF.Sqrt(MathF.Pow(ofx, 2) + MathF.Pow(ofy, 2)); var a = MathF.Atan2(ofy, ofx); text += string.Format(" 半径 {0:0.00} 角度 {1:0.00}", r, ToAngle(a)); return(text + info); } } else if (polygonUnitValue != MainPage.PolygonUnit.none) { int unit = (int)polygonUnitValue; var count = m_path.Count - 1; if (IsSameLast(m_path)) { count--; } if (count >= unit * 2 && count % 2 == 0) { var PolygonCenter = CalcCenter(m_path); string text = string.Format("中心:{0:0.0} {1:0.0}", PolygonCenter.X, PolygonCenter.Y); var index = CurrentIndex.ItemIndex;// if (index >= 0) { var item = m_path[index]; var p = item.GetPoint(); var v = PolygonCenter; var ofy = p.Y - v.Y; var ofx = p.X - v.X; float r = MathF.Sqrt(MathF.Pow(ofx, 2) + MathF.Pow(ofy, 2)); var a = MathF.Atan2(ofy, ofx); text += string.Format(" 半径 {0:0.00} 角度 {1:0.00}", r, ToAngle(a)); var partIndex = CurrentIndex.PartIndex; // string info = item.GetInfo(partIndex, true); text += info; } return(text); } } { var index = CurrentIndex.ItemIndex; // var partIndex = CurrentIndex.PartIndex; // if (index >= 0) { var item = m_path[index]; string info = item.GetInfo(partIndex); return(info); } } } return("選択されていません"); }