Пример #1
0
        /// <summary>
        /// Moves, scales, and/or rotates the current attribute given a 3x3 transformation matrix and a translation vector.
        /// </summary>
        /// <param name="transformation">Transformation matrix.</param>
        /// <param name="translation">Translation vector.</param>
        /// <remarks>Matrix3 adopts the convention of using column vectors to represent a transformation matrix.</remarks>
        public void TransformBy(Matrix3 transformation, Vector3 translation)
        {
            bool mirrText;

            if (this.Owner == null)
            {
                mirrText = Text.DefaultMirrText;
            }
            else if (this.Owner.Owner == null)
            {
                mirrText = Text.DefaultMirrText;
            }
            else
            {
                mirrText = this.Owner.Owner.Record.Owner.Owner.DrawingVariables.MirrText;
            }

            Vector3 newPosition = transformation * this.Position + translation;
            Vector3 newNormal   = transformation * this.Normal;

            if (Vector3.Equals(Vector3.Zero, newNormal))
            {
                newNormal = this.Normal;
            }

            Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal);

            Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal);

            transWO = transWO.Transpose();

            List <Vector2> uv = MathHelper.Transform(
                new[]
            {
                this.WidthFactor * this.Height * Vector2.UnitX,
                new Vector2(this.Height * Math.Tan(this.ObliqueAngle * MathHelper.DegToRad), this.Height)
            },
                this.Rotation * MathHelper.DegToRad,
                CoordinateSystem.Object, CoordinateSystem.World);

            Vector3 v;

            v = transOW * new Vector3(uv[0].X, uv[0].Y, 0.0);
            v = transformation * v;
            v = transWO * v;
            Vector2 newUvector = new Vector2(v.X, v.Y);

            v = transOW * new Vector3(uv[1].X, uv[1].Y, 0.0);
            v = transformation * v;
            v = transWO * v;
            Vector2 newVvector = new Vector2(v.X, v.Y);

            double newRotation     = Vector2.Angle(newUvector) * MathHelper.RadToDeg;
            double newObliqueAngle = Vector2.Angle(newVvector) * MathHelper.RadToDeg;

            if (mirrText)
            {
                if (Vector2.CrossProduct(newUvector, newVvector) < 0)
                {
                    newObliqueAngle = 90 - (newRotation - newObliqueAngle);
                    if (!(this.Alignment == TextAlignment.Fit || this.Alignment == TextAlignment.Aligned))
                    {
                        newRotation += 180;
                    }
                    this.IsBackward = !this.IsBackward;
                }
                else
                {
                    newObliqueAngle = 90 + (newRotation - newObliqueAngle);
                }
            }
            else
            {
                if (Vector2.CrossProduct(newUvector, newVvector) < 0.0)
                {
                    newObliqueAngle = 90 - (newRotation - newObliqueAngle);

                    if (Vector2.DotProduct(newUvector, uv[0]) < 0.0)
                    {
                        newRotation += 180;

                        switch (this.Alignment)
                        {
                        case TextAlignment.TopLeft:
                            this.Alignment = TextAlignment.TopRight;
                            break;

                        case TextAlignment.TopRight:
                            this.Alignment = TextAlignment.TopLeft;
                            break;

                        case TextAlignment.MiddleLeft:
                            this.Alignment = TextAlignment.MiddleRight;
                            break;

                        case TextAlignment.MiddleRight:
                            this.Alignment = TextAlignment.MiddleLeft;
                            break;

                        case TextAlignment.BaselineLeft:
                            this.Alignment = TextAlignment.BaselineRight;
                            break;

                        case TextAlignment.BaselineRight:
                            this.Alignment = TextAlignment.BaselineLeft;
                            break;

                        case TextAlignment.BottomLeft:
                            this.Alignment = TextAlignment.BottomRight;
                            break;

                        case TextAlignment.BottomRight:
                            this.Alignment = TextAlignment.BottomLeft;
                            break;
                        }
                    }
                    else
                    {
                        switch (this.Alignment)
                        {
                        case TextAlignment.TopLeft:
                            this.Alignment = TextAlignment.BottomLeft;
                            break;

                        case TextAlignment.TopCenter:
                            this.Alignment = TextAlignment.BottomCenter;
                            break;

                        case TextAlignment.TopRight:
                            this.Alignment = TextAlignment.BottomRight;
                            break;

                        case TextAlignment.BottomLeft:
                            this.Alignment = TextAlignment.TopLeft;
                            break;

                        case TextAlignment.BottomCenter:
                            this.Alignment = TextAlignment.TopCenter;
                            break;

                        case TextAlignment.BottomRight:
                            this.Alignment = TextAlignment.TopRight;
                            break;
                        }
                    }
                }
                else
                {
                    newObliqueAngle = 90 + (newRotation - newObliqueAngle);
                }
            }

            // the oblique angle is defined between -85 and 85 degrees
            newObliqueAngle = MathHelper.NormalizeAngle(newObliqueAngle);
            if (newObliqueAngle > 180)
            {
                newObliqueAngle = 180 - newObliqueAngle;
            }

            if (newObliqueAngle < -85)
            {
                newObliqueAngle = -85;
            }
            else if (newObliqueAngle > 85)
            {
                newObliqueAngle = 85;
            }

            // the height must be greater than zero, the cos is always positive between -85 and 85
            double newHeight = newVvector.Modulus() * Math.Cos(newObliqueAngle * MathHelper.DegToRad);

            newHeight = MathHelper.IsZero(newHeight) ? MathHelper.Epsilon : newHeight;

            // the width factor is defined between 0.01 and 100
            double newWidthFactor = newUvector.Modulus() / newHeight;

            if (newWidthFactor < 0.01)
            {
                newWidthFactor = 0.01;
            }
            else if (newWidthFactor > 100)
            {
                newWidthFactor = 100;
            }

            this.Position     = newPosition;
            this.Normal       = newNormal;
            this.Rotation     = newRotation;
            this.Height       = newHeight;
            this.WidthFactor  = newWidthFactor;
            this.ObliqueAngle = newObliqueAngle;
        }
