コード例 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="p0">First point on route</param>
        /// <param name="q0">First point on map</param>
        /// <param name="p1">Second point on route</param>
        /// <param name="q1">Second point on map</param>
        /// <param name="p2">Third point on route</param>
        /// <param name="q2">Third point on map</param>
        /// <param name="fallbackMatrix">Matrix to use if calculation fails due to singular matrix</param>
        /// <returns></returns>
        public static GeneralMatrix CalculateTransformationMatrix(PointD p0, PointD q0, PointD p1, PointD q1, PointD p2, PointD q2, GeneralMatrix fallbackMatrix)
        {
            try
            {
                var m = new GeneralMatrix(3, 3);
                m.SetElement(0, 0, p0.X);
                m.SetElement(0, 1, p0.Y);
                m.SetElement(0, 2, 1.0);
                m.SetElement(1, 0, p1.X);
                m.SetElement(1, 1, p1.Y);
                m.SetElement(1, 2, 1.0);
                m.SetElement(2, 0, p2.X);
                m.SetElement(2, 1, p2.Y);
                m.SetElement(2, 2, 1.0);

                var v1 = new GeneralMatrix(3, 1);
                v1.SetElement(0, 0, q0.X);
                v1.SetElement(1, 0, q1.X);
                v1.SetElement(2, 0, q2.X);
                var t1 = m.Inverse() * v1;

                var v2 = new GeneralMatrix(3, 1);
                v2.SetElement(0, 0, q0.Y);
                v2.SetElement(1, 0, q1.Y);
                v2.SetElement(2, 0, q2.Y);
                var t2 = m.Inverse() * v2;

                var v3 = new GeneralMatrix(3, 1);
                v3.SetElement(0, 0, 1.0);
                v3.SetElement(1, 0, 1.0);
                v3.SetElement(2, 0, 1.0);
                var t3 = m.Inverse() * v3;

                var t = new GeneralMatrix(3, 3);
                t.SetElement(0, 0, t1.GetElement(0, 0));
                t.SetElement(0, 1, t1.GetElement(1, 0));
                t.SetElement(0, 2, t1.GetElement(2, 0));
                t.SetElement(1, 0, t2.GetElement(0, 0));
                t.SetElement(1, 1, t2.GetElement(1, 0));
                t.SetElement(1, 2, t2.GetElement(2, 0));
                t.SetElement(2, 0, t3.GetElement(0, 0));
                t.SetElement(2, 1, t3.GetElement(1, 0));
                t.SetElement(2, 2, t3.GetElement(2, 0));

                return(t);
            }
            catch (Exception)
            {
                return((GeneralMatrix)fallbackMatrix.Clone());
            }
        }
