/// <summary> /// Crea un arco de circunferencia indicando puntoInicial, puntoFinal, centro, radio y sentido de giro (cw). /// </summary> public static CircleArc2 NewArc(Point2d pt1, Point2d pt2, Point2d center, double radius, ArcDirection dir) { double angle1 = AngleUtils.Ensure0To2Pi(pt1.Sub(center).Angle, false); double angle2 = AngleUtils.Ensure0To2Pi(pt2.Sub(center).Angle, false); if (dir == ArcDirection.Clockwise) { if (angle2 > angle1) { angle2 -= 2.0 * System.Math.PI; } } else if (angle2 < angle1) { angle2 += 2.0 * System.Math.PI; } if (angle2 > 2.0 * System.Math.PI) { angle1 -= 2.0 * System.Math.PI; angle2 -= 2.0 * System.Math.PI; } else if (angle2 < -2.0 * System.Math.PI) { angle1 += 2.0 * System.Math.PI; angle2 += 2.0 * System.Math.PI; } return(new CircleArc2(center, radius, angle1, angle2)); }
/// <summary> /// Crea un arco de circunferencia indicando puntoInicial, puntoFinal, centro, radio y sentido de giro (cw). /// </summary> public static CircleArc2 NewArc(Vec2d pt1, Vec2d pt2, Vec2d center, double radius, bool cw) { double a1 = vecMath.Angle(pt1.Sub(center)); double a2 = vecMath.Angle(pt2.Sub(center)); a1 = AngleUtils.Ensure0To2Pi(a1); a2 = AngleUtils.Ensure0To2Pi(a2); if (cw) { if (a2 > a1) { a2 -= 2 * SysMath.PI; } } else { if (a2 < a1) { a2 += 2 * SysMath.PI; } } return(new CircleArc2(center, radius, a1, a2)); }
public void Test1() { const double error = 1e-8; // desarrollo, r, parametro, x, y, c, normal ¿o direccion?, for (int i = 0; i < this.testData1.Length;) { double l = this.testData1[i++]; double r = this.testData1[i++]; double a = this.testData1[i++]; double x = this.testData1[i++]; double y = this.testData1[i++]; double radio = this.testData1[i++]; double tg = this.testData1[i++]; bool invertY = ((l < 0 && r > 0) || (l > 0 && r < 0)); double x2, y2; ClothoUtils.Clotho(l, invertY, a, out x2, out y2); double radio2 = ClothoUtils.ClothoRadius(l, invertY, a); double tg2 = ClothoUtils.ClothoTangent(l, invertY, a); Assert.IsTrue(x.EpsilonEquals(x2, error)); Assert.IsTrue(y.EpsilonEquals(y2, error)); Assert.IsTrue((double.IsInfinity(radio) && double.IsInfinity(radio2)) || radio.EpsilonEquals(radio2, error)); Assert.IsTrue(AngleUtils.Ensure0To2Pi(tg).EpsilonEquals(AngleUtils.Ensure0To2Pi(tg2), error)); } }
public void Test1() { double angle = Point2d.EvAngle(new Point2d(10, 10), new Point2d(0, 0), new Point2d(20, 0)); angle = AngleUtils.Ensure0To2Pi(angle); Assert.IsTrue(angle.EpsilonEquals(Math.PI / 2)); }
public double Project(Point2d punto, out double d2) { DistPointCircleArc2 distance = new DistPointCircleArc2() { Point = punto, Arc = this }; // Se calcula el punto mas cercano. d2 = distance.CalcDistance2(); double ca = distance.ClosestAngle; double ai = this.Angle1; double aa = this.AdvAngle; ai = AngleUtils.Ensure0To2Pi(ai); // Se comprueban los valores. Contract.Assert(ca.Between(0, 2 * SysMath.PI)); Contract.Assert(ai.Between(0, 2 * SysMath.PI)); Contract.Assert(aa.Between(-2 * SysMath.PI, 2 * SysMath.PI)); if (aa >= 0) { if (ca < ai) { ca += 2 * SysMath.PI; Contract.Assert(ca >= ai); } } else { if (ca > ai) { ca -= 2 * SysMath.PI; Contract.Assert(ca <= ai); } } // Se calcula la estacion. return((ca - ai) / aa); }
public double CalcDistance2() { // Se calcula la distancia al circulo. Circle2 circulo = new Circle2(this.Arc.Center, this.Arc.Radius); DistPointCircle2 dist = new DistPointCircle2() { Point = this.Point, Circle = circulo }; double d = dist.CalcDistance(); Point2d p = dist.ClosestPoint; double ca = AngleUtils.Ensure0To2Pi(dist.ClosestAngle); // [0, 2PI) // Se comprueba si el punto cae dentro del arco. double ai = this.Arc.Angle1; double aa = this.Arc.AdvAngle; if (AngleUtils.InArc(ai, aa, ca)) { this.ClosestPoint = p; this.ClosestAngle = ca; return(d * d); } // Se prueban los extremos. double d2_0 = this.Arc.Point0.Distance2To(this.Point); double d2_1 = this.Arc.Point1.Distance2To(this.Point); if (d2_0 <= d2_1) { this.ClosestPoint = this.Arc.Point0; this.ClosestAngle = AngleUtils.Ensure0To2Pi(this.Arc.Angle1, true); return(d2_0); } else { this.ClosestPoint = this.Arc.Point1; this.ClosestAngle = AngleUtils.Ensure0To2Pi(this.Arc.Angle2, true); return(d2_1); } }
public bool PointInCurve(Point2d p) { Vector2d vector2d = p - this.Center; if (!vector2d.Length.EpsilonEquals(this.Radius, 0.01)) { return(false); } double num1 = AngleUtils.Ensure0To2Pi(vector2d.Angle, false); double num2 = AngleUtils.Ensure0To2Pi(this.Angle1, false); double num3 = this.Angle2 - this.Angle1; if (num3 > 0.0) { return(num1 >= num2 && num1 <= num2 + num3); } else { return(num1 >= num2 + num3 && num1 <= num2); } }
/// <summary> /// Arco que pasa por los puntos <c>pinicial</c>, <c>ppaso</c>, <c>pfinal</c>. /// </summary> /// <exception cref="PuntosAlineadosException"> /// Indica que los puntos estan /// alineados. /// </exception> public static CircleArc2 ThreePoints(Vec2d p1, Vec2d pp, Vec2d p2) { Vec2d pcenter = GetCenter(p1, pp, p2); double radius = vecMath.Length(pcenter, p1); Vec2d v1 = p1.Sub(pcenter); Vec2d vp = pp.Sub(pcenter); Vec2d v2 = p2.Sub(pcenter); double alpha1 = vecMath.Angle(v1); double alphap = vecMath.Angle(vp); double alpha2 = vecMath.Angle(v2); { // Se prueba el sentido CCW, alpha1 < alphap < alpha2 double a1 = alpha1; double ap = alphap; double a2 = alpha2; while (ap < a1) { ap += 2 * SysMath.PI; } while (a2 < ap) { a2 += 2 * SysMath.PI; } if (a2 - a1 > 2 * SysMath.PI) { // Se ha dado mas de una vuelta, solucion no valida. } else { return(NewArcWithAdvance(pcenter, radius, AngleUtils.Ensure0To2Pi(a1), a2 - a1)); } } { // Se prueba el sentido CW, alpha1 > alphap > alpha2 double a1 = alpha1; double ap = alphap; double a2 = alpha2; while (ap > a1) { ap -= 2 * SysMath.PI; } while (a2 > ap) { a2 -= 2 * SysMath.PI; } if (a1 - a2 > 2 * SysMath.PI) { // Se ha dado mas de una vuelta, solucion no valida. } else { return(NewArcWithAdvance(pcenter, radius, AngleUtils.Ensure0To2Pi(a1), a2 - a1)); } } throw new Exception(); #if false double alpha2 = vecMath.Angle(v1, v2); alpha1 = AngleUtils.Ensure0To2Pi(alpha1); // Existen 2 soluciones que dependen de angulo de pp: // si alpha2 > 0 : alpha2 y alpha2 - 2*PI // si alpha2 < 0 : alpha2 y alpha2 + 2*PI if (alpha2 > 0) { double alpha3 = vecMath.Angle(pp); } else { } return(NewArcWithAdvance(pcenter, radius, alpha1, alpha2)); #endif }