Пример #2
0
        /// <summary>
        /// Moves, scales, and/or rotates the current entity given a 3x3 transformation matrix and a translation vector.
        /// </summary>
        /// <param name="transformation">Transformation matrix.</param>
        /// <param name="translation">Translation vector.</param>
        /// <remarks>
        /// Non-uniform scaling is not supported, it would require to decompose each line into independent Text entities.
        /// When the current MText entity does not belong to a DXF document, the text will be mirrored by default when a symmetry is performed;
        /// otherwise, the drawing variable MirrText will be used.
        /// </remarks>
        public override void TransformBy(Matrix3 transformation, Vector3 translation)
        {
            bool mirrText = this.Owner == null ? DefaultMirrText : this.Owner.Record.Owner.Owner.DrawingVariables.MirrText;

            Vector3 newPosition;
            Vector3 newNormal;
            Vector2 newUvector;
            Vector2 newVvector;
            double  scale;
            double  newHeight;
            double  newRotation;

            newPosition = transformation * this.Position + translation;
            newNormal   = transformation * this.Normal;

            Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal);

            Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal);

            transWO = transWO.Transpose();

            List <Vector2> uv = MathHelper.Transform(new List <Vector2>
            {
                Vector2.UnitX,
                Vector2.UnitY
            },
                                                     this.Rotation * MathHelper.DegToRad,
                                                     CoordinateSystem.Object, CoordinateSystem.World);

            Vector3 v;

            v          = transOW * new Vector3(uv[0].X, uv[0].Y, 0.0);
            v          = transformation * v;
            v          = transWO * v;
            newUvector = new Vector2(v.X, v.Y);

            v          = transOW * new Vector3(uv[1].X, uv[1].Y, 0.0);
            v          = transformation * v;
            v          = transWO * v;
            newVvector = new Vector2(v.X, v.Y);

            newRotation = Vector2.Angle(newUvector) * MathHelper.RadToDeg;

            if (mirrText)
            {
                if (Vector2.CrossProduct(newUvector, newVvector) < 0.0)
                {
                    newRotation += 180;
                    newNormal    = -newNormal;
                }
            }
            else
            {
                if (Vector2.CrossProduct(newUvector, newVvector) < 0.0)
                {
                    if (Vector2.DotProduct(newUvector, uv[0]) < 0.0)
                    {
                        newRotation += 180;

                        switch (this.AttachmentPoint)
                        {
                        case MTextAttachmentPoint.TopLeft:
                            this.AttachmentPoint = MTextAttachmentPoint.TopRight;
                            break;

                        case MTextAttachmentPoint.TopRight:
                            this.AttachmentPoint = MTextAttachmentPoint.TopLeft;
                            break;

                        case MTextAttachmentPoint.MiddleLeft:
                            this.AttachmentPoint = MTextAttachmentPoint.MiddleRight;
                            break;

                        case MTextAttachmentPoint.MiddleRight:
                            this.AttachmentPoint = MTextAttachmentPoint.MiddleLeft;
                            break;

                        case MTextAttachmentPoint.BottomLeft:
                            this.AttachmentPoint = MTextAttachmentPoint.BottomRight;
                            break;

                        case MTextAttachmentPoint.BottomRight:
                            this.AttachmentPoint = MTextAttachmentPoint.BottomLeft;
                            break;
                        }
                    }
                    else
                    {
                        switch (this.AttachmentPoint)
                        {
                        case MTextAttachmentPoint.TopLeft:
                            this.AttachmentPoint = MTextAttachmentPoint.BottomLeft;
                            break;

                        case MTextAttachmentPoint.TopCenter:
                            this.attachmentPoint = MTextAttachmentPoint.BottomCenter;
                            break;

                        case MTextAttachmentPoint.TopRight:
                            this.AttachmentPoint = MTextAttachmentPoint.BottomRight;
                            break;

                        case MTextAttachmentPoint.BottomLeft:
                            this.AttachmentPoint = MTextAttachmentPoint.TopLeft;
                            break;

                        case MTextAttachmentPoint.BottomCenter:
                            this.attachmentPoint = MTextAttachmentPoint.TopCenter;
                            break;

                        case MTextAttachmentPoint.BottomRight:
                            this.AttachmentPoint = MTextAttachmentPoint.TopRight;
                            break;
                        }
                    }
                }
            }

            // the MText entity does not support non-uniform scaling
            scale = newNormal.Modulus();

            newHeight = this.Height * scale;
            newHeight = MathHelper.IsZero(newHeight) ? MathHelper.Epsilon : newHeight;

            this.Position        = newPosition;
            this.Normal          = newNormal;
            this.Rotation        = newRotation;
            this.Height          = newHeight;
            this.RectangleWidth *= scale;
        }
