/// <summary> /// Gets the rotation matrix from the normal vector (extrusion direction) of an entity. /// </summary> /// <param name="zAxis">Normal vector.</param> /// <returns>Rotation matriz.</returns> public static Matrix3d ArbitraryAxis(Vector3d zAxis) { zAxis.Normalize(); Vector3d wY = Vector3d.UnitarioY; Vector3d wZ = Vector3d.UnitarioZ; Vector3d aX; if ((Math.Abs(zAxis.X) < 1 / 64.0) && (Math.Abs(zAxis.Y) < 1 / 64.0)) aX = Vector3d.CrossProduct(wY, zAxis); else aX = Vector3d.CrossProduct(wZ, zAxis); aX.Normalize(); Vector3d aY = Vector3d.CrossProduct(zAxis, aX); aY.Normalize(); return new Matrix3d(aX.X, aY.X, zAxis.X, aX.Y, aY.Y, zAxis.Y, aX.Z, aY.Z, zAxis.Z); }
/// <summary> /// Obtains the square distance between two points. /// </summary> /// <param name="u">Vector3d.</param> /// <param name="v">Vector3d.</param> /// <returns>Square distance.</returns> public static double SquareDistance(Vector3d u, Vector3d v) { return (u.X - v.X) * (u.X - v.X) + (u.Y - v.Y) * (u.Y - v.Y) + (u.Z - v.Z) * (u.Z - v.Z); }
/// <summary> /// Rounds the components of a vector. /// </summary> /// <param name="u">Vector3d.</param> /// <param name="numDigits">Number of significative defcimal digits.</param> /// <returns>Vector3d.</returns> public static Vector3d Round(Vector3d u, int numDigits) { return new Vector3d((Math.Round(u.X, numDigits)), (Math.Round(u.Y, numDigits)), (Math.Round(u.Z, numDigits))); }
/// <summary> /// Obtains the midpoint. /// </summary> /// <param name="u">Vector3d.</param> /// <param name="v">Vector3d.</param> /// <returns>Vector3d.</returns> public static Vector3d MidPoint(Vector3d u, Vector3d v) { return new Vector3d((v.X + u.X) * 0.5F, (v.Y + u.Y) * 0.5F, (v.Z + u.Z) * 0.5F); }
/// <summary> /// Obtains the dot product of two vectors. /// </summary> /// <param name="u">Vector3d.</param> /// <param name="v">Vector3d.</param> /// <returns>The dot product.</returns> public static double DotProduct(Vector3d u, Vector3d v) { return (u.X * v.X) + (u.Y * v.Y) + (u.Z * v.Z); }
/// <summary> /// Obtains the distance between two points. /// </summary> /// <param name="u">Vector3d.</param> /// <param name="v">Vector3d.</param> /// <returns>Distancie.</returns> public static double Distance(Vector3d u, Vector3d v) { return (Math.Sqrt((u.X - v.X) * (u.X - v.X) + (u.Y - v.Y) * (u.Y - v.Y) + (u.Z - v.Z) * (u.Z - v.Z))); }
/// <summary> /// Obtains the cross product of two vectors. /// </summary> /// <param name="u">Vector3d.</param> /// <param name="v">Vector3d.</param> /// <returns>Vector3d.</returns> public static Vector3d CrossProduct(Vector3d u, Vector3d v) { double a = u.Y * v.Z - u.Z * v.Y; double b = u.Z * v.X - u.X * v.Z; double c = u.X * v.Y - u.Y * v.X; return new Vector3d(a, b, c); }
/// <summary> /// Transforms a point list between coordinate systems. /// </summary> /// <param name="points">Points to transform.</param> /// <param name="zAxis">Object normal vector.</param> /// <param name="from">Points coordinate system.</param> /// <param name="to">Coordinate system of the transformed points.</param> /// <returns>Transormed point list.</returns> public static IList<Vector3d> Transform(IList<Vector3d> points, Vector3d zAxis, CoordinateSystem from, CoordinateSystem to) { Matrix3d trans = ArbitraryAxis(zAxis); List<Vector3d> transPoints; if (from == CoordinateSystem.World && to == CoordinateSystem.Object) { transPoints = new List<Vector3d>(); trans = trans.Traspose(); foreach (Vector3d p in points) { transPoints.Add(trans * p); } return transPoints; } if (from == CoordinateSystem.Object && to == CoordinateSystem.World) { transPoints = new List<Vector3d>(); foreach (Vector3d p in points) { transPoints.Add(trans * p); } return transPoints; } return points; }
/// <summary> /// Checks if two vectors are parallel. /// </summary> /// <param name="u">Vector3d.</param> /// <param name="v">Vector3d.</param> /// <param name="threshold">Tolerance used.</param> /// <returns>True if are parallel or false in anyother case.</returns> public static bool AreParallel(Vector3d u, Vector3d v, double threshold) { double a = u.Y * v.Z - u.Z * v.Y; double b = u.Z * v.X - u.X * v.Z; double c = u.X * v.Y - u.Y * v.X; if (!MathHelper.IsZero(a, threshold)) { return false; } if (!MathHelper.IsZero(b, threshold)) { return false; } if (!MathHelper.IsZero(c, threshold)) { return false; } return true; }
/// <summary> /// Obtains the angle between two vectors. /// </summary> /// <param name="u">Vector3d.</param> /// <param name="v">Vector3d.</param> /// <returns>Angle in radians.</returns> public static double AngleBetween(Vector3d u, Vector3d v) { double cos = DotProduct(u, v) / (u.Modulus() * v.Modulus()); if (MathHelper.IsOne(cos)) { return 0; } if (MathHelper.IsOne(-cos)) { return Math.PI; } return Math.Acos(cos); }
private List<string> EliminarCodigoInnecesario(List<string> newList) { if (newList.Count > 0) { List<string> lista = new List<string>(); Vector3d punto1 = new Vector3d(0, 0, 0); Vector3d punto2; //if (newList[0] == "<polilinea>") // punto2 = new Vector3d(Convert.ToDouble(PuntoInicioX(newList[1])), Convert.ToDouble(PuntoInicioY(newList[1])), Convert.ToDouble(PuntoInicioZ(newList[1]))); //else punto2 = new Vector3d(Convert.ToDouble(PuntoInicioX(newList[0])), Convert.ToDouble(PuntoInicioY(newList[0])), Convert.ToDouble(PuntoInicioZ(newList[0]))); if (!(ObtenerDoubleTresDecimales(punto1) == ObtenerDoubleTresDecimales(punto2))) { //if (newList[0] != "<polilinea>") lista.Add(newList[0]); } int i = 1; while (i < newList.Count - 1) { //if (newList[i-1] == "<polilinea>") //{ // lista.Add(newList[i-1]); // while (newList[i] != "</polilinea>") // { // lista.Add(newList[i]); // i++; // } // lista.Add(newList[i]); // i=i+2; // continue; //} punto1 = new Vector3d(Convert.ToDouble(PuntoInicioX(newList[i])), Convert.ToDouble(PuntoInicioY(newList[i])), Convert.ToDouble(PuntoInicioZ(newList[i]))); punto2 = new Vector3d(Convert.ToDouble(PuntoInicioX(newList[i + 1])), Convert.ToDouble(PuntoInicioY(newList[i + 1])), Convert.ToDouble(PuntoInicioZ(newList[i + 1]))); if (ObtenerDoubleTresDecimales(punto1) == ObtenerDoubleTresDecimales(punto2)) { lista.Add(newList[i]); } else { lista.Add(newList[i]); lista.Add(newList[i + 1]); } i = i + 2; } //if(i<newList.Count-1) lista.Add(newList[i]); return lista; } return null; }
private List<string> OptimizarCodigoG(List<string> list) { List<string> newList = new List<string>(); Vector3d puntoActual = new Vector3d(0, 0, 0); //Eliminamos movimientos sobrantes list = QuitartMovimientos(list); // Variables int j; string tempFig; string auxiliar1; string auxiliar2; int posAux; int posFig; while (list.Count > 0) { //if (list[0] == "<polilinea>") //{ // while (list[0] != "</polilinea>") // { // newList.Add(list[0]); // list.RemoveAt(0); // } // newList.Add(list[0]); // list.RemoveAt(0); // continue; //} auxiliar1 = list[0]; posAux = 0; tempFig = list[1]; posFig = 1; j = 2; while (j <= list.Count - 1) { auxiliar2 = list[j]; if (ObtieneDistancia( puntoActual, new Vector3d( Convert.ToDouble(PuntoInicioX(auxiliar1)), Convert.ToDouble(PuntoInicioY(auxiliar1)), Convert.ToDouble(PuntoInicioZ(auxiliar1))) ) > ObtieneDistancia( puntoActual, new Vector3d( Convert.ToDouble(PuntoInicioX(auxiliar2)), Convert.ToDouble(PuntoInicioY(auxiliar2)), Convert.ToDouble(PuntoInicioZ(auxiliar2)) ) ) ) { auxiliar1 = auxiliar2; posAux = j; tempFig = list[j + 1]; posFig = j + 1; j = 0; } j = j + 2; } newList.Add(auxiliar1); newList.Add(tempFig); puntoActual = new Vector3d(Convert.ToDouble(PuntoInicioX(tempFig)), Convert.ToDouble(PuntoInicioY(tempFig)), Convert.ToDouble(PuntoInicioZ(tempFig))); //Elimino los elementos agregados a la nueva lista list.RemoveAt(posAux); list.RemoveAt(posAux);//Vuelvo a eliminar el mismo, porque al eliminarlo por primera vez, se corren un indice menos. } //Eliminamos movimientos cuando el pto de fin de una figura coincide con el de la siguiente figura newList = EliminarCodigoInnecesario(newList); //Agregamos a cada G00 la instruccion para que levante en z, se desplace y baje. newList = AgregarAccionesAG00(newList); return newList; }
private Vector3d ObtenerDoubleTresDecimales(Vector3d num) { Vector3d d = new Vector3d(); d.X = Math.Round(num.X, 3); d.Y = Math.Round(num.Y, 3); d.Z = Math.Round(num.Z, 3); return d; }
/// </summary> /// Check if the components of two vectors are approximate equals. /// <param name="obj">Vector3d.</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(Vector3d obj, double threshold) { if (Math.Abs(obj.X - this.x) > threshold) { return false; } if (Math.Abs(obj.Y - this.y) > threshold) { return false; } if (Math.Abs(obj.Z - this.z) > threshold) { return false; } return true; }
/// <summary> /// Checks if two vectors are perpendicular. /// </summary> /// <param name="u">Vector3d.</param> /// <param name="v">Vector3d.</param> /// <param name="threshold">Tolerance used.</param> /// <returns>True if are penpendicular or false in anyother case.</returns> public static bool ArePerpendicular(Vector3d u, Vector3d v, double threshold) { return MathHelper.IsZero(DotProduct(u, v), threshold); }
public bool Equals(Vector3d obj) { return obj.x == this.x && obj.y == this.y && obj.z == this.z; }
/// <summary> /// Transforms a point between coordinate systems. /// </summary> /// <param name="point">Point to transform.</param> /// <param name="zAxis">Object normal vector.</param> /// <param name="from">Point coordinate system.</param> /// <param name="to">Coordinate system of the transformed point.</param> /// <returns>Transormed point.</returns> public static Vector3d Transform(Vector3d point, Vector3d zAxis, CoordinateSystem from, CoordinateSystem to) { Matrix3d trans = ArbitraryAxis(zAxis); if (from == CoordinateSystem.World && to == CoordinateSystem.Object) { trans = trans.Traspose(); return trans * point; } if (from == CoordinateSystem.Object && to == CoordinateSystem.World) { return trans * point; } return point; }