public static CADVector RotateInRadian(CADVector v, double rad) { double x = v.X * System.Math.Cos(rad) - v.Y * System.Math.Sin(rad); double y = v.X * System.Math.Sin(rad) + v.Y * System.Math.Cos(rad); return(new CADVector(x, y)); }
public static CADVector RotateInRadian(CADVector point, CADVector basePoint, double rad) { double cos = System.Math.Cos(rad); double sin = System.Math.Sin(rad); double x = point.X * cos - point.Y * sin + basePoint.X * (1 - cos) + basePoint.Y * sin; double y = point.X * sin + point.Y * cos + basePoint.Y * (1 - cos) + basePoint.X * sin; return(new CADVector(x, y)); }
/// <summary> /// Returns the signed acute clockwise angle in radians between from and to. /// The result value range: [-PI, PI] /// </summary> public static double SignedAngleInRadian(CADVector from, CADVector to) { double rad = AngleInRadian(from, to); if (Cross(from, to) < 0) { rad = -rad; } return(rad); }
/// <summary> /// Returns the unsigned angle in radians between a and b. /// The smaller of the two possible angles between the two vectors is used. /// The result value range: [0, PI] /// </summary> public static double AngleInRadian(CADVector a, CADVector b) { double num = a.Length * b.Length; if (num == 0.0) { return(0.0); } double num2 = Dot(a, b) / num; return(System.Math.Acos(Utils.Clamp(num2, -1.0, 1.0))); }
/// <summary> /// 镜像矩阵 /// </summary> public static Matrix3 MirrorMatrix(Line2 mirrorLine) { CADVector lineDir = mirrorLine.direction; Matrix3 matPos1 = Matrix3.Translate(-mirrorLine.startPoint); double rotAngle = CADVector.SignedAngle(lineDir, new CADVector(1, 0)); Matrix3 matRot1 = Matrix3.Rotate(rotAngle); Matrix3 mirrorMatX = new Matrix3( 1, 0, 0, 0, -1, 0, 0, 0, 1); Matrix3 matRot2 = Matrix3.Rotate(-rotAngle); Matrix3 matPos2 = Matrix3.Translate(mirrorLine.startPoint); return(matPos2 * matRot2 * mirrorMatX * matRot1 * matPos1); }
/// <summary> /// 求线段的交点 /// </summary> /// <param name="line1st">线段1</param> /// <param name="line2nd">线段2</param> /// <param name="intersection">交点</param> /// <returns> /// true --- 相交 /// false --- 不相交 /// </returns> public static bool Intersect(Line2 line1st, Line2 line2nd, ref CADPoint intersection, double tolerance = 1e-10) { CADPoint p = line1st.startPoint; CADVector r = line1st.endPoint - line1st.startPoint; CADPoint q = line2nd.startPoint; CADVector s = line2nd.endPoint - line2nd.startPoint; double rxs = CADVector.Cross(r, s); if (!Utils.IsEqualZero(rxs, tolerance)) { double t = CADVector.Cross(q - p, s) / rxs; double u = CADVector.Cross(q - p, r) / rxs; if (t >= (0.0 - tolerance) && t <= (1.0 + tolerance) && u >= (0.0 - tolerance) && u <= (1.0 + tolerance)) { intersection = p + t * r; return(true); } } return(false); }
public static CADVector Rotate(CADVector point, CADVector basePoint, double angle) { return(RotateInRadian(point, basePoint, Utils.DegreeToRadian(angle))); }
public static CADVector Rotate(CADVector v, double angle) { return(RotateInRadian(v, Utils.DegreeToRadian(angle))); }
public static double Distance(CADVector a, CADVector b) { CADVector vector = b - a; return(vector.Length); }
/// <summary> /// Returns the signed acute clockwise angle in degrees between from and to. /// The result value range: [-180, 180] /// </summary> public static double SignedAngle(CADVector from, CADVector to) { return(Utils.RadianToDegree(SignedAngleInRadian(from, to))); }
/// <summary> /// Returns the unsigned angle in degrees between a and b. /// The smaller of the two possible angles between the two vectors is used. /// The result value range: [0, 180] /// </summary> public static double Angle(CADVector a, CADVector b) { return(Utils.RadianToDegree(AngleInRadian(a, b))); }
public static double Cross(CADVector a, CADVector b) { return((a.X * b.Y) - (a.Y * b.X)); }
public static double Dot(CADVector a, CADVector b) { return(a.X * b.X + a.Y * b.Y); }
/// <summary> /// NOTE: Rotation will need to be added to this function /// </summary> /// <param name="c">Ellipse centre</param> /// <param name="rx">Ellipse X radius</param> /// <param name="ry">Ellipse Y radius</param> /// <param name="a1">Line P1</param> /// <param name="a2">Line P2</param> /// <returns></returns> public static Intersection IntersectEllipseLine(CADPoint c, double rx, double ry, CADPoint a1, CADPoint a2) { Intersection result; var origin = new CADVector(a1.X, a1.Y); var dir = a2 - a1; var center = new CADVector(c.X, c.Y); var diff = origin - center; var mDir = new CADVector(dir.X / (rx * rx), dir.Y / (ry * ry)); var mDiff = new CADVector(diff.X / (rx * rx), diff.Y / (ry * ry)); var a = CADVector.Dot(dir, mDir); var b = CADVector.Dot(dir, mDiff); var cc = CADVector.Dot(diff, mDiff) - 1.0; var d = b * b - a * cc; if (d < 0) { result = new Intersection(Intersection.IntStatus.Outside); } else if (d > 0) { var root = Math.Sqrt(d); var t_a = (-b - root) / a; var t_b = (-b + root) / a; if ((t_a < 0 || 1 < t_a) && (t_b < 0 || 1 < t_b)) { if ((t_a < 0 && t_b < 0) || (t_a > 1 && t_b > 1)) { result = new Intersection(Intersection.IntStatus.Outside); } else { result = new Intersection(Intersection.IntStatus.Inside); } } else { result = new Intersection(Intersection.IntStatus.Intersection); if (0 <= t_a && t_a <= 1) { result.appendPoint(a1.lerp(a2, t_a)); } if (0 <= t_b && t_b <= 1) { result.appendPoint(a1.lerp(a2, t_b)); } } } else { var t = -b / a; if (0 <= t && t <= 1) { result = new Intersection(Intersection.IntStatus.Intersection); result.appendPoint(a1.lerp(a2, t)); } else { result = new Intersection(Intersection.IntStatus.Outside); } } return(result); }