Пример #3
0
        public void TransformBy2(Matrix3 transformation, Vector3 translation)
        {
            Vector3 newPosition;
            Vector3 newNormal;
            Vector2 newUvector;
            Vector2 newVvector;
            double  newWidthFactor;
            double  newHeight;
            double  newRotation;
            double  newObliqueAngle;
            bool    reverseText;

            newPosition = transformation * this.Position + translation;
            newNormal   = transformation * this.Normal;

            Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal);

            Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal);

            transWO = transWO.Transpose();

            List <Vector2> uv = MathHelper.Transform(new List <Vector2>
            {
                this.WidthFactor * this.Height * Vector2.UnitX,
                new Vector2(this.Height * Math.Tan(this.ObliqueAngle * MathHelper.DegToRad), this.Height)
            },
                                                     this.Rotation * MathHelper.DegToRad,
                                                     CoordinateSystem.Object, CoordinateSystem.World);

            Vector3 v;

            v          = transOW * new Vector3(uv[0].X, uv[0].Y, 0.0);
            v          = transformation * v;
            v          = transWO * v;
            newUvector = new Vector2(v.X, v.Y);

            v          = transOW * new Vector3(uv[1].X, uv[1].Y, 0.0);
            v          = transformation * v;
            v          = transWO * v;
            newVvector = new Vector2(v.X, v.Y);

            newRotation     = Vector2.Angle(newUvector) * MathHelper.RadToDeg;
            newObliqueAngle = Vector2.Angle(newVvector) * MathHelper.RadToDeg;

            if (Vector2.CrossProduct(newUvector, newVvector) < 0)
            {
                newObliqueAngle = 90 - (newRotation - newObliqueAngle);
                newRotation    += 180;
                reverseText     = true;
            }
            else
            {
                newObliqueAngle = 90 + (newRotation - newObliqueAngle);
                reverseText     = false;
            }

            if (newObliqueAngle >= 360)
            {
                newObliqueAngle -= 360;
            }

            // the oblique angle is defined between -85 nad 85 degrees
            if (newObliqueAngle > 180)
            {
                newObliqueAngle = 180 - newObliqueAngle;
            }
            if (newObliqueAngle < -85)
            {
                newObliqueAngle = -85;
            }
            else if (newObliqueAngle > 85)
            {
                newObliqueAngle = 85;
            }

            // the height must be greater than zero, the cos is always positive between -85 and 85
            newHeight = newVvector.Modulus() * Math.Cos(newObliqueAngle * MathHelper.DegToRad);
            newHeight = MathHelper.IsZero(newHeight) ? MathHelper.Epsilon : newHeight;

            // the width factor is defined between 0.01 nad 100
            newWidthFactor = newUvector.Modulus() / newHeight;
            if (newWidthFactor < 0.01)
            {
                newWidthFactor = 0.01;
            }
            else if (newWidthFactor > 100)
            {
                newWidthFactor = 100;
            }

            this.Position     = newPosition;
            this.Normal       = newNormal;
            this.Rotation     = newRotation;
            this.Height       = newHeight;
            this.WidthFactor  = newWidthFactor;
            this.ObliqueAngle = newObliqueAngle;
            if (reverseText)
            {
                this.IsBackward = !this.IsBackward;
            }
        }
Пример #4
0
        /// <summary>
        /// Moves, scales, and/or rotates the current entity given a 3x3 transformation matrix and a translation vector.
        /// </summary>
        /// <param name="transformation">Transformation matrix.</param>
        /// <param name="translation">Translation vector.</param>
        /// <remarks>
        /// Non-uniform and zero scaling local to the dimension entity are not supported.<br />
        /// The transformation will not be applied if the resulting reference lines are parallel.<br />
        /// Matrix3 adopts the convention of using column vectors to represent a transformation matrix.
        /// </remarks>
        public override void TransformBy(Matrix3 transformation, Vector3 translation)
        {
            Vector3 newNormal = transformation * this.Normal;

            if (Vector3.Equals(Vector3.Zero, newNormal))
            {
                newNormal = this.Normal;
            }

            Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal);
            Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal).Transpose();

            Vector3 v = transOW * new Vector3(this.StartFirstLine.X, this.StartFirstLine.Y, this.Elevation);

            v = transformation * v + translation;
            v = transWO * v;
            Vector2 newStart1    = new Vector2(v.X, v.Y);
            double  newElevation = v.Z;

            v = transOW * new Vector3(this.EndFirstLine.X, this.EndFirstLine.Y, this.Elevation);
            v = transformation * v + translation;
            v = transWO * v;
            Vector2 newEnd1 = new Vector2(v.X, v.Y);

            v = transOW * new Vector3(this.StartSecondLine.X, this.StartSecondLine.Y, this.Elevation);
            v = transformation * v + translation;
            v = transWO * v;
            Vector2 newStart2 = new Vector2(v.X, v.Y);

            v = transOW * new Vector3(this.EndSecondLine.X, this.EndSecondLine.Y, this.Elevation);
            v = transformation * v + translation;
            v = transWO * v;
            Vector2 newEnd2 = new Vector2(v.X, v.Y);

            Vector2 dir1 = newEnd1 - newStart1;
            Vector2 dir2 = newEnd2 - newStart2;

            if (Vector2.AreParallel(dir1, dir2))
            {
                Debug.Assert(false, "The transformation cannot be applied, the resulting reference lines are parallel.");
                return;
            }

            v = transOW * new Vector3(this.ArcDefinitionPoint.X, this.ArcDefinitionPoint.Y, this.Elevation);
            v = transformation * v + translation;
            v = transWO * v;
            Vector2 newArcDefPoint = new Vector2(v.X, v.Y);

            if (this.TextPositionManuallySet)
            {
                v = transOW * new Vector3(this.textRefPoint.X, this.textRefPoint.Y, this.Elevation);
                v = transformation * v + translation;
                v = transWO * v;
                this.textRefPoint = new Vector2(v.X, v.Y);
            }

            v             = transOW * new Vector3(this.defPoint.X, this.defPoint.Y, this.Elevation);
            v             = transformation * v + translation;
            v             = transWO * v;
            this.defPoint = new Vector2(v.X, v.Y);

            this.StartFirstLine     = newStart1;
            this.EndFirstLine       = newEnd1;
            this.StartSecondLine    = newStart2;
            this.EndSecondLine      = newEnd2;
            this.ArcDefinitionPoint = newArcDefPoint;
            this.Elevation          = newElevation;
            this.Normal             = newNormal;

            this.SetDimensionLinePosition(newArcDefPoint);
        }
