/// <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.UnitY; Vector3d wZ = Vector3d.UnitZ; 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> /// 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; }
/// <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; }
public bool Equals(Vector3d obj) { return obj.x == this.x && obj.y == this.y && obj.z == this.z; }
private void WriteAttribute(Attribute attrib, Vector3d puntoInsercion) { this.WriteCodePair(0, DxfObjectCode.Attribute); this.WriteCodePair(5, attrib.Handle); this.WriteCodePair(100, SubclassMarker.Entity); this.WriteEntityCommonCodes(attrib); this.WriteCodePair(100, SubclassMarker.Text); this.WriteCodePair(10, attrib.Definition.BasePoint.X + puntoInsercion.X); this.WriteCodePair(20, attrib.Definition.BasePoint.Y + puntoInsercion.Y); this.WriteCodePair(30, attrib.Definition.BasePoint.Z + puntoInsercion.Z); this.WriteCodePair(1, attrib.Value); this.WriteCodePair(40, attrib.Definition.Height); this.WriteCodePair(41, attrib.Definition.WidthFactor); this.WriteCodePair(50, attrib.Definition.Rotation); this.WriteCodePair(7, attrib.Definition.Style); this.WriteCodePair(100, SubclassMarker.Attribute); this.WriteCodePair(2, attrib.Definition.Id); this.WriteCodePair(70, (int) attrib.Definition.Flags); this.WriteCodePair(11, attrib.Definition.BasePoint.X + puntoInsercion.X); this.WriteCodePair(21, attrib.Definition.BasePoint.Y + puntoInsercion.Y); this.WriteCodePair(31, attrib.Definition.BasePoint.Z + puntoInsercion.Z); }
/// <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); }
/// </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> /// 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> /// 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 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 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 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> /// 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); }
/// <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; }
private Insert ReadInsert(ref CodeValuePair code) { string handle = string.Empty; Vector3d basePoint = Vector3d.Zero; Vector3d normal = Vector3d.UnitZ; Vector3d scale = new Vector3d(1, 1, 1); float rotation = 0.0f; Block block = null; Layer layer = Layer.Default; AciColor color = AciColor.ByLayer; LineType lineType = LineType.ByLayer; List<Attribute> attributes = new List<Attribute>(); Dictionary<ApplicationRegistry, XData> xData = new Dictionary<ApplicationRegistry, XData>(); code = this.ReadCodePair(); while (code.Code != 0) { switch (code.Code) { case 5: handle = code.Value; code = this.ReadCodePair(); break; case 2: block = this.GetBlock(code.Value); if (block == null) throw new DxfEntityException(DxfObjectCode.Insert, this.file, "Block " + code.Value + " not defined line " + this.fileLine); code = this.ReadCodePair(); break; case 8: //layer code layer = this.GetLayer(code.Value); code = this.ReadCodePair(); break; case 62: //aci color code color = new AciColor(short.Parse(code.Value)); code = this.ReadCodePair(); break; case 6: //type line code lineType = this.GetLineType(code.Value); code = this.ReadCodePair(); break; case 10: basePoint.X = double.Parse(code.Value); code = this.ReadCodePair(); break; case 20: basePoint.Y = double.Parse(code.Value); code = this.ReadCodePair(); break; case 30: basePoint.Z = double.Parse(code.Value); code = this.ReadCodePair(); break; case 41: scale.X = double.Parse(code.Value); code = this.ReadCodePair(); break; case 42: scale.X = double.Parse(code.Value); code = this.ReadCodePair(); break; case 43: scale.X = double.Parse(code.Value); code = this.ReadCodePair(); break; case 50: rotation = float.Parse(code.Value); code = this.ReadCodePair(); break; case 210: normal.X = double.Parse(code.Value); code = this.ReadCodePair(); break; case 220: normal.Y = double.Parse(code.Value); code = this.ReadCodePair(); break; case 230: normal.Z = double.Parse(code.Value); code = this.ReadCodePair(); break; case 1001: XData xDataItem = this.ReadXDataRecord(code.Value, ref code); xData.Add(xDataItem.ApplicationRegistry, xDataItem); break; default: if (code.Code >= 1000 && code.Code <= 1071) throw new DxfInvalidCodeValueEntityException(code.Code, code.Value, this.file, "The extended data of an entity must start with the application registry code " + this.fileLine); code = this.ReadCodePair(); break; } } // if there are attributes string endSequenceHandle = string.Empty; Layer endSequenceLayer = Layer.Default; if (code.Value == DxfObjectCode.Attribute) { while (code.Value != StringCode.EndSequence) { if (code.Value == DxfObjectCode.Attribute) { Debug.Assert(code.Code == 0); Attribute attribute = this.ReadAttribute(block, ref code); attributes.Add(attribute); } } // read the end end sequence object until a new element is found code = this.ReadCodePair(); while (code.Code != 0) { switch (code.Code) { case 5: endSequenceHandle = code.Value; code = this.ReadCodePair(); break; case 8: endSequenceLayer = this.GetLayer(code.Value); code = this.ReadCodePair(); break; default: code = this.ReadCodePair(); break; } } } Insert insert = new Insert(block) { Color = color, Layer = layer, LineType = lineType, InsertionPoint = basePoint, Rotation = rotation, Scale = scale, Normal = normal, Handle = handle }; insert.EndSequence.Handle = endSequenceHandle; insert.EndSequence.Layer = endSequenceLayer; insert.Attributes.Clear(); insert.Attributes.AddRange(attributes); insert.XData = xData; return insert; }
/// <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); }
private Vertex ReadVertex(ref CodeValuePair code) { string handle = string.Empty; Layer layer = Layer.Default; AciColor color = AciColor.ByLayer; LineType lineType = LineType.ByLayer; Vector3d location = new Vector3d(); Dictionary<ApplicationRegistry, XData> xData = new Dictionary<ApplicationRegistry, XData>(); float endThickness = 0.0f; float beginThickness = 0.0f; double bulge = 0.0; List<int> vertexIndexes = new List<int>(); VertexTypeFlags flags = VertexTypeFlags.PolylineVertex; code = this.ReadCodePair(); while (code.Code != 0) { switch (code.Code) { case 5: handle = code.Value; code = this.ReadCodePair(); break; case 8: layer = this.GetLayer(code.Value); code = this.ReadCodePair(); break; case 62: color = new AciColor(short.Parse(code.Value)); code = this.ReadCodePair(); break; case 6: lineType = this.GetLineType(code.Value); code = this.ReadCodePair(); break; case 10: location.X = double.Parse(code.Value); code = this.ReadCodePair(); break; case 20: location.Y = double.Parse(code.Value); code = this.ReadCodePair(); break; case 30: location.Z = double.Parse(code.Value); code = this.ReadCodePair(); break; case 40: beginThickness = float.Parse(code.Value); code = this.ReadCodePair(); break; case 41: endThickness = float.Parse(code.Value); code = this.ReadCodePair(); break; case 42: bulge = double.Parse(code.Value); code = this.ReadCodePair(); break; case 70: flags = (VertexTypeFlags) int.Parse(code.Value); code = this.ReadCodePair(); break; case 71: vertexIndexes.Add(int.Parse(code.Value)); code = this.ReadCodePair(); break; case 72: vertexIndexes.Add(int.Parse(code.Value)); code = this.ReadCodePair(); break; case 73: vertexIndexes.Add(int.Parse(code.Value)); code = this.ReadCodePair(); break; case 74: vertexIndexes.Add(int.Parse(code.Value)); code = this.ReadCodePair(); break; case 1001: XData xDataItem = this.ReadXDataRecord(code.Value, ref code); xData.Add(xDataItem.ApplicationRegistry, xDataItem); break; default: if (code.Code >= 1000 && code.Code <= 1071) throw new DxfInvalidCodeValueEntityException(code.Code, code.Value, this.file, "The extended data of an entity must start with the application registry code " + this.fileLine); code = this.ReadCodePair(); break; } } return new Vertex { Flags = flags, Location = location, BeginThickness = beginThickness, Bulge = bulge, Color = color, EndThickness = endThickness, Layer = layer, LineType = lineType, VertexIndexes = vertexIndexes.ToArray(), XData = xData, Handle = handle }; //IVertex vertex; //if ((flags & (VertexTypeFlags.PolyfaceMeshVertex | VertexTypeFlags.Polygon3dMesh)) == (VertexTypeFlags.PolyfaceMeshVertex | VertexTypeFlags.Polygon3dMesh)) //{ // vertex = new PolyfaceMeshVertex // { // Location=location // }; // vertex.XData=xData; //} //else if ((flags & (VertexTypeFlags.PolyfaceMeshVertex)) == (VertexTypeFlags.PolyfaceMeshVertex)) //{ // vertex = new PolyfaceMeshFace(vertexIndexes.ToArray()); //} //else if ((flags & (VertexTypeFlags.Polyline3dVertex)) == (VertexTypeFlags.Polyline3dVertex)) //{ // vertex = new Polyline3dVertex // { // Location = location, // }; // vertex.XData=xData; //} //else //{ // vertex = new PolylineVertex // { // Location =new Vector2d(location.X, location.Y), // Bulge = bulge, // BeginThickness = beginThickness, // EndThickness = endThickness // }; // vertex.XData=xData; //} //return vertex; }
private static void WriteDxfFile() { DxfDocument dxf = new DxfDocument(); //arc Arc arc = new Arc(new Vector3d(10, 10, 0), 10, 45, 135); arc.Layer = new Layer("arc"); arc.Layer.Color.Index = 1; dxf.AddEntity(arc); //xData sample XData xdata = new XData(new ApplicationRegistry("netDxf")); xdata.XDataRecord.Add(new XDataRecord(XDataCode.String, "extended data with netDxf")); xdata.XDataRecord.Add(XDataRecord.OpenControlString); xdata.XDataRecord.Add(new XDataRecord(XDataCode.WorldSpacePositionX, 0)); xdata.XDataRecord.Add(new XDataRecord(XDataCode.WorldSpacePositionY, 0)); xdata.XDataRecord.Add(new XDataRecord(XDataCode.WorldSpacePositionZ, 0)); xdata.XDataRecord.Add(XDataRecord.CloseControlString); XData xdata2 = new XData(new ApplicationRegistry("other application")); xdata2.XDataRecord.Add(new XDataRecord(XDataCode.String, "extended data with netDxf")); xdata2.XDataRecord.Add(XDataRecord.OpenControlString); xdata2.XDataRecord.Add(new XDataRecord(XDataCode.String, "string record")); xdata2.XDataRecord.Add(new XDataRecord(XDataCode.Real, 15.5)); xdata2.XDataRecord.Add(new XDataRecord(XDataCode.Long, 350)); xdata2.XDataRecord.Add(XDataRecord.CloseControlString); //circle Vector3d extrusion = new Vector3d(1, 1, 1); Vector3d centerWCS = new Vector3d(1, 1, 1); Vector3d centerOCS = MathHelper.Transform(centerWCS, extrusion, MathHelper.CoordinateSystem.World, MathHelper.CoordinateSystem.Object); Circle circle = new Circle(centerOCS, 5); circle.Layer = new Layer("circle with spaces"); circle.Layer.Color=AciColor.Yellow; circle.LineType = LineType.Dashed; circle.Normal = extrusion; circle.XData=new Dictionary<ApplicationRegistry, XData> { {xdata.ApplicationRegistry, xdata}, {xdata2.ApplicationRegistry, xdata2} }; dxf.AddEntity(circle); //points Point point1 = new Point(new Vector3d(-3, -3, 0)); point1.Layer = new Layer("point"); point1.Color = new AciColor(30); Point point2 = new Point(new Vector3d(1, 1, 1)); point2.Layer = point1.Layer; point2.Layer.Color.Index = 9; point2.Normal = new Vector3d(1, 1, 1); dxf.AddEntity(point1); dxf.AddEntity(point2); //3dface Face3d face3D = new Face3d(new Vector3d(-5, -5, 5), new Vector3d(5, -5, 5), new Vector3d(5, 5, 5), new Vector3d(-5, 5, 5)); face3D.Layer = new Layer("3dface"); face3D.Layer.Color.Index = 3; dxf.AddEntity(face3D); //polyline PolylineVertex polyVertex; List<PolylineVertex> polyVertexes = new List<PolylineVertex>(); polyVertex = new PolylineVertex(new Vector2d(-50, -50)); polyVertex.BeginThickness = 2; polyVertexes.Add(polyVertex); polyVertex = new PolylineVertex(new Vector2d(50, -50)); polyVertex.BeginThickness = 1; polyVertexes.Add(polyVertex); polyVertex = new PolylineVertex(new Vector2d(50, 50)); polyVertex.Bulge = 1; polyVertexes.Add(polyVertex); polyVertex = new PolylineVertex(new Vector2d(-50, 50)); polyVertexes.Add(polyVertex); Polyline polyline2d = new Polyline(polyVertexes, true); polyline2d.Layer = new Layer("polyline2d"); polyline2d.Layer.Color.Index = 5; polyline2d.Normal = new Vector3d(1, 1, 1); polyline2d.Elevation = 100.0; dxf.AddEntity(polyline2d); //lightweight polyline LightWeightPolylineVertex lwVertex; List<LightWeightPolylineVertex> lwVertexes = new List<LightWeightPolylineVertex>(); lwVertex = new LightWeightPolylineVertex(new Vector2d(-25, -25)); lwVertex.BeginThickness = 2; lwVertexes.Add(lwVertex); lwVertex = new LightWeightPolylineVertex(new Vector2d(25, -25)); lwVertex.BeginThickness = 1; lwVertexes.Add(lwVertex); lwVertex = new LightWeightPolylineVertex(new Vector2d(25, 25)); lwVertex.Bulge = 1; lwVertexes.Add(lwVertex); lwVertex = new LightWeightPolylineVertex(new Vector2d(-25, 25)); lwVertexes.Add(lwVertex); LightWeightPolyline lwPolyline = new LightWeightPolyline(lwVertexes, true); lwPolyline.Layer = new Layer("lwpolyline"); lwPolyline.Layer.Color.Index = 5; lwPolyline.Normal = new Vector3d(1, 1, 1); lwPolyline.Elevation = 100.0; dxf.AddEntity(lwPolyline); //line Line line = new Line(new Vector3d(0, 0, 0), new Vector3d(10, 10, 10)); line.Layer = new Layer("line"); line.Layer.Color.Index = 6; dxf.AddEntity(line); //3d polyline Polyline3dVertex vertex; List<Polyline3dVertex> vertexes = new List<Polyline3dVertex>(); vertex = new Polyline3dVertex(new Vector3d(-50, -50, 0)); vertexes.Add(vertex); vertex = new Polyline3dVertex(new Vector3d(50, -50, 10)); vertexes.Add(vertex); vertex = new Polyline3dVertex(new Vector3d(50, 50, 25)); vertexes.Add(vertex); vertex = new Polyline3dVertex(new Vector3d(-50, 50, 50)); vertexes.Add(vertex); Polyline3d polyline = new Polyline3d(vertexes, true); polyline.Layer = new Layer("polyline3d"); polyline.Layer.Color.Index = 24; dxf.AddEntity(polyline); //block definition Block block = new Block("TestBlock"); block.Entities.Add(new Line(new Vector3d(-5, -5, 5), new Vector3d(5, 5, 5))); block.Entities.Add(new Line(new Vector3d(5, -5, 5), new Vector3d(-5, 5, 5))); //insert Insert insert = new Insert(block, new Vector3d(5, 5, 5)); insert.Layer = new Layer("insert"); insert.Layer.Color.Index = 4; dxf.AddEntity(insert); //text TextStyle style=new TextStyle("True type font","Arial.ttf"); Text text = new Text("Hello world!", Vector3d.Zero, 10.0f,style); text.Layer = new Layer("text"); text.Layer.Color.Index = 8; text.Alignment = TextAlignment.TopRight; dxf.AddEntity(text); dxf.Save("AutoCad2007.dxf", DxfVersion.AutoCad2007); dxf.Save("AutoCad2004.dxf", DxfVersion.AutoCad2004); dxf.Save("AutoCad2000.dxf", DxfVersion.AutoCad2000); dxf.Save("AutoCad12.dxf", DxfVersion.AutoCad12); }