/// <summary> /// Initializes a new instance of the <c>Vertex</c> class. /// </summary> /// <param name="location">Vertex <see cref="netDxf.Vector2f">location</see>.</param> public Vertex(Vector2f location) : base(DxfCodigoObjeto.Vertex) { this.flags = VertexTypeFlags.PolylineVertex; this.location = new Vector3f(location.X, location.Y, 0.0f); //this.layer = Layer.Default; //this.color = AciColor.ByLayer; //this.lineType = LineType.ByLayer; this.bulge = 0.0f; this.beginThickness = 0.0f; this.endThickness = 0.0f; }
/// <summary> /// Convierte el circulo en una lista de vertices. /// </summary> /// <param name="precision">Numero de vertices generados.</param> /// <param name="tolerancia">Tolerancia a considerar para comparar si dos nuevos vertices son iguales.</param> /// <returns>Una lista de verices que representa el circulo expresado en coordenadas.</returns> public List<Vector2f> PoligonalVertices(int precision, float tolerancia) { if (precision < 3) throw new ArgumentOutOfRangeException("precision", precision, "La precision del circulo debe ser mayor o igual a tres"); List<Vector2f> ocsVertices = new List<Vector2f>(); if (2 * this.radio >= tolerancia) { float angulo = (float)(MathHelper.TwoPI / precision); Vector2f antPunto; Vector2f primerPunto; float seno = (float)(this.radio * Math.Sin(MathHelper.HalfPI * 0.5)); float coseno = (float)(this.radio * Math.Cos(MathHelper.HalfPI * 0.5)); primerPunto = new Vector2f(coseno + this.centro.X, seno + this.centro.Y); ocsVertices.Add(primerPunto); antPunto = primerPunto; for (int i = 1; i < precision; i++) { seno = (float)(this.radio * Math.Sin(MathHelper.HalfPI + angulo * i)); coseno = (float)(this.radio * Math.Cos(MathHelper.HalfPI + angulo * i)); Vector2f punto = new Vector2f(coseno + this.centro.X, seno + this.centro.Y); if (!punto.Equals(antPunto, tolerancia) && !punto.Equals(primerPunto, tolerancia)) { ocsVertices.Add(punto); antPunto = punto; } } } return ocsVertices; }
private Vector2f PointFromEllipse(float degrees) { // Convert the basic input into something more usable Vector2f ptCenter = new Vector2f(this.centro.X, this.centro.Y); float radians = (float) (degrees*MathHelper.DegToRad); // Calculate the radius of the ellipse for the given angle float a = this.ejeMayor; float b = this.ejeMenor; float eccentricity = (float) Math.Sqrt(1 - (b*b)/(a*a)); float radiusAngle = b/(float) Math.Sqrt(1 - (eccentricity*eccentricity)*Math.Pow(Math.Cos(radians), 2)); // Convert the radius back to Cartesian coordinates return new Vector2f(ptCenter.X + radiusAngle*(float) Math.Cos(radians), ptCenter.Y + radiusAngle*(float) Math.Sin(radians)); }
public bool Equals(Vector2f obj) { return obj.x == this.x && obj.y == this.y; }
/// </summary> /// Check if the components of two vectors are approximate equals. /// <param name="obj">Vector2f.</param> /// <param name="threshold">Maximun tolerance.</param> /// <returns>True if the three components are almost equal or false in anyother case.</returns> public bool Equals(Vector2f obj, float threshold) { if (Math.Abs(obj.X - this.x) > threshold) { return false; } if (Math.Abs(obj.Y - this.y) > threshold) { return false; } return true; }
/// <summary> /// Obtains the angle between two vectors. /// </summary> /// <param name="u">Vector2f.</param> /// <param name="v">Vector2f.</param> /// <returns>Angle in radians.</returns> public static float AngleBetween(Vector2f u, Vector2f v) { float cos = DotProduct(u, v) / (u.Modulus() * v.Modulus()); if (MathHelper.IsOne(cos)) { return 0; } if (MathHelper.IsOne(-cos)) { return (float)Math.PI; } return (float)Math.Acos(cos); //if (AreParallel(u, v)) //{ // if (Math.Sign(u.X) == Math.Sign(v.X) && Math.Sign(u.Y) == Math.Sign(v.Y)) // { // return 0; // } // return (float)Math.PI; //} //Vector3f normal = Vector3f.CrossProduct(new Vector3f(u.X, u.Y, 0), new Vector3f(v.X, v.Y, 0)); //if (normal.Z < 0) //{ // return (float)(2 * Math.PI - Math.Acos(DotProduct(u, v) / (u.Modulus() * v.Modulus()))); //} //return (float)(Math.Acos(DotProduct(u, v) / (u.Modulus() * v.Modulus()))); }
/// <summary> /// Converts the arc in a list of vertexes. /// </summary> /// <param name="precision">Number of vertexes generated.</param> /// <param name="weldThreshold">Tolerance to consider if two new generated vertexes are equal.</param> /// <returns>A list vertexes that represents the arc expresed in object coordinate system.</returns> public List<Vector2f> PoligonalVertexes(int precision, float weldThreshold) { if (precision < 2) throw new ArgumentOutOfRangeException("precision", precision, "The arc precision must be greater or equal to two"); List<Vector2f> ocsVertexes = new List<Vector2f>(); float start = (float)(this.anguloInicio * MathHelper.DegToRad); float end = (float)(this.anguloFin * MathHelper.DegToRad); if (2 * this.radio >= weldThreshold) { float angulo = (end - start) / precision; Vector2f prevPoint; Vector2f firstPoint; float sine = (float)(this.radio * Math.Sin(start)); float cosine = (float)(this.radio * Math.Cos(start)); firstPoint = new Vector2f(cosine + this.centro.X, sine + this.centro.Y); ocsVertexes.Add(firstPoint); prevPoint = firstPoint; for (int i = 1; i <= precision; i++) { sine = (float)(this.radio * Math.Sin(start + angulo * i)); cosine = (float)(this.radio * Math.Cos(start + angulo * i)); Vector2f point = new Vector2f(cosine + this.centro.X, sine + this.centro.Y); if (!point.Equals(prevPoint, weldThreshold) && !point.Equals(firstPoint, weldThreshold)) { ocsVertexes.Add(point); prevPoint = point; } } } return ocsVertexes; }
/// <summary> /// Initializes a new instance of the <c>LightWeightPolylineVertex</c> class. /// </summary> /// <param name="x">X coordinate.</param> /// <param name="y">Y coordinate.</param> public LightWeightPolylineVertex(float x, float y) { this.location = new Vector2f(x, y); this.bulge = 0.0f; this.beginThickness = 0.0f; this.endThickness = 0.0f; }
/// <summary> /// Obtains the midpoint. /// </summary> /// <param name="u">Vector2f.</param> /// <param name="v">Vector2f.</param> /// <returns>Vector2f.</returns> public static Vector2f MidPoint(Vector2f u, Vector2f v) { return new Vector2f((v.X + u.X) * 0.5F, (v.Y + u.Y) * 0.5F); }
/// <summary> /// Obtains the dot product of two vectors. /// </summary> /// <param name="u">Vector2f.</param> /// <param name="v">Vector2f.</param> /// <returns>The dot product.</returns> public static float DotProduct(Vector2f u, Vector2f v) { return (u.X * v.X) + (u.Y * v.Y); }
/// <summary> /// Obtains the distance between two points. /// </summary> /// <param name="u">Vector2f.</param> /// <param name="v">Vector2f.</param> /// <returns>Distancie.</returns> public static float Distance(Vector2f u, Vector2f v) { return (float)(Math.Sqrt((u.X - v.X) * (u.X - v.X) + (u.Y - v.Y) * (u.Y - v.Y))); }
/// <summary> /// Obtains the cross product of two vectors. /// </summary> /// <param name="u">Vector2f.</param> /// <param name="v">Vector2f.</param> /// <returns>Vector2f.</returns> public static float CrossProduct(Vector2f u, Vector2f v) { return (u.X * v.Y) - (u.Y * v.X); }
/// <summary> /// Checks if two vectors are perpendicular. /// </summary> /// <param name="u">Vector2f.</param> /// <param name="v">Vector2f.</param> /// <param name="threshold">Tolerance used.</param> /// <returns>True if are penpendicular or false in anyother case.</returns> public static bool ArePerpendicular(Vector2f u, Vector2f v, float threshold) { return MathHelper.IsZero(DotProduct(u, v), threshold); }
/// <summary> /// Checks if two vectors are parallel. /// </summary> /// <param name="u">Vector2f.</param> /// <param name="v">Vector2f.</param> /// <param name="threshold">Tolerance used.</param> /// <returns>True if are parallel or false in anyother case.</returns> public static bool AreParallel(Vector2f u, Vector2f v, float threshold) { float a = u.X * v.Y - u.Y * v.X; return MathHelper.IsZero(a, threshold); }
/// <summary> /// Initializes a new instance of the <c>LightWeightPolylineVertex</c> class. /// </summary> public LightWeightPolylineVertex() { this.location = Vector2f.Zero; this.bulge = 0.0f; this.beginThickness = 0.0f; this.endThickness = 0.0f; }
/// <summary> /// Initializes a new instance of the <c>LightWeightPolylineVertex</c> class. /// </summary> /// <param name="location">Lightweight polyline <see cref="netDxf.Vector2f">vertex</see> coordinates.</param> public LightWeightPolylineVertex(Vector2f location) { this.location = location; this.bulge = 0.0f; this.beginThickness = 0.0f; this.endThickness = 0.0f; }
/// <summary> /// Obtains the counter clockwise perpendicular vector . /// </summary> /// <param name="u">Vector2f.</param> /// <returns>Vector2f.</returns> public static Vector2f Perpendicular(Vector2f u) { return new Vector2f(-u.Y, u.X); }
/// <summary> /// Obtains a list of vertexes that represent the polyline approximating the curve segments as necessary. /// </summary> /// <param name="bulgePrecision">Curve segments precision (a value of zero means that no approximation will be made).</param> /// <param name="weldThreshold">Tolerance to consider if two new generated vertexes are equal.</param> /// <param name="bulgeThreshold">Minimun distance from which approximate curved segments of the polyline.</param> /// <returns>The return vertexes are expresed in object coordinate system.</returns> public List<Vector2f> PoligonalVertexes(int bulgePrecision, float weldThreshold, float bulgeThreshold) { List<Vector2f> ocsVertexes = new List<Vector2f>(); int index = 0; foreach (PolylineVertex vertex in this.Vertexes) { float bulge = vertex.Bulge; Vector2f p1; Vector2f p2; if (index == this.Vertexes.Count - 1) { p1 = new Vector2f(vertex.Location.X, vertex.Location.Y); p2 = new Vector2f(this.vertexes[0].Location.X, this.vertexes[0].Location.Y); } else { p1 = new Vector2f(vertex.Location.X, vertex.Location.Y); p2 = new Vector2f(this.vertexes[index + 1].Location.X, this.vertexes[index + 1].Location.Y); } if (!p1.Equals(p2, weldThreshold)) { if (bulge == 0 || bulgePrecision == 0) { ocsVertexes.Add(p1); } else { float c = Vector2f.Distance(p1, p2); if (c >= bulgeThreshold) { float s = (c / 2) * Math.Abs(bulge); float r = ((c / 2) * (c / 2) + s * s) / (2 * s); float theta = (float)(4 * Math.Atan(Math.Abs(bulge))); float gamma = (float)((Math.PI - theta) / 2); float phi; if (bulge > 0) { phi = Vector2f.AngleBetween(Vector2f.UnitX, p2 - p1) + gamma; } else { phi = Vector2f.AngleBetween(Vector2f.UnitX, p2 - p1) - gamma; } Vector2f center = new Vector2f((float)(p1.X + r * Math.Cos(phi)), (float)(p1.Y + r * Math.Sin(phi))); Vector2f a1 = p1 - center; float angle = 4 * ((float)(Math.Atan(bulge))) / (bulgePrecision + 1); ocsVertexes.Add(p1); for (int i = 1; i <= bulgePrecision; i++) { Vector2f curvePoint = new Vector2f(); Vector2f prevCurvePoint = new Vector2f(this.vertexes[this.vertexes.Count - 1].Location.X, this.vertexes[this.vertexes.Count - 1].Location.Y); curvePoint.X = center.X + (float)(Math.Cos(i * angle) * a1.X - Math.Sin(i * angle) * a1.Y); curvePoint.Y = center.Y + (float)(Math.Sin(i * angle) * a1.X + Math.Cos(i * angle) * a1.Y); if (!curvePoint.Equals(prevCurvePoint, weldThreshold) && !curvePoint.Equals(p2, weldThreshold)) { ocsVertexes.Add(curvePoint); } } } else { ocsVertexes.Add(p1); } } } index++; } return ocsVertexes; }
/// <summary> /// Rounds the components of a vector. /// </summary> /// <param name="u">Vector2f.</param> /// <param name="numDigits">Number of significative defcimal digits.</param> /// <returns>Vector2f.</returns> public static Vector2f Round(Vector2f u, int numDigits) { return new Vector2f((float)Math.Round(u.X, numDigits), (float)Math.Round(u.Y, numDigits)); }
/// <summary> /// Obtains the square distance between two points. /// </summary> /// <param name="u">Vector2f.</param> /// <param name="v">Vector2f.</param> /// <returns>Square distance.</returns> public static float SquareDistance(Vector2f u, Vector2f v) { return (u.X - v.X) * (u.X - v.X) + (u.Y - v.Y) * (u.Y - v.Y); }
/// <summary> /// Initializes a new instance of the <c>PolylineVertex</c> class. /// </summary> public PolylineVertex() : base(DxfCodigoObjeto.Vertex) { this.flags = VertexTypeFlags.PolylineVertex; this.location = Vector2f.Zero; //this.layer = Layer.Default; //this.color = AciColor.ByLayer; //this.lineType = LineType.ByLayer; this.bulge = 0.0f; this.beginThickness = 0.0f; this.endThickness = 0.0f; }