Пример #5
0
        /// <summary>
        /// Decompose the actual polyline 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 polyline.</returns>
        public List <EntityObject> Explode()
        {
            List <EntityObject> entities = new List <EntityObject>();

            if (this.smoothType == PolylineSmoothType.NoSmooth)
            {
                int index = 0;
                foreach (Polyline2DVertex vertex in this.Vertexes)
                {
                    double  bulge = vertex.Bulge;
                    Vector2 p1;
                    Vector2 p2;

                    if (index == this.Vertexes.Count - 1)
                    {
                        if (!this.IsClosed)
                        {
                            break;
                        }
                        p1 = new Vector2(vertex.Position.X, vertex.Position.Y);
                        p2 = new Vector2(this.vertexes[0].Position.X, this.vertexes[0].Position.Y);
                    }
                    else
                    {
                        p1 = new Vector2(vertex.Position.X, vertex.Position.Y);
                        p2 = new Vector2(this.vertexes[index + 1].Position.X, this.vertexes[index + 1].Position.Y);
                    }

                    if (MathHelper.IsZero(bulge))
                    {
                        // the polyline edge is a line
                        Vector3 start = MathHelper.Transform(new Vector3(p1.X, p1.Y, this.elevation), this.Normal, CoordinateSystem.Object, CoordinateSystem.World);
                        Vector3 end   = MathHelper.Transform(new Vector3(p2.X, p2.Y, this.elevation), this.Normal, CoordinateSystem.Object, CoordinateSystem.World);

                        entities.Add(new Line
                        {
                            Layer         = (Layer)this.Layer.Clone(),
                            Linetype      = (Linetype)this.Linetype.Clone(),
                            Color         = (AciColor)this.Color.Clone(),
                            Lineweight    = this.Lineweight,
                            Transparency  = (Transparency)this.Transparency.Clone(),
                            LinetypeScale = this.LinetypeScale,
                            Normal        = this.Normal,
                            StartPoint    = start,
                            EndPoint      = end,
                            Thickness     = this.Thickness
                        });
                    }
                    else
                    {
                        // the polyline edge is an arc
                        double theta = 4 * Math.Atan(Math.Abs(bulge));
                        double c     = Vector2.Distance(p1, p2) / 2.0;
                        double r     = c / Math.Sin(theta / 2.0);

                        // avoid arcs with very small radius, draw a line instead
                        if (MathHelper.IsZero(r))
                        {
                            // the polyline edge is a line
                            List <Vector3> points = MathHelper.Transform(
                                new []
                            {
                                new Vector3(p1.X, p1.Y, this.elevation),
                                new Vector3(p2.X, p2.Y, this.elevation)
                            },
                                this.Normal,
                                CoordinateSystem.Object, CoordinateSystem.World);

                            entities.Add(new Line
                            {
                                Layer         = (Layer)this.Layer.Clone(),
                                Linetype      = (Linetype)this.Linetype.Clone(),
                                Color         = (AciColor)this.Color.Clone(),
                                Lineweight    = this.Lineweight,
                                Transparency  = (Transparency)this.Transparency.Clone(),
                                LinetypeScale = this.LinetypeScale,
                                Normal        = this.Normal,
                                StartPoint    = points[0],
                                EndPoint      = points[1],
                                Thickness     = this.Thickness,
                            });
                        }
                        else
                        {
                            double  gamma  = (Math.PI - theta) / 2;
                            double  phi    = Vector2.Angle(p1, p2) + Math.Sign(bulge) * gamma;
                            Vector2 center = new Vector2(p1.X + r * Math.Cos(phi), p1.Y + r * Math.Sin(phi));
                            double  startAngle;
                            double  endAngle;
                            if (bulge > 0)
                            {
                                startAngle = MathHelper.RadToDeg * Vector2.Angle(p1 - center);
                                endAngle   = startAngle + MathHelper.RadToDeg * theta;
                            }
                            else
                            {
                                endAngle   = MathHelper.RadToDeg * Vector2.Angle(p1 - center);
                                startAngle = endAngle - MathHelper.RadToDeg * theta;
                            }
                            Vector3 point = MathHelper.Transform(new Vector3(center.X, center.Y,
                                                                             this.elevation),
                                                                 this.Normal,
                                                                 CoordinateSystem.Object,
                                                                 CoordinateSystem.World);

                            entities.Add(new Arc
                            {
                                Layer         = (Layer)this.Layer.Clone(),
                                Linetype      = (Linetype)this.Linetype.Clone(),
                                Color         = (AciColor)this.Color.Clone(),
                                Lineweight    = this.Lineweight,
                                Transparency  = (Transparency)this.Transparency.Clone(),
                                LinetypeScale = this.LinetypeScale,
                                Normal        = this.Normal,
                                Center        = point,
                                Radius        = r,
                                StartAngle    = startAngle,
                                EndAngle      = endAngle,
                                Thickness     = this.Thickness,
                            });
                        }
                    }
                    index++;
                }
                return(entities);
            }

            Vector3[] wcsVertexes = new Vector3[this.vertexes.Count];
            Matrix3   trans       = MathHelper.ArbitraryAxis(this.Normal);

            for (int i = 0; i < this.vertexes.Count; i++)
            {
                Vector3 wcsVertex = trans * new Vector3(this.vertexes[i].Position.X, this.vertexes[i].Position.Y, this.elevation);
                wcsVertexes[i] = wcsVertex;
            }

            int            degree       = this.smoothType == PolylineSmoothType.Quadratic ? 2 : 3;
            int            splineSegs   = this.Owner == null ? DefaultSplineSegs : this.Owner.Record.Owner.Owner.DrawingVariables.SplineSegs;
            int            precision    = this.IsClosed ? splineSegs * this.Vertexes.Count : splineSegs * (this.Vertexes.Count - 1);
            List <Vector3> splinePoints = Spline.NurbsEvaluator(wcsVertexes, null, null, degree, false, this.IsClosed, precision);

            for (int i = 1; i < splinePoints.Count; i++)
            {
                Vector3 start = splinePoints[i - 1];
                Vector3 end   = splinePoints[i];
                entities.Add(new Line
                {
                    Layer         = (Layer)this.Layer.Clone(),
                    Linetype      = (Linetype)this.Linetype.Clone(),
                    Color         = (AciColor)this.Color.Clone(),
                    Lineweight    = this.Lineweight,
                    Transparency  = (Transparency)this.Transparency.Clone(),
                    LinetypeScale = this.LinetypeScale,
                    Normal        = this.Normal,
                    StartPoint    = start,
                    EndPoint      = end,
                    Thickness     = this.Thickness
                });
            }

            if (this.IsClosed)
            {
                entities.Add(new Line
                {
                    Layer         = (Layer)this.Layer.Clone(),
                    Linetype      = (Linetype)this.Linetype.Clone(),
                    Color         = (AciColor)this.Color.Clone(),
                    Lineweight    = this.Lineweight,
                    Transparency  = (Transparency)this.Transparency.Clone(),
                    LinetypeScale = this.LinetypeScale,
                    Normal        = this.Normal,
                    StartPoint    = splinePoints[splinePoints.Count - 1],
                    EndPoint      = splinePoints[0],
                    Thickness     = this.Thickness
                });
            }

            return(entities);
        }
