public static double GetClockwiseMostAngle(Vec2d v1, Vec2d v2) { // Assume v1 and v2 normalized double dot = Vec2d.Dot(v1, v2); // Limit dot to valid values [-1 .. 1] dot = Math.Max(-1.0, Math.Min(1.0, dot)); double angle = Math.Acos(dot); angle = Math.Abs(angle); // Check clockwise / ccw angle = (v1.X * v2.Y - v1.Y * v2.X) < 0 ? 2 * Math.PI - angle : angle; //// Same direction (i.e. back) is to be maximum angle //angle = angle < 0.001 && angle > -0.001 ? 2 * Math::PI : angle; return(angle); }
public virtual double GetCurvature(double t) { Vec2d der1 = this.GetFirstDerivative(t); double speed2 = der1.Length2; if (speed2.EpsilonEquals(0)) { // Curvature is indeterminate, just return 0. return(0); } Vec2d der2 = this.GetSecondDerivative(t); double numer = der1.Dot(der2); double denom = SysMath.Pow(speed2, 1.5); return(numer / denom); }
public static Vec2d[] LineCircleIntersection(Vec2d pointA, Vec2d pointB, Vec2d pointO, double radius) { Vec2d[] output = new Vec2d[2]; Vec2d v1, v2; //Vector from point 1 to point 2 v1 = pointB - pointA; //Vector from point 1 to the circle's center v2 = pointO - pointA; double dot = Vec2d.Dot(v1, v2); Vec2d proj1 = new Vec2d(((dot / (v1.Length2)) * v1.X), ((dot / (v1.Length2)) * v1.Y)); Vec2d midpt = new Vec2d(pointA.X + proj1.X, pointA.Y + proj1.Y); double distToCenter = (midpt.X - pointO.X) * (midpt.X - pointO.X) + (midpt.Y - pointO.Y) * (midpt.Y - pointO.Y); if (distToCenter > radius * radius) { return(output); } if (distToCenter == radius * radius) { output[0] = midpt; return(output); } double distToIntersection; if (distToCenter == 0) { distToIntersection = radius; } else { distToCenter = Math.Sqrt(distToCenter); distToIntersection = Math.Sqrt(radius * radius - distToCenter * distToCenter); } double lineSegmentLength = 1 / v1.Length; v1 *= lineSegmentLength; v1 *= distToIntersection; output[0] = (midpt + v1); output[1] = (midpt - v1); return(output); }
public void ValueType_Vec2d() { var p1 = new Vec2d(1, 0); var p2 = new Vec2d(0, 1); Assert.IsFalse(p1.IsEqual(p2, 0.99, 0.1)); Assert.IsTrue(p1.IsEqual(p2, 1.01, 0.1)); Assert.IsTrue(p1.IsEqual(p2, 0.99, Math.PI / 2)); Assert.IsTrue(p1.IsNormal(p2, 0.1)); Assert.IsFalse(p1.IsOpposite(p2, 0.1)); Assert.IsTrue(p1.IsOpposite(p2, Math.PI / 2)); Assert.IsFalse(p1.IsParallel(p2, 0.1)); Assert.IsTrue(p1.IsParallel(p2, Math.PI / 2)); p1 = new Vec2d(1, 2); p2 = new Vec2d(4, 5); Assert.AreEqual(5, p1.SquareMagnitude()); Assert.AreEqual(Math.Sqrt(5), p1.Magnitude()); p2 = p1; p2.Add(new Vec2d(1, 2)); Assert.AreEqual(new Vec2d(2, 4), p2); Assert.AreEqual(new Vec2d(2, 4), p1.Added(new Vec2d(1, 2))); p2 = new Vec2d(1, 2); p2.Subtract(new Vec2d(3, 2)); Assert.AreEqual(new Vec2d(-2, 0), p2); Assert.AreEqual(new Vec2d(-2, 0), p1.Subtracted(new Vec2d(3, 2))); p2 = new Vec2d(1, 2); Assert.AreEqual(-4, p1.Crossed(new Vec2d(3, 2))); Assert.AreEqual(Math.Sqrt(16), p1.CrossMagnitude(new Vec2d(3, 2))); Assert.AreEqual(16, p1.CrossSquareMagnitude(new Vec2d(3, 2))); p2 = new Vec2d(1, 2); p2.Divide(2); Assert.AreEqual(new Vec2d(0.5, 1), p2); Assert.AreEqual(new Vec2d(0.5, 1), p1.Divided(2)); Assert.AreEqual(5, p1.Dot(new Vec2d(1, 2))); p2 = new Vec2d(1, 2); p2.Multiply(2); Assert.AreEqual(new Vec2d(2, 4), p2); Assert.AreEqual(new Vec2d(2, 4), p1.Multiplied(2)); p2 = new Vec2d(1, 2); p2.Scale(2); Assert.AreEqual(new Vec2d(2, 4), p2); Assert.AreEqual(new Vec2d(2, 4), p1.Scaled(2)); p2 = new Vec2d(1, 23); Assert.AreEqual("0.0434372242763069,0.99905615835506", p2.Normalized().ToString()); p2.Normalize(); Assert.AreEqual("0.0434372242763069,0.99905615835506", p2.ToString()); p2 = new Vec2d(1, 2); p2.Reverse(); Assert.AreEqual(new Vec2d(-1, -2), p2); Assert.AreEqual(new Vec2d(-1, -2), p1.Reversed()); p2.SetLinearForm(new Vec2d(1, 2), new Vec2d(4, 5)); Assert.AreEqual(new Vec2d(5, 7), p2); p2.SetLinearForm(2, new Vec2d(1, 2), new Vec2d(4, 5)); Assert.AreEqual(new Vec2d(6, 9), p2); p2.SetLinearForm(2, new Vec2d(1, 2), 3, new Vec2d(4, 5)); Assert.AreEqual(new Vec2d(14, 19), p2); p2.SetLinearForm(2, new Vec2d(1, 2), 3, new Vec2d(4, 5), new Vec2d(7, 8)); Assert.AreEqual(new Vec2d(21, 27), p2); p2 = new Vec2d(2, 1); Assert.AreEqual(new Vec2d(1, 0), p2.Mirrored(new Vec2d(1, 0))); p2.Mirror(new Vec2d(1, 0)); Assert.AreEqual(new Vec2d(1, 0), p2); var m2 = new Ax2d(new Pnt2d(-1, 2), new Dir2d(-1, 0)); p2 = new Vec2d(2, 1); Assert.AreEqual(new Vec2d(2, -1), p2.Mirrored(m2)); p2.Mirror(m2); Assert.AreEqual(new Vec2d(2, -1), p2); p2 = new Vec2d(2, 1); Assert.AreEqual("-1,2", p2.Rotated(Math.PI / 2).ToString()); p2.Rotate(Math.PI / 2); Assert.AreEqual("-1,2", p2.ToString()); //TestContext.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", gp2.x, gp2.y, gp2.z)); Trsf2d t1 = new Trsf2d(); t1.SetRotation(new Pnt2d(1, 2), Math.PI / 2); p2 = new Vec2d(2, 1); Assert.AreEqual("-1,2", p2.Transformed(t1).ToString()); p2.Transform(t1); Assert.AreEqual("-1,2", p2.ToString()); }
/// <summary> /// Returns a signed angle in radians between vector u and v. /// </summary> /// <param name="u">first (normalized!) vector</param> /// <param name="v">second (normalized!) vector</param> /// <returns></returns> public static double GetAngle(Vec2d u, Vec2d v) { return(Math.Atan2(Vec2d.Dot(new Vec2d(-u.Y, u.X), v), Vec2d.Dot(u, v))); }
public void Dot() { var p1 = new Vec2d(1, 2); Assert.AreEqual(5, p1.Dot(new Vec2d(1, 2))); }