示例#1
0
        /// <summary>
        /// Creates a 3D Z-rotation matrix.
        /// </summary>
        /// <remarks>For a right-handed 3D system (like WPF), a positive angle value results in a counter-clockwise rotation around the axis. For a left-handed 3D system, a positive angle value results in a clockwise rotation around the axis.</remarks>
        /// <param name="angle">Angle value in degree.</param>
        /// <param name="handedness">The handedness of the coordinate system (optional). Under WPF, the defaut value is Right-handed.</param>
        /// <returns>A Matrix3D object.</returns>
        public static Matrix3D GetZRotationMatrix(double angle, Handedness3D handedness = Handedness3D.RightHanded)
        {
            //var m = new Matrix3D();
            //m.Rotate(new Quaternion(new Vector3D(0, 0, 1), angle));
            //return m;

            // var radianAngle = GeometryHelper.DegreeToRadian(angle);
            double radianAngle = 0.0;

            if (handedness == Handedness3D.LeftHanded)
            {
                radianAngle = (2 * Math.PI) - GeometryHelper.DegreeToRadian(angle);
            }
            else
            {
                radianAngle = GeometryHelper.DegreeToRadian(angle);
            }
            return(new Matrix3D
            {
                M11 = Math.Cos(radianAngle), M21 = -Math.Sin(radianAngle),
                M12 = Math.Sin(radianAngle), M22 = Math.Cos(radianAngle)
            });
        }
示例#2
0
        /// <summary>
        /// Creates a 3D Y-rotation matrix.
        /// </summary>
        /// <remarks>For a left-handed 3D system (the default in Silverlight projections), a positive angle value results in a clockwise rotation around the axis. For a right-handed 3D system, a positive angle value results in a counter-clockwise rotation around the axis.</remarks>
        /// <param name="angle">Angle value in degree.</param>
        /// <param name="handedness">The handedness of the coordinate system (optional). Under Silverlight, the defaut value is Left-handed.</param>
        /// <returns>A Matrix3D object.</returns>
        public static Matrix3D GetYRotationMatrix(double angle, Handedness3D handedness = Handedness3D.LeftHanded)
        {
            //var m = new Matrix3D();
            //m.Rotate(new Quaternion(new Vector3D(0, 1, 0), angle));
            //return m;

            double radianAngle = 0.0;

            // angle inverted in respect to the relative orientation of Z to X
            if (handedness == Handedness3D.LeftHanded)
            {
                radianAngle = GeometryHelper.DegreeToRadian(angle);
            }
            else
            {
                radianAngle = (2 * Math.PI) - GeometryHelper.DegreeToRadian(angle);
            }
            return(new Matrix3D
            {
                M11 = Math.Cos(radianAngle), M31 = -Math.Sin(radianAngle),
                M13 = Math.Sin(radianAngle), M33 = Math.Cos(radianAngle)
            });
        }
示例#3
0
        /// <summary>
        /// Rounds a vertex of a triangle.
        /// </summary>
        /// <param name="pA">First point.</param>
        /// <param name="pB">Second point. Vertex to round</param>
        /// <param name="pC">Third point.</param>
        /// <param name="roundingRate">Vertex rounding rate. The value must be comprized between 0.0 and 0.5.</param>
        /// <returns></returns>
        public static Point3DCollection RoundCorner(Point3D pA, Point3D pB, Point3D pC, double roundingRate)
        {
            if (!((pA.Z == pB.Z) && (pB.Z == pC.Z))
                )
            {
                throw new ArgumentOutOfRangeException("pA");
            }

            if ((roundingRate < 0.0) ||
                (roundingRate > 0.5)
                )
            {
                throw new ArgumentOutOfRangeException("roundingRate");
            }

            Point3DCollection points = new Point3DCollection();

            int roundingDefinition = (int)(roundingRate * 40.0);

            Vector3D v1 = new Vector3D();

            v1   = pA - pB;
            v1.X = Math.Round(v1.X, 3);
            v1.Y = Math.Round(v1.Y, 3);
            v1.Z = Math.Round(v1.Z, 3);
            Point3D p1 = Point3D.Add(pB, Vector3D.Multiply(v1, roundingRate));

            Vector3D v2 = new Vector3D();

            v2   = pC - pB;
            v2.X = Math.Round(v2.X, 3);
            v2.Y = Math.Round(v2.Y, 3);
            v2.Z = Math.Round(v2.Z, 3);
            Point3D p2 = Point3D.Add(pB, Vector3D.Multiply(v2, roundingRate));

            // v1 is the normal vector for the linear curve
            // v1.X*x + v1.Y*y + c1 = 0;
            // p1 is owned by this curve so
            double c1 = -(v1.X * p1.X) - (v1.Y * p1.Y);

            // same for v2 and p2
            double c2 = -(v2.X * p2.X) - (v2.Y * p2.Y);

            // center for the arc that owns p1 and p2
            Point3D center = new Point3D();

            if (v1.Y == 0.0)
            {
                if (v1.X == 0.0)
                {
                    throw new InvalidOperationException();
                }
                center.X = -c1 / v1.X;
                if (v2.Y == 0.0)
                {
                    throw new InvalidOperationException();
                }
                else
                {
                    center.Y = (-c2 - v2.X * center.X) / v2.Y;
                }
            }
            else
            {
                if (v2.Y == 0.0)
                {
                    if (v2.X == 0.0)
                    {
                        throw new InvalidOperationException();
                    }
                    center.X = -c2 / v2.X;
                }
                else
                {
                    center.X = (c1 / v1.Y - c2 / v2.Y) / (v2.X / v2.Y - v1.X / v1.Y);
                }
                center.Y = (-c1 - v1.X * center.X) / v1.Y;
            }
            center.Z = pB.Z;

            // angle of the arc between p1 and p2
            // 360 - 180 - Vector3D.AngleBetween(v1, v2)
            double angleArc = GeometryHelper.DegreeToRadian(180 - Vector3D.AngleBetween(v1, v2));

            // angle of each part
            double angleStep = angleArc / roundingDefinition;

            Vector3D vRadius = p1 - center;

            double angleBaseDeg = Vector3D.AngleBetween(new Vector3D(1, 0, 0), vRadius);

            // necessar adjustment because of Vector3D.AngleBetween() - see documentation
            if (p1.Y < 0.0)
            {
                angleBaseDeg = 360 - angleBaseDeg;
            }
            double angleBase = GeometryHelper.DegreeToRadian(angleBaseDeg);

            points.Add(p1);
            // points of the arc
            for (int j = 1; j <= roundingDefinition - 1; j++)
            {
                double  angle = angleBase + (angleStep * j);
                Point3D p     = new Point3D();
                p.X = center.X + Math.Cos(angle) * vRadius.Length;
                p.Y = center.Y + Math.Sin(angle) * vRadius.Length;
                p.Z = pB.Z;
                points.Add(p);
            }
            points.Add(p2);

            return(points);
        }