Пример #6
0
        /// <summary>
        /// Moves, scales, and/or rotates the current attribute given a 3x3 transformation matrix and a translation vector.
        /// </summary>
        /// <param name="transformation">Transformation matrix.</param>
        /// <param name="translation">Translation vector.</param>
        public void TransformBy(Matrix3 transformation, Vector3 translation)
        {
            Vector3 newPosition;
            Vector3 newNormal;
            Vector2 newUvector;
            Vector2 newVvector;
            double  newWidthFactor;
            double  newHeight;
            double  newRotation;
            double  newObliqueAngle;

            newPosition = transformation * Position + translation;
            newNormal   = transformation * Normal;

            Matrix3 transOW = MathHelper.ArbitraryAxis(Normal);

            Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal);

            transWO = transWO.Transpose();

            IList <Vector2> uv = MathHelper.Transform(new List <Vector2> {
                WidthFactor *Height *Vector2.UnitX, Height *Vector2.UnitY
            },
                                                      Rotation * MathHelper.DegToRad,
                                                      CoordinateSystem.Object, CoordinateSystem.World);

            Vector3 v;

            v          = transOW * new Vector3(uv[0].X, uv[0].Y, 0.0);
            v          = transformation * v;
            v          = transWO * v;
            newUvector = new Vector2(v.X, v.Y);

            v          = transOW * new Vector3(uv[1].X, uv[1].Y, 0.0);
            v          = transformation * v;
            v          = transWO * v;
            newVvector = new Vector2(v.X, v.Y);

            newRotation = Vector2.Angle(newUvector) * MathHelper.RadToDeg;

            // the oblique angle is defined between -85 nad 85 degrees
            newObliqueAngle = Vector2.Angle(newVvector) * MathHelper.RadToDeg;
            newObliqueAngle = (newRotation + 90.0) - newObliqueAngle;
            if (newObliqueAngle > 180)
            {
                newObliqueAngle = 180 - newObliqueAngle;
            }
            if (newObliqueAngle < -85)
            {
                newObliqueAngle = -85;
            }
            else if (newObliqueAngle > 85)
            {
                newObliqueAngle = 85;
            }

            // the height must be greater than zero, the cos is always positive between -85 and 85
            newHeight = newVvector.Modulus() * Math.Cos(newObliqueAngle * MathHelper.DegToRad);
            newHeight = MathHelper.IsZero(newHeight) ? MathHelper.Epsilon : newHeight;

            // the width factor is defined between 0.01 nad 100
            newWidthFactor = newUvector.Modulus() / newHeight;
            if (newWidthFactor < 0.01)
            {
                newWidthFactor = 0.01;
            }
            else if (newWidthFactor > 100)
            {
                newWidthFactor = 100;
            }

            Position     = newPosition;
            Normal       = newNormal;
            Rotation     = newRotation;
            Height       = newHeight;
            WidthFactor  = newWidthFactor;
            ObliqueAngle = newObliqueAngle;
        }