コード例 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="p0">First point on route, in projected (metric) coordinates relative to projection origin</param>
        /// <param name="q0">First point on map, in pixels</param>
        /// <param name="p1">Second point on route, in projected (metric) coordinates relative to projection origin</param>
        /// <param name="q1">Second point on map, in pixels</param>
        /// <param name="fallbackMatrix">Matrix to use if calculation fails due to singular matrix</param>
        /// <param name="useRotation">If true, assumes orthogonal map and calculates scale and rotation. If false, calculates different scale in x and y directions and no rotation.</param>
        /// <returns></returns>
        public static GeneralMatrix CalculateTransformationMatrix(PointD p0, PointD q0, PointD p1, PointD q1, GeneralMatrix fallbackMatrix, bool useRotation)
        {
            try
            {
                if (useRotation)
                {
                    // note that we need to mirror y pixel value in x axis
                    double angleDifferece = GetAngleR(p1 - p0, new PointD(q1.X, -q1.Y) - new PointD(q0.X, -q0.Y));
                    double lengthQ        = DistancePointToPoint(q0, q1);
                    double lengthP        = DistancePointToPoint(p0, p1);
                    double scaleFactor    = lengthP == 0 ? 0 : lengthQ / lengthP;
                    double cos            = Math.Cos(angleDifferece);
                    double sin            = Math.Sin(angleDifferece);

                    // translation to origo in metric space
                    var a = new GeneralMatrix(3, 3);
                    a.SetElement(0, 0, 1);
                    a.SetElement(0, 1, 0);
                    a.SetElement(0, 2, -p0.X);
                    a.SetElement(1, 0, 0);
                    a.SetElement(1, 1, 1);
                    a.SetElement(1, 2, -p0.Y);
                    a.SetElement(2, 0, 0);
                    a.SetElement(2, 1, 0);
                    a.SetElement(2, 2, 1);

                    // rotation
                    var b = new GeneralMatrix(3, 3);
                    b.SetElement(0, 0, cos);
                    b.SetElement(0, 1, -sin);
                    b.SetElement(0, 2, 0);
                    b.SetElement(1, 0, sin);
                    b.SetElement(1, 1, cos);
                    b.SetElement(1, 2, 0);
                    b.SetElement(2, 0, 0);
                    b.SetElement(2, 1, 0);
                    b.SetElement(2, 2, 1);

                    // scaling, note that we need to mirror y scale around x axis
                    var c = new GeneralMatrix(3, 3);
                    c.SetElement(0, 0, scaleFactor);
                    c.SetElement(0, 1, 0);
                    c.SetElement(0, 2, 0);
                    c.SetElement(1, 0, 0);
                    c.SetElement(1, 1, -scaleFactor);
                    c.SetElement(1, 2, 0);
                    c.SetElement(2, 0, 0);
                    c.SetElement(2, 1, 0);
                    c.SetElement(2, 2, 1);

                    // translation from origo to pixel space
                    var d = new GeneralMatrix(3, 3);
                    d.SetElement(0, 0, 1);
                    d.SetElement(0, 1, 0);
                    d.SetElement(0, 2, q0.X);
                    d.SetElement(1, 0, 0);
                    d.SetElement(1, 1, 1);
                    d.SetElement(1, 2, q0.Y);
                    d.SetElement(2, 0, 0);
                    d.SetElement(2, 1, 0);
                    d.SetElement(2, 2, 1);

                    return(d * c * b * a);
                }
                else // useRotation == false
                {
                    var m1 = new GeneralMatrix(2, 2);
                    m1.SetElement(0, 0, p0.X);
                    m1.SetElement(0, 1, 1);
                    m1.SetElement(1, 0, p1.X);
                    m1.SetElement(1, 1, 1);

                    var v1 = new GeneralMatrix(2, 1);
                    v1.SetElement(0, 0, q0.X);
                    v1.SetElement(1, 0, q1.X);
                    var t1 = m1.Inverse() * v1;

                    var m2 = new GeneralMatrix(2, 2);
                    m2.SetElement(0, 0, p0.Y);
                    m2.SetElement(0, 1, 1);
                    m2.SetElement(1, 0, p1.Y);
                    m2.SetElement(1, 1, 1);

                    var v2 = new GeneralMatrix(2, 1);
                    v2.SetElement(0, 0, q0.Y);
                    v2.SetElement(1, 0, q1.Y);
                    var t2 = m2.Inverse() * v2;

                    var t = new GeneralMatrix(3, 3);
                    t.SetElement(0, 0, t1.GetElement(0, 0));
                    t.SetElement(0, 1, 0);
                    t.SetElement(0, 2, t1.GetElement(1, 0));
                    t.SetElement(1, 0, 0);
                    t.SetElement(1, 1, t2.GetElement(0, 0));
                    t.SetElement(1, 2, t2.GetElement(1, 0));
                    t.SetElement(2, 0, 0);
                    t.SetElement(2, 1, 0);
                    t.SetElement(2, 2, 1);

                    return(t);
                }
            }
            catch (Exception)
            {
                return((GeneralMatrix)fallbackMatrix.Clone());
            }
        }