public Angle(double radian) { if (GeoUtils.Equals(radian, 0)) { _radian = 0; } else if (GeoUtils.Equals(radian, PI2)) { _radian = PI2; } else { while (radian < 0) { radian += PI2; } while (radian > PI2) { radian -= PI2; } _radian = radian; } }
/// <summary> /// 二分法查找参数对应区间 /// </summary> /// <param name="par">参数</param> /// <returns>参数对应区间</returns> public int FindSpan(double par) { var n = _knots.Count - 1; if (GeoUtils.Equals(par, _knots[_knots.Count - 1])) { return(n + Degree - 1); } int low = 0, high = n; int mid = (low + high) / 2; while (par < _knots[mid] || par >= _knots[mid + 1]) { if (par < _knots[mid]) { high = mid; } else { low = mid; } mid = (low + high) / 2; } return(mid + Degree); }
private void AddAttribute(XElement xe, string name, double value) { if (!GeoUtils.Equals(value, 0)) { xe.Add(new XAttribute(name, value)); } }
/// <summary> /// 按直线的镜像矩阵 /// </summary> /// <param name="start"></param> /// <param name="vec"></param> /// <returns></returns> public static Matrix2D Mirror(Point2D start, Vector2D vec) { bool ex = GeoUtils.Equals(vec.X, 0); bool ey = GeoUtils.Equals(vec.Y, 0); if (ex && ey) { return(Rotation(new Angle(Math.PI), start)); } else if (ex) { return(new Matrix2D(-1, 0, 0, 1, start.X * 2, 0)); } else if (ey) { return(new Matrix2D(1, 0, 0, -1, 0, start.Y * 2)); } double k = vec.Y / vec.X; double b = (start.Y - k * start.X); double x0 = b / k; double angle = vec.Angle * 2; double s2 = Math.Sin(angle); double c2 = Math.Cos(angle); return (new Matrix2D(c2, s2, s2, -c2, -b * s2, x0 * s2)); }
public Angle(double radian, bool format) { if (format) { if (GeoUtils.Equals(radian, PI2)) { _radian = PI2; } else { while (radian < 0) { radian += PI2; } while (radian > PI2) { radian -= PI2; } _radian = radian; } } else { _radian = radian; } }
public override bool Equals(object obj) { if (obj is Vector2D) { var v2 = (Vector2D)obj; return (GeoUtils.Equals(X, v2.X, GeoUtils.EqualsVector) && GeoUtils.Equals(Y, v2.Y, GeoUtils.EqualsVector)); } return(false); }
public override bool Equals(object obj) { if (obj is Point2D) { var p2 = (Point2D)obj; return (GeoUtils.Equals(X, p2.X, GeoUtils.EqualsPoint) && GeoUtils.Equals(Y, p2.Y, GeoUtils.EqualsPoint)); } return(false); }
public int Compare(Vector2D v1, Vector2D v2) { if (GeoUtils.Equals(v1.X, v2.X, GeoUtils.EqualsVector)) { if (GeoUtils.Equals(v1.Y, v2.Y, GeoUtils.EqualsVector)) { return(0); } else { return(v1.Y.CompareTo(v2.Y)); } } return(v1.X.CompareTo(v2.X)); }
public int Compare(Point2D p1, Point2D p2) { if (GeoUtils.Equals(p1.X, p2.X, GeoUtils.EqualsPoint)) { if (GeoUtils.Equals(p1.Y, p2.Y, GeoUtils.EqualsPoint)) { return(0); } else { return(p1.Y.CompareTo(p2.Y)); } } return(p1.X.CompareTo(p2.X)); }
public IEnumerator <Curve2D> GetEnumerator() { for (int i = 0; i < SegmentCount; i++) { var pt1 = Vertexs[i]; var pt2 = i == Vertexs.Count - 1 ? Vertexs[0] : Vertexs[i + 1]; if (GeoUtils.Equals(pt1.Bulge, 0)) { yield return(new LineSegment2D(pt1.Position, pt2.Position)); } else { yield return(new CircleArc2D(pt1.Position, pt2.Position, pt1.Bulge)); } } }
public void ToX(XElement xe) { var closed = Closed; if (GeoUtils.Equals(ControlPoints[0], ControlPoints[ControlPoints.Count - 1])) { closed = true; } xe.Add(new XAttribute("Closed", closed)); xe.Add(new XAttribute("Degree", Degree)); var controlPoints = new XElement("ControlPoints"); xe.Add(controlPoints); foreach (var pt in ControlPoints) { controlPoints.Add(pt.ToX("Point")); } xe.Add(Knots.ToX()); }
public Curve2D GetSegmentAt(int index) { if (index < 0 || index >= SegmentCount) { return(null); } var pt1 = Vertexs[index]; var pt2 = index == Vertexs.Count - 1 ? Vertexs[0] : Vertexs[index + 1]; if (GeoUtils.Equals(pt1.Bulge, 0)) { return(new LineSegment2D(pt1.Position, pt2.Position)); } else { return(new CircleArc2D(pt1.Position, pt2.Position, pt1.Bulge)); } }
public CircleArc2D(Point2D pt1, Point2D pt2, Point2D pt3, bool isWholeCircle) { if (isWholeCircle) { var xy1 = Math.Pow(pt1.X, 2) + Math.Pow(pt1.Y, 2); var xy2 = xy1 - Math.Pow(pt3.X, 2) - Math.Pow(pt3.Y, 2); var xy3 = xy1 - Math.Pow(pt2.X, 2) - Math.Pow(pt2.Y, 2); xy1 = (pt1.X - pt2.X) * (pt1.Y - pt3.Y) - (pt1.X - pt3.X) * (pt1.Y - pt2.Y); if (GeoUtils.Equals(xy1, 0)) { throw new Exception("无法创建圆!"); } Center = new Point2D( (xy3 * (pt1.Y - pt3.Y) - xy2 * (pt1.Y - pt2.Y)) / (2 * xy1), (xy2 * (pt1.X - pt2.X) - xy3 * (pt1.X - pt3.X)) / (2 * xy1)); Radius = (pt1 - Center).Length; if (GeoUtils.Equals(Radius, 0)) { throw new Exception("半径为零!"); } StartAngle = Angle.Zero; EndAngle = Angle.Degree360; } else { CircleArc2D cir = new CircleArc2D(pt1, pt2, pt3, true); Center = cir.Center; Radius = cir.Radius; IsClockWise = Vector2D.IsClockWise( pt1 - cir.Center, pt2 - cir.Center, pt3 - cir.Center); } }
/// <summary> /// 按向量的镜像矩阵 /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <returns></returns> public static Matrix2D Mirror(Vector2D vec) { bool ex = GeoUtils.Equals(vec.X, 0); bool ey = GeoUtils.Equals(vec.Y, 0); if (ex && ey) { return(Rotation(new Angle(Math.PI))); } else if (ex) { return(new Matrix2D(-1, 0, 0, 1, 0, 0)); } else if (ey) { return(new Matrix2D(1, 0, 0, -1, 0, 0)); } double angle = vec.Angle * 2; double s2 = Math.Sin(angle); double c2 = Math.Cos(angle); return(new Matrix2D(c2, s2, s2, -c2, 0, 0)); }
public static bool operator ==(Point2D p1, Point2D p2) { return (GeoUtils.Equals(p1.X, p2.X, GeoUtils.EqualsPoint) && GeoUtils.Equals(p1.Y, p2.Y, GeoUtils.EqualsPoint)); }
public bool IsZero() { return(GeoUtils.Equals(_radian, 0)); }
public bool IsPerpendicularTo(Vector2D vec) { return(GeoUtils.Equals(DotProduct(vec), 0)); }
public bool IsParallelTo(Vector2D vec) { return(GeoUtils.Equals(CrossProduct(vec), 0)); }
public static bool operator ==(Vector2D v1, Vector2D v2) { return (GeoUtils.Equals(v1.X, v2.X, GeoUtils.EqualsPoint) && GeoUtils.Equals(v1.Y, v2.Y, GeoUtils.EqualsPoint)); }
public bool IsWholeCircle() { return(GeoUtils.Equals(_radian, PI2)); }
public bool Equals(Angle x, Angle y) { return(GeoUtils.Equals(x._radian, y._radian)); }