Пример #7
0
        // TODO: apply the transformation directly to edges
        //public void TransformBy2(Matrix3 transformation, Vector3 translation)
        //{
        //    if (this.associative)
        //    {
        //        this.UnLinkBoundary();
        //    }

        //    Vector3 newNormal = transformation * this.Normal;
        //    if (Vector3.Equals(Vector3.Zero, newNormal))
        //    {
        //        newNormal = this.Normal;
        //    }

        //    Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal);
        //    Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal).Transpose();

        //    Vector3 position = transOW * new Vector3(0.0, 0.0, this.Elevation);

        //    foreach (HatchBoundaryPath path in this.BoundaryPaths)
        //    {
        //        foreach (HatchBoundaryPath.Edge edge in path.Edges)
        //        {
        //            switch (edge.Type)
        //            {
        //                case HatchBoundaryPath.EdgeType.Arc:
        //                    break;

        //                case HatchBoundaryPath.EdgeType.Ellipse:
        //                    break;

        //                case HatchBoundaryPath.EdgeType.Line:
        //                    HatchBoundaryPath.Line line = (HatchBoundaryPath.Line)edge;
        //                    Vector3 start = new Vector3(line.Start.X, line.Start.Y, 0.0);
        //                    Vector3 end = new Vector3(line.End.X, line.End.Y, 0.0);

        //                    // to world coordinates
        //                    start = transOW * start + position;
        //                    end = transOW * end + position;

        //                    // transformation
        //                    start = transformation * start + translation;
        //                    end = transformation * end + translation;

        //                    Vector3 point;
        //                    point = transWO * start;
        //                    line.Start = new Vector2(point.X, point.Y);
        //                    point = transWO * end;
        //                    line.End = new Vector2(point.X, point.Y);
        //                    break;

        //                case HatchBoundaryPath.EdgeType.Polyline:
        //                    break;

        //                case HatchBoundaryPath.EdgeType.Spline:
        //                    break;
        //            }
        //        }
        //    }

        //    position = transformation * position + translation;
        //    position = transWO * position;

        //    Vector2 refAxis = Vector2.Rotate(Vector2.UnitX, this.Pattern.Angle * MathHelper.DegToRad);
        //    refAxis = this.Pattern.Scale * refAxis;
        //    Vector3 v = transOW * new Vector3(refAxis.X, refAxis.Y, 0.0);
        //    v = transformation * v;
        //    v = transWO * v;
        //    Vector2 axis = new Vector2(v.X, v.Y);
        //    double newAngle = Vector2.Angle(axis) * MathHelper.RadToDeg;

        //    double newScale = axis.Modulus();
        //    newScale = MathHelper.IsZero(newScale) ? MathHelper.Epsilon : newScale;

        //    this.Pattern.Scale = newScale;
        //    this.Pattern.Angle = newAngle;
        //    this.Elevation = position.Z;
        //    this.Normal = newNormal;
        //}

        /// <summary>
        /// Moves, scales, and/or rotates the current entity given a 3x3 transformation matrix and a translation vector.
        /// </summary>
        /// <param name="transformation">Transformation matrix.</param>
        /// <param name="translation">Translation vector.</param>
        /// <remarks>Matrix3 adopts the convention of using column vectors to represent a transformation matrix.</remarks>
        public override void TransformBy(Matrix3 transformation, Vector3 translation)
        {
            if (this.associative)
            {
                this.UnLinkBoundary();
            }

            Vector3 newNormal = transformation * this.Normal;

            if (Vector3.Equals(Vector3.Zero, newNormal))
            {
                newNormal = this.Normal;
            }

            Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal);
            Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal).Transpose();

            Vector3 position = transOW * new Vector3(0.0, 0.0, this.Elevation);

            List <HatchBoundaryPath> paths = new List <HatchBoundaryPath>();

            foreach (HatchBoundaryPath path in this.BoundaryPaths)
            {
                List <EntityObject> data = new List <EntityObject>();

                foreach (HatchBoundaryPath.Edge edge in path.Edges)
                {
                    EntityObject entity = edge.ConvertTo();

                    switch (entity.Type)
                    {
                    case EntityType.Arc:
                        entity = ProcessArc((Arc)entity, transOW, position);
                        break;

                    case EntityType.Circle:
                        entity = ProcessCircle((Circle)entity, transOW, position);
                        break;

                    case EntityType.Ellipse:
                        entity = ProcessEllipse((Ellipse)entity, transOW, position);
                        break;

                    case EntityType.Line:
                        entity = ProcessLine((Line)entity, transOW, position);
                        break;

                    case EntityType.Polyline2D:
                        entity = ProcessLwPolyline((Polyline2D)entity, this.Normal, this.Elevation);
                        break;

                    case EntityType.Spline:
                        entity = ProcessSpline((Spline)entity, transOW, position);
                        break;
                    }
                    entity.TransformBy(transformation, translation);
                    data.Add(entity);
                }
                paths.Add(new HatchBoundaryPath(data));
            }

            position = transformation * position + translation;
            position = transWO * position;

            Vector2 refAxis = Vector2.Rotate(Vector2.UnitX, this.Pattern.Angle * MathHelper.DegToRad);

            refAxis = this.Pattern.Scale * refAxis;
            Vector3 v = transOW * new Vector3(refAxis.X, refAxis.Y, 0.0);

            v = transformation * v;
            v = transWO * v;
            Vector2 axis     = new Vector2(v.X, v.Y);
            double  newAngle = Vector2.Angle(axis) * MathHelper.RadToDeg;

            double newScale = axis.Modulus();

            newScale = MathHelper.IsZero(newScale) ? MathHelper.Epsilon : newScale;

            this.Pattern.Scale = newScale;
            this.Pattern.Angle = newAngle;
            this.Elevation     = position.Z;

            this.Normal = newNormal;
            this.BoundaryPaths.Clear();
            this.BoundaryPaths.AddRange(paths);
        }
