Пример #1
0
        // vector _y as user input
        public static void ComputePCATransf(List <Point3D> _points, Vector3D v_correction, out Matrix3D trWC2LC, out Matrix3D trLC2WC)
        {
            trWC2LC = Matrix3D.Identity;
            trLC2WC = Matrix3D.Identity;
            if (_points == null || _points.Count < 1 || v_correction == null)
            {
                return;
            }

            Point3D  pivot;
            Vector3D vec0, vec1, vec2;

            GeometricTransforms.CalculatePCA(_points, out pivot, out vec0, out vec1, out vec2);

            // detect which base vector is closest to the correction vector
            v_correction.Normalize();
            double angle0 = Vector3D.DotProduct(v_correction, vec0);
            double angle1 = Vector3D.DotProduct(v_correction, vec1);
            double angle2 = Vector3D.DotProduct(v_correction, vec2);

            Vector3D vec_to_rotate = vec2;

            if (Math.Abs(angle0) < Math.Abs(angle1) && Math.Abs(angle0) < Math.Abs(angle2))
            {
                vec_to_rotate = (angle0 > 0) ? vec0 : -vec0;
            }
            else if (Math.Abs(angle1) < Math.Abs(angle0) && Math.Abs(angle1) < Math.Abs(angle2))
            {
                vec_to_rotate = (angle1 > 0) ? vec1 : -vec1;
            }
            else
            {
                vec_to_rotate = (angle2 > 0) ? vec2 : -vec2;
            }

            // correct by user-defined vector
            Matrix3D R      = GeometricTransforms.AlingVector(v_correction, vec_to_rotate);
            Vector3D vec0_r = R.Transform(vec0);
            Vector3D vec1_r = R.Transform(vec1);
            Vector3D vec2_r = R.Transform(vec2);

            // debug
            List <Vector3D> ucs_1 = new List <Vector3D> {
                vec0, vec1, vec2, v_correction
            };
            List <Vector3D> ucs_2 = new List <Vector3D> {
                vec0_r, vec1_r, vec2_r
            };
            string ucs_1_str = GeometricTransforms.VectorListToString(ucs_1);
            string ucs_2_str = GeometricTransforms.VectorListToString(ucs_2);

            // debug

            // calculate the transforms WITH CORRECTION
            trWC2LC = GeometricTransforms.GetTransformWC2LC(pivot, vec0_r, vec1_r, vec2_r);
            trLC2WC = GeometricTransforms.GetTransformLC2WC(pivot, vec0_r, vec1_r, vec2_r);
        }
Пример #2
0
        private static void CalculatePCA(List <Point3D> _points, out Point3D pivotO,
                                         out Vector3D vecX, out Vector3D vecY, out Vector3D vecZ)
        {
            pivotO = new Point3D(0, 0, 0);
            vecX   = new Vector3D(0, 0, 0);
            vecY   = new Vector3D(0, 0, 0);
            vecZ   = new Vector3D(0, 0, 0);
            if (_points == null || _points.Count < 1)
            {
                return;
            }

            Point3D pivot = GeometricTransforms.GetPivot(_points);

            pivotO = new Point3D(pivot.X, pivot.Y, pivot.Z);
            List <Vector3D> point_deviations = _points.Select(x => x - pivot).ToList();
            int             nrP = _points.Count;

            #region COVARIANCE:Old
            //// compute the covariance matrix
            //double[] m = new double[3*nrP];
            //for(int i = 0; i < nrP; i++)
            //{
            //    m[i*3] = point_deviations[i].X;
            //    m[i*3 + 1] = point_deviations[i].Y;
            //    m[i*3 + 2] = point_deviations[i].Z;
            //}
            //MatrixNxN M = new MatrixNxN(nrP, 3, m);
            //MatrixNxN MtxM = MatrixNxN.Squared(M);
            //MtxM.Scale(1.0 / nrP);
            #endregion

            // compute the covariance matrix ...
            // using 3rd party library DotNetMatrix
            double[][] pd_as_array = new double[nrP][];
            for (int i = 0; i < nrP; i++)
            {
                pd_as_array[i] = new double[] { point_deviations[i].X, point_deviations[i].Y, point_deviations[i].Z };
            }
            GeneralMatrix gm_M    = new GeneralMatrix(pd_as_array);
            GeneralMatrix gm_Mt   = gm_M.Transpose();
            GeneralMatrix gm_Msq  = gm_Mt.Multiply(gm_M);
            GeneralMatrix gm_Msqn = gm_Msq.Multiply(1.0 / nrP);

            // extract the sorted Eigenvalues of the matrix...
            // using 3rd party library DotNetMatrix
            EigenvalueDecomposition decomp  = gm_Msqn.Eigen();
            GeneralMatrix           gm_EVec = decomp.GetV();
            double[] gm_EVal = decomp.RealEigenvalues;

            // from smallest to largest eigenvalue
            vecX = new Vector3D(gm_EVec.GetElement(0, 0), gm_EVec.GetElement(1, 0), gm_EVec.GetElement(2, 0));
            vecY = new Vector3D(gm_EVec.GetElement(0, 1), gm_EVec.GetElement(1, 1), gm_EVec.GetElement(2, 1));
            vecZ = new Vector3D(gm_EVec.GetElement(0, 2), gm_EVec.GetElement(1, 2), gm_EVec.GetElement(2, 2));
        }
