private List <EntityObject> CreateSquareCap(Vector2 start, Vector2 end, Matrix3 transformation, AciColor color1, Linetype linetype1, AciColor color2, Linetype linetype2) { List <EntityObject> entities = new List <EntityObject>(); Vector2 midPoint = Vector2.MidPoint(start, end); if (!color1.Equals(color2) || !linetype1.Equals(linetype2)) { Line line1 = this.CreateLine(start, midPoint, color1, linetype1); line1.TransformBy(transformation, Vector3.Zero); entities.Add(line1); Line line2 = this.CreateLine(midPoint, end, color2, linetype2); line2.TransformBy(transformation, Vector3.Zero); entities.Add(line2); } else { Line line = this.CreateLine(start, end, color1, linetype1); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } return(entities); }
/// <summary> /// Decompose the actual multiline in its internal entities, <see cref="Line">lines</see> and <see cref="Arc">arcs</see>. /// </summary> /// <returns>A list of <see cref="Line">lines</see> and <see cref="Arc">arcs</see> that made up the multiline.</returns> public List <EntityObject> Explode() { List <EntityObject> entities = new List <EntityObject>(); Matrix3 transformation = MathHelper.ArbitraryAxis(this.Normal); // precomputed points at mline vertexes for start and end caps calculations Vector2[][] cornerVextexes = new Vector2[this.vertexes.Count][]; for (int i = 0; i < this.vertexes.Count; i++) { MLineVertex vertex = this.vertexes[i]; MLineVertex nextVertex; if (this.IsClosed && i == this.vertexes.Count - 1) { nextVertex = this.vertexes[0]; } else if (!this.IsClosed && i == this.vertexes.Count - 1) { continue; } else { nextVertex = this.vertexes[i + 1]; cornerVextexes[i + 1] = new Vector2[this.style.Elements.Count]; } cornerVextexes[i] = new Vector2[this.style.Elements.Count]; for (int j = 0; j < this.style.Elements.Count; j++) { if (vertex.Distances[j].Count == 0) { continue; } Vector2 refStart = vertex.Position + vertex.Miter * vertex.Distances[j][0]; cornerVextexes[i][j] = refStart; for (int k = 1; k < vertex.Distances[j].Count; k++) { Vector2 start = refStart + vertex.Direction * vertex.Distances[j][k]; Vector2 end; if (k >= vertex.Distances[j].Count - 1) { end = nextVertex.Position + nextVertex.Miter * nextVertex.Distances[j][0]; if (!this.IsClosed) { cornerVextexes[i + 1][j] = end; } } else { end = refStart + vertex.Direction * vertex.Distances[j][k + 1]; k++; // skip next segment it is a blank space } Line line = this.CreateLine(start, end, this.style.Elements[j].Color, this.style.Elements[j].Linetype); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } if (this.style.Flags.HasFlag(MLineStyleFlags.DisplayJoints)) { AciColor color1 = this.style.Elements[0].Color; AciColor color2 = this.style.Elements[this.style.Elements.Count - 1].Color; Linetype linetype1 = this.style.Elements[0].Linetype; Linetype linetype2 = this.style.Elements[this.style.Elements.Count - 1].Linetype; for (int i = 0; i < cornerVextexes.Length; i++) { if (!this.IsClosed && (i == 0 || i == cornerVextexes.Length - 1)) { continue; } Vector2 start = cornerVextexes[i][0]; Vector2 end = cornerVextexes[i][cornerVextexes[0].Length - 1]; entities.AddRange(this.CreateSquareCap(start, end, transformation, color1, linetype1, color2, linetype2)); } } // when the mline is closed there are no caps if (this.IsClosed) { return(entities); } if (!this.NoStartCaps) { if (this.style.Flags.HasFlag(MLineStyleFlags.StartRoundCap)) { AciColor color1 = this.style.Elements[0].Color; AciColor color2 = this.style.Elements[this.style.Elements.Count - 1].Color; Linetype linetype1 = this.style.Elements[0].Linetype; Linetype linetype2 = this.style.Elements[this.style.Elements.Count - 1].Linetype; Vector2 start = cornerVextexes[0][0]; Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1]; entities.AddRange(this.scale >= 0 ? this.CreateRoundCap(start, end, transformation, color1, linetype1, color2, linetype2) : this.CreateRoundCap(end, start, transformation, color2, linetype2, color1, linetype1)); } if (this.style.Flags.HasFlag(MLineStyleFlags.StartInnerArcsCap)) { int j = (int)(this.style.Elements.Count / 2.0); // Math.Floor for (int i = 1; i < j; i++) { AciColor color1 = this.style.Elements[i].Color; AciColor color2 = this.style.Elements[this.style.Elements.Count - 1 - i].Color; Linetype linetype1 = this.style.Elements[i].Linetype; Linetype linetype2 = this.style.Elements[this.style.Elements.Count - 1 - i].Linetype; Vector2 start = cornerVextexes[0][i]; Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1 - i]; entities.AddRange(this.scale >= 0 ? this.CreateRoundCap(start, end, transformation, color1, linetype1, color2, linetype2) : this.CreateRoundCap(end, start, transformation, color2, linetype2, color1, linetype1)); } } if (this.style.Flags.HasFlag(MLineStyleFlags.StartSquareCap)) { AciColor color1 = this.style.Elements[0].Color; AciColor color2 = this.style.Elements[this.style.Elements.Count - 1].Color; Linetype linetype1 = this.style.Elements[0].Linetype; Linetype linetype2 = this.style.Elements[this.style.Elements.Count - 1].Linetype; Vector2 start = cornerVextexes[0][0]; Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1]; entities.AddRange(this.CreateSquareCap(start, end, transformation, color1, linetype1, color2, linetype2)); } } if (!this.NoEndCaps) { if (this.style.Flags.HasFlag(MLineStyleFlags.EndRoundCap)) { AciColor color1 = this.style.Elements[this.style.Elements.Count - 1].Color; AciColor color2 = this.style.Elements[0].Color; Linetype linetype1 = this.style.Elements[this.style.Elements.Count - 1].Linetype; Linetype linetype2 = this.style.Elements[0].Linetype; Vector2 start = cornerVextexes[this.vertexes.Count - 1][cornerVextexes[0].Length - 1]; Vector2 end = cornerVextexes[this.vertexes.Count - 1][0]; entities.AddRange(this.scale >= 0 ? this.CreateRoundCap(start, end, transformation, color1, linetype1, color2, linetype2) : this.CreateRoundCap(end, start, transformation, color2, linetype2, color1, linetype1)); } if (this.style.Flags.HasFlag(MLineStyleFlags.EndInnerArcsCap)) { int j = (int)(this.style.Elements.Count / 2.0); // Math.Floor for (int i = 1; i < j; i++) { AciColor color1 = this.style.Elements[this.style.Elements.Count - 1 - i].Color; AciColor color2 = this.style.Elements[i].Color; Linetype linetype1 = this.style.Elements[this.style.Elements.Count - 1 - i].Linetype; Linetype linetype2 = this.style.Elements[i].Linetype; Vector2 start = cornerVextexes[this.vertexes.Count - 1][cornerVextexes[0].Length - 1 - i]; Vector2 end = cornerVextexes[this.vertexes.Count - 1][i]; entities.AddRange(this.scale >= 0 ? this.CreateRoundCap(start, end, transformation, color1, linetype1, color2, linetype2) : this.CreateRoundCap(end, start, transformation, color2, linetype2, color1, linetype1)); } } if (this.style.Flags.HasFlag(MLineStyleFlags.EndSquareCap)) { AciColor color1 = this.style.Elements[this.style.Elements.Count - 1].Color; AciColor color2 = this.style.Elements[0].Color; Linetype linetype1 = this.style.Elements[this.style.Elements.Count - 1].Linetype; Linetype linetype2 = this.style.Elements[0].Linetype; Vector2 start = cornerVextexes[this.vertexes.Count - 1][cornerVextexes[0].Length - 1]; Vector2 end = cornerVextexes[this.vertexes.Count - 1][0]; entities.AddRange(this.CreateSquareCap(start, end, transformation, color1, linetype1, color2, linetype2)); } } return(entities); }
/// <summary> /// Decompose the actual multiline in its internal entities, <see cref="Line">lines</see> and <see cref="Arc">arcs</see>. /// </summary> /// <returns>A list of <see cref="Line">lines</see> and <see cref="Arc">arcs</see> that made up the multiline.</returns> /// <exception cref="InvalidOperationException">An exception will be thrown if the number of distances for a given MLineStyleElement is not an even number.</exception> public List <EntityObject> Explode() { Matrix3 transformation = MathHelper.ArbitraryAxis(Normal); List <EntityObject> entities = new List <EntityObject>(); // precomputed points at mline vertexes for start and end caps calculations Vector2[][] cornerVextexes = new Vector2[vertexes.Count][]; for (int i = 0; i < vertexes.Count; i++) { MLineVertex vertex = vertexes[i]; MLineVertex nextVertex; if (IsClosed && i == vertexes.Count - 1) { nextVertex = vertexes[0]; } else if (!IsClosed && i == vertexes.Count - 1) { continue; } else { nextVertex = vertexes[i + 1]; cornerVextexes[i + 1] = new Vector2[style.Elements.Count]; } cornerVextexes[i] = new Vector2[style.Elements.Count]; for (int j = 0; j < style.Elements.Count; j++) { if (style.Elements.Count % 2 != 0) { throw new InvalidOperationException("The number of distances for a given MLineStyleElement must be an even number."); } Vector2 refStart = vertex.Position + vertex.Miter * vertex.Distances[j][0]; cornerVextexes[i][j] = refStart; for (int k = 1; k < vertex.Distances[j].Count; k++) { Vector2 start = refStart + vertex.Direction * vertex.Distances[j][k]; Vector2 end; if (k >= vertex.Distances[j].Count - 1) { end = nextVertex.Position + nextVertex.Miter * nextVertex.Distances[j][0]; if (!IsClosed) { cornerVextexes[i + 1][j] = end; } } else { end = refStart + vertex.Direction * vertex.Distances[j][k + 1]; k++; // skip next segment it is a blank space } Line line = CreateLine(start, end, style.Elements[j].Color, style.Elements[j].Linetype); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } if (style.Flags.HasFlag(MLineStyleFlags.DisplayJoints)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); for (int i = 0; i < cornerVextexes.Length; i++) { if (!IsClosed && (i == 0 || i == cornerVextexes.Length - 1)) { continue; } Vector2 start = cornerVextexes[i][0]; Vector2 end = cornerVextexes[i][cornerVextexes[0].Length - 1]; Vector2 midPoint = Vector2.MidPoint(start, end); if (trim) { Line line1 = CreateLine(start, midPoint, color1, linetype1); line1.TransformBy(transformation, Vector3.Zero); entities.Add(line1); Line line2 = CreateLine(midPoint, end, color2, linetype2); line2.TransformBy(transformation, Vector3.Zero); entities.Add(line2); } else { Line line = CreateLine(start, end, color1, linetype1); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } // when the mline is closed there are no caps if (IsClosed) { return(entities); } if (!NoStartCaps) { if (style.Flags.HasFlag(MLineStyleFlags.StartRoundCap)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 center = Vector2.MidPoint(cornerVextexes[0][0], cornerVextexes[0][cornerVextexes.Length - 1]); Vector2 start = cornerVextexes[0][0]; //Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1]; double startAngle = Vector2.Angle(start - center) * MathHelper.RadToDeg; //double endAngle = Vector2.Angle(end - center) * MathHelper.RadToDeg; double endAngle = startAngle + 180.0; double radius = (start - center).Modulus(); if (trim) { double midAngle = startAngle + 90.0; Arc arc1 = CreateArc(center, radius, startAngle, midAngle, color1, linetype1); arc1.TransformBy(transformation, Vector3.Zero); entities.Add(arc1); Arc arc2 = CreateArc(center, radius, midAngle, endAngle, color2, linetype2); arc2.TransformBy(transformation, Vector3.Zero); entities.Add(arc2); } else { Arc arc = CreateArc(center, radius, startAngle, endAngle, color1, linetype1); arc.TransformBy(transformation, Vector3.Zero); entities.Add(arc); } } if (style.Flags.HasFlag(MLineStyleFlags.StartInnerArcsCap)) { Vector2 center = Vector2.MidPoint(cornerVextexes[0][0], cornerVextexes[0][cornerVextexes.Length - 1]);; int j = (int)Math.Floor(style.Elements.Count / 2.0); for (int i = 1; i < j; i++) { AciColor color1 = style.Elements[i].Color; AciColor color2 = style.Elements[style.Elements.Count - 1 - i].Color; Linetype linetype1 = style.Elements[i].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1 - i].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 start = cornerVextexes[0][i]; //Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1 - i]; double startAngle = Vector2.Angle(start - center) * MathHelper.RadToDeg; //double endAngle = Vector2.Angle(end - center) * MathHelper.RadToDeg; double endAngle = startAngle + 180.0; double radius = (start - center).Modulus(); if (trim) { double midAngle = startAngle + 90.0; Arc arc1 = CreateArc(center, radius, startAngle, midAngle, color1, linetype1); arc1.TransformBy(transformation, Vector3.Zero); entities.Add(arc1); Arc arc2 = CreateArc(center, radius, midAngle, endAngle, color2, linetype2); arc2.TransformBy(transformation, Vector3.Zero); entities.Add(arc2); } else { Arc arc = CreateArc(center, radius, startAngle, endAngle, color1, linetype1); arc.TransformBy(transformation, Vector3.Zero); entities.Add(arc); } } } if (style.Flags.HasFlag(MLineStyleFlags.StartSquareCap)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 start = cornerVextexes[0][0]; Vector2 end = cornerVextexes[0][cornerVextexes[0].Length - 1]; Vector2 midPoint = Vector2.MidPoint(start, end); if (trim) { Line line1 = CreateLine(start, midPoint, color1, linetype1); line1.TransformBy(transformation, Vector3.Zero); entities.Add(line1); Line line2 = CreateLine(midPoint, end, color2, linetype2); line2.TransformBy(transformation, Vector3.Zero); entities.Add(line2); } else { Line line = CreateLine(start, end, color1, linetype1); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } if (!NoEndCaps) { if (style.Flags.HasFlag(MLineStyleFlags.EndRoundCap)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 center = Vector2.MidPoint(cornerVextexes[vertexes.Count - 1][0], cornerVextexes[vertexes.Count - 1][cornerVextexes.Length - 1]); Vector2 start = cornerVextexes[vertexes.Count - 1][cornerVextexes[0].Length - 1]; //Vector2 end = cornerVextexes[this.vertexes.Count - 1][0]; double startAngle = Vector2.Angle(start - center) * MathHelper.RadToDeg; //double endAngle = Vector2.Angle(end - center) * MathHelper.RadToDeg; double endAngle = startAngle + 180.0; double radius = (start - center).Modulus(); if (trim) { double midAngle = startAngle + 90.0; Arc arc1 = CreateArc(center, radius, midAngle, endAngle, color1, linetype1); arc1.TransformBy(transformation, Vector3.Zero); entities.Add(arc1); Arc arc2 = CreateArc(center, radius, startAngle, midAngle, color2, linetype2); arc2.TransformBy(transformation, Vector3.Zero); entities.Add(arc2); } else { Arc arc = CreateArc(center, radius, startAngle, endAngle, color1, linetype1); arc.TransformBy(transformation, Vector3.Zero); entities.Add(arc); } } if (style.Flags.HasFlag(MLineStyleFlags.EndInnerArcsCap)) { Vector2 center = Vector2.MidPoint(cornerVextexes[vertexes.Count - 1][0], cornerVextexes[vertexes.Count - 1][cornerVextexes.Length - 1]); int j = (int)Math.Floor(style.Elements.Count / 2.0); for (int i = 1; i < j; i++) { AciColor color1 = style.Elements[i].Color; AciColor color2 = style.Elements[style.Elements.Count - 1 - i].Color; Linetype linetype1 = style.Elements[i].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1 - i].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 start = cornerVextexes[vertexes.Count - 1][cornerVextexes[0].Length - 1 - i]; //Vector2 end = cornerVextexes[this.vertexes.Count - 1][i]; double startAngle = Vector2.Angle(start - center) * MathHelper.RadToDeg; //double endAngle = Vector2.Angle(end - center) * MathHelper.RadToDeg; double endAngle = startAngle + 180.0; double radius = (start - center).Modulus(); if (trim) { double midAngle = startAngle + 90.0; Arc arc1 = CreateArc(center, radius, midAngle, endAngle, color1, linetype1); arc1.TransformBy(transformation, Vector3.Zero); entities.Add(arc1); Arc arc2 = CreateArc(center, radius, startAngle, midAngle, color2, linetype2); arc2.TransformBy(transformation, Vector3.Zero); entities.Add(arc2); } else { Arc arc = CreateArc(center, radius, startAngle, endAngle, color1, linetype1); arc.TransformBy(transformation, Vector3.Zero); entities.Add(arc); } } } if (style.Flags.HasFlag(MLineStyleFlags.EndSquareCap)) { AciColor color1 = style.Elements[0].Color; AciColor color2 = style.Elements[style.Elements.Count - 1].Color; Linetype linetype1 = style.Elements[0].Linetype; Linetype linetype2 = style.Elements[style.Elements.Count - 1].Linetype; bool trim = !color1.Equals(color2) || !linetype1.Equals(linetype2); Vector2 start = cornerVextexes[vertexes.Count - 1][cornerVextexes[0].Length - 1]; Vector2 end = cornerVextexes[vertexes.Count - 1][0]; Vector2 midPoint = Vector2.MidPoint(start, end); if (trim) { Line line1 = CreateLine(midPoint, end, color1, linetype1); line1.TransformBy(transformation, Vector3.Zero); entities.Add(line1); Line line2 = CreateLine(start, midPoint, color2, linetype2); line2.TransformBy(transformation, Vector3.Zero); entities.Add(line2); } else { Line line = CreateLine(start, end, color1, linetype1); line.TransformBy(transformation, Vector3.Zero); entities.Add(line); } } } return(entities); }