Пример #8
0
        /// <summary>
        /// Moves, scales, and/or rotates the current entity given a 3x3 transformation matrix and a translation vector.
        /// </summary>
        /// <param name="transformation">Transformation matrix.</param>
        /// <param name="translation">Translation vector.</param>
        /// <remarks>Matrix3 adopts the convention of using column vectors to represent a transformation matrix.</remarks>
        public override void TransformBy(Matrix3 transformation, Vector3 translation)
        {
            bool mirrorShape;

            Vector3 newPosition = transformation * this.Position + translation;
            Vector3 newNormal   = transformation * this.Normal;

            if (Vector3.Equals(Vector3.Zero, newNormal))
            {
                newNormal = this.Normal;
            }

            Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal);

            Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal);

            transWO = transWO.Transpose();

            List <Vector2> uv = MathHelper.Transform(
                new[]
            {
                Vector2.UnitX *this.WidthFactor *this.Size,
                new Vector2(this.Size * Math.Tan(this.ObliqueAngle * MathHelper.DegToRad), this.Size)
            },
                this.Rotation * MathHelper.DegToRad,
                CoordinateSystem.Object, CoordinateSystem.World);

            Vector3 v;

            v = transOW * new Vector3(uv[0].X, uv[0].Y, 0.0);
            v = transformation * v;
            v = transWO * v;
            Vector2 newUvector = new Vector2(v.X, v.Y);

            v = transOW * new Vector3(uv[1].X, uv[1].Y, 0.0);
            v = transformation * v;
            v = transWO * v;
            Vector2 newVvector = new Vector2(v.X, v.Y);

            double newRotation     = Vector2.Angle(newUvector) * MathHelper.RadToDeg;
            double newObliqueAngle = Vector2.Angle(newVvector) * MathHelper.RadToDeg;

            if (Vector2.CrossProduct(newUvector, newVvector) < 0)
            {
                newRotation    += 180;
                newObliqueAngle = 270 - (newRotation - newObliqueAngle);
                if (newObliqueAngle >= 360)
                {
                    newObliqueAngle -= 360;
                }
                mirrorShape = true;
            }
            else
            {
                newObliqueAngle = 90 + (newRotation - newObliqueAngle);
                mirrorShape     = false;
            }

            // the oblique angle is defined between -85 and 85 degrees
            if (newObliqueAngle > 180)
            {
                newObliqueAngle = 180 - newObliqueAngle;
            }

            if (newObliqueAngle < -85)
            {
                newObliqueAngle = -85;
            }
            else if (newObliqueAngle > 85)
            {
                newObliqueAngle = 85;
            }

            // the height must be greater than zero, the cos is always positive between -85 and 85
            double newHeight = newVvector.Modulus() * Math.Cos(newObliqueAngle * MathHelper.DegToRad);

            newHeight = MathHelper.IsZero(newHeight) ? MathHelper.Epsilon : newHeight;

            // the width factor is defined between 0.01 and 100
            double newWidthFactor = newUvector.Modulus() / newHeight;

            if (newWidthFactor < 0.01)
            {
                newWidthFactor = 0.01;
            }
            else if (newWidthFactor > 100)
            {
                newWidthFactor = 100;
            }

            this.Position     = newPosition;
            this.Normal       = newNormal;
            this.Rotation     = newRotation;
            this.Size         = newHeight;
            this.WidthFactor  = mirrorShape ? -newWidthFactor : newWidthFactor;
            this.ObliqueAngle = mirrorShape ? -newObliqueAngle : newObliqueAngle;
        }