Пример #3
0
        public static void TestGeometricTransforms()
        {
            // get geometric properties of a reference object (e.g. BOX_01)
            Matrix3D tr_WC2LC, tr_LC2WC;

            GeometricTransforms.ComputePCATransf(GeometricTransforms.BOX_01, out tr_WC2LC, out tr_LC2WC);
            List <Point3D> BOX_01_lc     = GeometricTransforms.TransformBy(GeometricTransforms.BOX_01, tr_WC2LC);
            string         BOX_01_lc_str = GeometricTransforms.PointListToString(BOX_01_lc);

            // position a new object (e.g. BOX_02_wc) relative to the one above
            List <Point3D> BOX_02_wc     = GeometricTransforms.TransformBy(GeometricTransforms.BOX_02_LC, tr_LC2WC);
            string         BOX_02_wc_str = GeometricTransforms.PointListToString(BOX_02_wc);

            // test test
            GeometricTransforms.ComputePCATransf(GeometricTransforms.OBJ_01, GeometricTransforms.OBJ_01_CORRECTION, out tr_WC2LC, out tr_LC2WC);
            List <Point3D> OBJ_01_lc     = GeometricTransforms.TransformBy(GeometricTransforms.OBJ_01, tr_WC2LC);
            string         OBJ_01_lc_str = GeometricTransforms.PointListToString(OBJ_01_lc);
        }
Пример #4
0
        public static void ComputePCATransf(List <Point3D> _points, out Matrix3D trWC2LC, out Matrix3D trLC2WC)
        {
            trWC2LC = Matrix3D.Identity;
            trLC2WC = Matrix3D.Identity;
            if (_points == null || _points.Count < 1)
            {
                return;
            }

            Point3D  pivot;
            Vector3D vec0, vec1, vec2;

            GeometricTransforms.CalculatePCA(_points, out pivot, out vec0, out vec1, out vec2);

            // calculate the transforms
            trWC2LC = GeometricTransforms.GetTransformWC2LC(pivot, vec0, vec1, vec2);
            trLC2WC = GeometricTransforms.GetTransformLC2WC(pivot, vec0, vec1, vec2);
        }
Пример #5
0
        /// <summary>
        /// <para>Calculates the local coordinate system based on the position on the editor canvas.</para>
        /// <para>Calculates a simple path for edges which contains the ids of the start and end nodes in the first path entry.</para>
        /// </summary>
        private static void DeriveGeomPositionOutOfPlacementIn(Component.FlNetElement _nwe, System.Windows.Point _offset, double _scale, out Matrix3D ucs, out List <Point3D> path)
        {
            ucs  = Matrix3D.Identity;
            path = new List <Point3D>();
            if (_nwe == null)
            {
                return;
            }

            Point3D pivot = new Point3D(0, 0, 0);

            System.Windows.Point offset = new System.Windows.Point(_offset.X * _scale, _offset.Y * _scale);
            List <Vector3D>      axes   = new List <Vector3D>(); // x, y, z

            if (_nwe is Component.FlNetNode)
            {
                Component.FlNetNode node = _nwe as Component.FlNetNode;
                if (!(node.IsValid))
                {
                    return;
                }

                pivot.X = node.Position.X * _scale + offset.X;
                pivot.Z = node.Position.Y * _scale + offset.Y;

                axes.Add(new Vector3D(1, 0, 0));
                axes.Add(new Vector3D(0, 0, 1));
                axes.Add(new Vector3D(0, 1, 0));
            }
            else if (_nwe is Component.FlNetEdge)
            {
                Component.FlNetEdge edge = _nwe as Component.FlNetEdge;
                if (!(edge.IsValid))
                {
                    return;
                }

                pivot.X = edge.Start.Position.X * _scale + offset.X;
                pivot.Z = edge.Start.Position.Y * _scale + offset.Y;

                // the first entry in the path saves the ids of the start and end nodes to
                // communicate connectivity to the GeometryViewer
                long start_id = edge.Start.ID;
                long end_id   = edge.End.ID;
                if (edge.Start is Component.FlowNetwork)
                {
                    Component.FlowNetwork nw_start = edge.Start as Component.FlowNetwork;
                    Component.FlNetNode   nN       = nw_start.SortAndGetLastNode();
                    if (nN != null)
                    {
                        start_id = nN.ID;
                    }
                }
                if (edge.End is Component.FlowNetwork)
                {
                    Component.FlowNetwork nw_end = edge.End as Component.FlowNetwork;
                    Component.FlNetNode   n1     = nw_end.SortAndGetFirstNode();
                    if (n1 != null)
                    {
                        end_id = n1.ID;
                    }
                }

                path.Add(new Point3D(start_id, end_id, -1));
                path.Add(new Point3D(edge.Start.Position.X * _scale + offset.X, 0, edge.Start.Position.Y * _scale + offset.Y));
                path.Add(new Point3D(edge.End.Position.X * _scale + offset.X, 0, edge.End.Position.Y * _scale + offset.Y));

                Vector3D axis_x = path[1] - path[0];
                axis_x.Normalize();
                axes.Add(axis_x);
                axes.Add(new Vector3D(0, 0, 1));
                Vector3D axis_z = Vector3D.CrossProduct(axes[0], axes[1]);
                axis_z.Normalize();
                axes.Add(axis_z);
            }

            ucs = GeometricTransforms.PackUCS(pivot, axes[0], axes[1], axes[2]);
        }