Пример #9
0
        /// <summary>
        /// Moves, scales, and/or rotates the current entity given a 3x3 transformation matrix and a translation vector.
        /// </summary>
        /// <param name="transformation">Transformation matrix.</param>
        /// <param name="translation">Translation vector.</param>
        /// <remarks>
        /// Non-uniform scaling is not supported.
        /// </remarks>
        public override void TransformBy(Matrix3 transformation, Vector3 translation)
        {
            Vector2 newStart1;
            Vector2 newEnd1;
            Vector2 newStart2;
            Vector2 newEnd2;
            Vector2 newArcDefPoint;
            Vector3 newNormal;
            double  newElevation;
            double  newScale;

            newNormal = transformation * this.Normal;
            newScale  = newNormal.Modulus();

            Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal);
            Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal).Transpose();

            Vector3 v = transOW * new Vector3(this.StartFirstLine.X, this.StartFirstLine.Y, this.Elevation);

            v            = transformation * v + translation;
            v            = transWO * v;
            newStart1    = new Vector2(v.X, v.Y);
            newElevation = v.Z;

            v       = transOW * new Vector3(this.EndFirstLine.X, this.EndFirstLine.Y, this.Elevation);
            v       = transformation * v + translation;
            v       = transWO * v;
            newEnd1 = new Vector2(v.X, v.Y);

            v         = transOW * new Vector3(this.StartSecondLine.X, this.StartSecondLine.Y, this.Elevation);
            v         = transformation * v + translation;
            v         = transWO * v;
            newStart2 = new Vector2(v.X, v.Y);

            v       = transOW * new Vector3(this.EndSecondLine.X, this.EndSecondLine.Y, this.Elevation);
            v       = transformation * v + translation;
            v       = transWO * v;
            newEnd2 = new Vector2(v.X, v.Y);

            v = transOW * new Vector3(this.ArcDefinitionPoint.X, this.ArcDefinitionPoint.Y, this.Elevation);
            v = transformation * v + translation;
            v = transWO * v;
            newArcDefPoint = new Vector2(v.X, v.Y);

            v = transOW * new Vector3(this.textRefPoint.X, this.textRefPoint.Y, this.Elevation);
            v = transformation * v + translation;
            v = transWO * v;
            this.textRefPoint = new Vector2(v.X, v.Y);

            v             = transOW * new Vector3(this.defPoint.X, this.defPoint.Y, this.Elevation);
            v             = transformation * v + translation;
            v             = transWO * v;
            this.defPoint = new Vector2(v.X, v.Y);

            this.Offset            *= newScale;
            this.StartFirstLine     = newStart1;
            this.EndFirstLine       = newEnd1;
            this.StartSecondLine    = newStart2;
            this.EndSecondLine      = newEnd2;
            this.ArcDefinitionPoint = newArcDefPoint;
            this.Elevation          = newElevation;
            this.Normal             = newNormal;
        }
Пример #10
0
        /// <summary>
        /// Moves, scales, and/or rotates the current entity given a 3x3 transformation matrix and a translation vector.
        /// </summary>
        /// <param name="transformation">Transformation matrix.</param>
        /// <param name="translation">Translation vector.</param>
        /// <remarks>
        /// Non-uniform scaling for rotated underlays is not supported.
        /// This is not a limitation of the code but the DXF format, unlike the Image there is no way to define the local UV vectors.
        /// </remarks>
        public override void TransformBy(Matrix3 transformation, Vector3 translation)
        {
            Vector3 newPosition;
            Vector3 newNormal;
            Vector2 newUvector;
            Vector2 newVvector;
            Vector2 newScale;
            double  newRotation;

            newPosition = transformation * this.Position + translation;
            newNormal   = transformation * this.Normal;

            Matrix3 transOW = MathHelper.ArbitraryAxis(this.Normal);

            Matrix3 transWO = MathHelper.ArbitraryAxis(newNormal);

            transWO = transWO.Transpose();

            IList <Vector2> uv = MathHelper.Transform(new List <Vector2> {
                this.Scale.X * Vector2.UnitX, this.Scale.Y * Vector2.UnitY
            },
                                                      this.rotation * MathHelper.DegToRad,
                                                      CoordinateSystem.Object, CoordinateSystem.World);

            int sign = Math.Sign(transformation.M11 * transformation.M22 * transformation.M33) < 0 ? -1 : 1;

            Vector3 v;

            v          = transOW * new Vector3(uv[0].X, uv[0].Y, 0.0);
            v          = transformation * v;
            v          = transWO * v;
            newUvector = new Vector2(v.X, v.Y);

            v          = transOW * new Vector3(uv[1].X, uv[1].Y, 0.0);
            v          = transformation * v;
            v          = transWO * v;
            newVvector = new Vector2(v.X, v.Y);

            double scaleX = sign * newUvector.Modulus();

            scaleX = MathHelper.IsZero(scaleX) ? MathHelper.Epsilon : scaleX;
            double scaleY = newVvector.Modulus();

            scaleY = MathHelper.IsZero(scaleY) ? MathHelper.Epsilon : scaleY;

            newScale    = new Vector2(scaleX, scaleY);
            newRotation = Vector2.Angle(sign * newUvector) * MathHelper.RadToDeg;

            this.Position = newPosition;
            this.Normal   = newNormal;
            this.Rotation = newRotation;
            this.Scale    = newScale;

            //if (this.ClippingBoundary == null) return;

            //List<Vector2> vertexes = new List<Vector2>();

            //foreach (Vector2 vertex in this.ClippingBoundary.Vertexes)
            //{
            //    v = transOW * new Vector3(vertex.X, vertex.Y, 0.0);
            //    v = transformation * v + translation;
            //    v = transWO * v;
            //    vertexes.Add(new Vector2(v.X, v.Y));
            //}

            //ClippingBoundary newClipping = this.ClippingBoundary.Type == ClippingBoundaryType.Rectangular
            //    ? new ClippingBoundary(vertexes[0], vertexes[1])
            //    : new ClippingBoundary(vertexes);

            //this.ClippingBoundary = newClipping;
        }