Esempio n. 1
0
        private void RenderGUI()
        {
            //============================================================================
            // Render a visual marker to highlight the node that is being manipulated
            //============================================================================

            if (solver.HandleNodeIndex != -1 || solver.NearestNodeIndex != -1)
            {
                CameraData camera = DynaShapeViewExtension.CameraData;

                Triple camOrigin = new Triple(camera.EyePosition.X, -camera.EyePosition.Z, camera.EyePosition.Y);
                Triple camZ      = new Triple(camera.LookDirection.X, -camera.LookDirection.Z, camera.LookDirection.Y).Normalise();
                Triple camY      = new Triple(camera.UpDirection.X, -camera.UpDirection.Z, camera.UpDirection.Y).Normalise();
                Triple camX      = camZ.Cross(camY);

                int    nodeIndex      = solver.HandleNodeIndex != -1 ? solver.HandleNodeIndex : solver.NearestNodeIndex;
                Triple v              = solver.Nodes[nodeIndex].Position - camOrigin;
                float  screenDistance = (float)camera.NearPlaneDistance + 0.1f;
                v = camOrigin + v * screenDistance / v.Dot(camZ);

                float markerSize = 0.025f * screenDistance;

                Triple v1 = v + camX * markerSize;
                Triple v2 = v - camY * markerSize;
                Triple v3 = v - camX * markerSize;
                Triple v4 = v + camY * markerSize;

                lineGeometry.Positions.Add(v1.ToVector3());
                lineGeometry.Positions.Add(v3.ToVector3());
                lineGeometry.Positions.Add(v2.ToVector3());
                lineGeometry.Positions.Add(v4.ToVector3());

                markerSize *= 0.5f;
                v1          = v + camX * markerSize;
                v2          = v - camY * markerSize;
                v3          = v - camX * markerSize;
                v4          = v + camY * markerSize;

                lineGeometry.Positions.Add(v1.ToVector3());
                lineGeometry.Positions.Add(v2.ToVector3());
                lineGeometry.Positions.Add(v2.ToVector3());
                lineGeometry.Positions.Add(v3.ToVector3());
                lineGeometry.Positions.Add(v3.ToVector3());
                lineGeometry.Positions.Add(v4.ToVector3());
                lineGeometry.Positions.Add(v4.ToVector3());
                lineGeometry.Positions.Add(v1.ToVector3());


                int temp = lineGeometry.Indices.Count;
                for (int i = 0; i < 12; i++)
                {
                    lineGeometry.Indices.Add(temp + i);
                    lineGeometry.Colors.Add(Color.OrangeRed);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Compute the plane that best fit a set of input points (least squared orthogonal distance)
        /// </summary>
        /// <param name="points">The input points</param>
        /// <param name="planeOrigin">The output plane origin</param>
        /// <param name="planeNormal">The output plane normal vector</param>
        /// <returns>0 if the input points are identical, 1 if the input points are colinear, 2 if the input points are coplanar (already on a plane), 3 otherwise</returns>
        public static int ComputeBestFitPlane(List <Triple> points, out Triple planeOrigin, out Triple planeNormal)
        {
            Triple centroid = Triple.Zero;

            for (int i = 0; i < points.Count; i++)
            {
                centroid += points[i];
            }
            centroid /= points.Count;

            float[,] P = new float[points.Count, 3];

            for (int i = 0; i < points.Count; i++)
            {
                P[i, 0] = points[i].X - centroid.X;
                P[i, 1] = points[i].Y - centroid.Y;
                P[i, 2] = points[i].Z - centroid.Z;
            }

            Matrix <float> covariance = Matrix <float> .Build.Dense(3, 3);

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    for (int k = 0; k < points.Count; k++)
                    {
                        covariance[i, j] += P[k, i] * P[k, j];
                    }
                }
            }

            Evd <float> evd = covariance.Evd();

            planeOrigin = centroid;

            if (evd.Rank == 0) // The input points are idendtical, so we just pick an arbitrary normal vector
            {
                planeNormal = Triple.BasisZ;
            }
            else if (evd.Rank == 1
                     ) // The input points are colinear, so we just pick an arbitrary vector perpendicular to the only eigen vector
            {
                planeNormal = new Triple(evd.EigenVectors[0, 1], evd.EigenVectors[1, 1], evd.EigenVectors[2, 1])
                              .GeneratePerpendicular();
            }
            else // The normal is perpendicular to the two dominant eigen vectors
            {
                Triple e1 = new Triple(evd.EigenVectors[0, 1], evd.EigenVectors[1, 1], evd.EigenVectors[2, 1]);
                Triple e2 = new Triple(evd.EigenVectors[0, 2], evd.EigenVectors[1, 2], evd.EigenVectors[2, 2]);
                planeNormal = e2.Cross(e1).Normalise();
            }

            return(evd.Rank);
        }
Esempio n. 3
0
        public void Tessellate(IRenderPackage package, TessellationParameters parameters)
        {
            for (int i = 0; i < solver.Nodes.Count; i++)
            {
                GeometryRender.DrawPoint(package, solver.Nodes[i].Position);
            }

            for (int i = 0; i < solver.GeometryBinders.Count; i++)
            {
                solver.GeometryBinders[i].DrawGraphics(package, parameters, solver.Nodes);
            }


            //=======================================================================================
            // Draw a cursor to highlight the node that is being manipulated by the mouse
            // ... the curor is 2D, so we need to draw it in the camera coordinate system, manually
            //=======================================================================================

            CameraData camera    = ((HelixWatch3DViewModel)Solver.Viewport).Camera.Dispatcher.Invoke(() => Solver.Viewport.GetCameraInformation());
            Triple     camOrigin = new Triple(camera.EyePosition.X, -camera.EyePosition.Z, camera.EyePosition.Y);
            Triple     camZ      = new Triple(camera.LookDirection.X, -camera.LookDirection.Z, camera.LookDirection.Y).Normalise();
            Triple     camY      = new Triple(camera.UpDirection.X, -camera.UpDirection.Z, camera.UpDirection.Y).Normalise();
            Triple     camX      = camZ.Cross(camY);


            if (solver.HandleNodeIndex != -1 || solver.NearestNodeIndex != -1)
            {
                int   i           = solver.HandleNodeIndex != -1 ? solver.HandleNodeIndex : solver.NearestNodeIndex;
                Color handleColor = solver.HandleNodeIndex != -1 ? Color.OrangeRed : Color.Black;

                Triple v = solver.Nodes[i].Position - camOrigin;
                v = camOrigin + ((float)camera.NearPlaneDistance + 0.5f) * v / v.Dot(camZ);

                float handleSize = 0.008f;

                Triple v1 = v + camX * handleSize;
                Triple v2 = v - camY * handleSize;
                Triple v3 = v - camX * handleSize;
                Triple v4 = v + camY * handleSize;
                GeometryRender.DrawPolyline(package, new List <Triple> {
                    v1, v2, v3, v4, v1
                }, handleColor);

                handleSize = 0.015f;
                v1         = v + camX * handleSize;
                v2         = v - camY * handleSize;
                v3         = v - camX * handleSize;
                v4         = v + camY * handleSize;

                GeometryRender.DrawLine(package, v1, v3, handleColor);
                GeometryRender.DrawLine(package, v2, v4, handleColor);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Compute the plane that best fit a set of input points (least squared orthogonal distance)
        /// </summary>
        /// <param name="points">The input points</param>
        /// <param name="planeOrigin">The output plane origin</param>
        /// <param name="planeNormal">The output plane normal vector</param>
        /// <returns>0 if the input points are identical, 1 if the input points are colinear, 2 if the input points are coplanar (already on a plane), 3 otherwise</returns>
        //public static int ComputeBestFitPlane(List<Triple> points, out Triple planeOrigin, out Triple planeNormal)
        //{
        //    Triple centroid = Triple.Zero;
        //    for (int i = 0; i < points.Count; i++) centroid += points[i];
        //    centroid /= points.Count;

        //    float[,] P = new float[points.Count, 3];

        //    for (int i = 0; i < points.Count; i++)
        //    {
        //        P[i, 0] = points[i].X - centroid.X;
        //        P[i, 1] = points[i].Y - centroid.Y;
        //        P[i, 2] = points[i].Z - centroid.Z;
        //    }

        //    Matrix<float> covariance = Matrix<float>.Build.Dense(3, 3);

        //    for (int i = 0; i < 3; i++)
        //    for (int j = 0; j < 3; j++)
        //    for (int k = 0; k < points.Count; k++)
        //        covariance[i, j] += P[k, i] * P[k, j];

        //    Evd<float> evd = covariance.Evd();

        //    planeOrigin = centroid;

        //    if (evd.Rank == 0) // The input points are idendtical, so we just pick an arbitrary normal vector
        //        planeNormal = Triple.BasisZ;
        //    else if (evd.Rank == 1
        //    ) // The input points are colinear, so we just pick an arbitrary vector perpendicular to the only eigen vector
        //        planeNormal = new Triple(evd.EigenVectors[0, 1], evd.EigenVectors[1, 1], evd.EigenVectors[2, 1])
        //            .GeneratePerpendicular();
        //    else // The normal is perpendicular to the two dominant eigen vectors
        //    {
        //        Triple e1 = new Triple(evd.EigenVectors[0, 1], evd.EigenVectors[1, 1], evd.EigenVectors[2, 1]);
        //        Triple e2 = new Triple(evd.EigenVectors[0, 2], evd.EigenVectors[1, 2], evd.EigenVectors[2, 2]);
        //        planeNormal = e2.Cross(e1).Normalise();
        //    }

        //    return evd.Rank;
        //}
        public static int ComputeBestFitPlane(List <Triple> points, out Triple planeOrigin, out Triple planeNormal)
        {
            Triple centroid = Triple.Zero;

            for (int i = 0; i < points.Count; i++)
            {
                centroid += points[i];
            }
            centroid /= points.Count;

            float[,] P = new float[points.Count, 3];

            for (int i = 0; i < points.Count; i++)
            {
                P[i, 0] = points[i].X - centroid.X;
                P[i, 1] = points[i].Y - centroid.Y;
                P[i, 2] = points[i].Z - centroid.Z;
            }

            Matrix3x3 covariance = new Matrix3x3();

            for (int k = 0; k < points.Count; k++)
            {
                covariance.V00 += P[k, 0] * P[k, 0];
                covariance.V01 += P[k, 0] * P[k, 1];
                covariance.V02 += P[k, 0] * P[k, 2];
                covariance.V10 += P[k, 1] * P[k, 0];
                covariance.V11 += P[k, 1] * P[k, 1];
                covariance.V12 += P[k, 1] * P[k, 2];
                covariance.V20 += P[k, 2] * P[k, 0];
                covariance.V21 += P[k, 2] * P[k, 1];
                covariance.V22 += P[k, 2] * P[k, 2];
            }

            Matrix3x3 u, v;

            AForge.Math.Vector3 e;
            covariance.SVD(out u, out e, out v);

            planeOrigin = centroid;

            Triple e1 = new Triple(u.V00, u.V10, u.V20);
            Triple e2 = new Triple(u.V01, u.V11, u.V21);

            planeNormal = e2.Cross(e1).Normalise();

            return(3);
        }
Esempio n. 5
0
        internal int FindNearestNodeIndex(float range = 0.03f)
        {
            CameraData cameraData = DynaShapeViewExtension.CameraData;

            Triple camZ = new Triple(
                cameraData.LookDirection.X,
                -cameraData.LookDirection.Z,
                cameraData.LookDirection.Y).Normalise();

            Triple camY = new Triple(
                cameraData.UpDirection.X,
                -cameraData.UpDirection.Z,
                cameraData.UpDirection.Y).Normalise();

            Triple camX = camY.Cross(camZ).Normalise();

            Triple mousePosition2D = new Triple(
                DynaShapeViewExtension.MouseRayDirection.Dot(camX),
                DynaShapeViewExtension.MouseRayDirection.Dot(camY),
                DynaShapeViewExtension.MouseRayDirection.Dot(camZ));

            mousePosition2D /= mousePosition2D.Z;

            int nearestNodeIndex = -1;

            float minDistSquared = range * range;

            for (int i = 0; i < Nodes.Count; i++)
            {
                Triple v = Nodes[i].Position - DynaShapeViewExtension.MouseRayOrigin;
                v = new Triple(v.Dot(camX), v.Dot(camY), v.Dot(camZ));
                Triple nodePosition2D = v / v.Z;

                float distSquared = (mousePosition2D - nodePosition2D).LengthSquared;

                if (distSquared < minDistSquared)
                {
                    minDistSquared   = distSquared;
                    nearestNodeIndex = i;
                }
            }

            return(nearestNodeIndex);
        }
Esempio n. 6
0
        public Triple Rotate(Triple origin, Triple Axis, float angle)
        {
            Triple z = Axis.Normalise();
            Triple x = z.GeneratePerpendicular().Normalise();
            Triple y = z.Cross(x).Normalise();

            Triple v = this - origin;

            float vx = x.Dot(v);
            float vy = y.Dot(v);
            float vz = z.Dot(v);

            float sin = (float)Math.Sin(angle);
            float cos = (float)Math.Cos(angle);

            float vx_ = cos * vx - sin * vy;
            float vy_ = sin * vx + cos * vy;

            return(origin + x * vx_ + y * vy_ + z * vz);
        }
Esempio n. 7
0
        internal int FindNearestNodeIndex(IRay clickRay, float range = 0.03f)
        {
            CameraData cameraData = Viewport.GetCameraInformation();
            Triple     camZ       = new Triple(cameraData.LookDirection.X, -cameraData.LookDirection.Z,
                                               cameraData.LookDirection.Y).Normalise();
            Triple camY = new Triple(cameraData.UpDirection.X, -cameraData.UpDirection.Z, cameraData.UpDirection.Y)
                          .Normalise();
            Triple camX = camY.Cross(camZ).Normalise();

            Triple clickRayOrigin    = new Triple(clickRay.Origin.X, clickRay.Origin.Y, clickRay.Origin.Z);
            Triple clickRayDirection = new Triple(clickRay.Direction.X, clickRay.Direction.Y, clickRay.Direction.Z);

            Triple mousePosition2D = new Triple(clickRayDirection.Dot(camX), clickRayDirection.Dot(camY),
                                                clickRayDirection.Dot(camZ));

            mousePosition2D /= mousePosition2D.Z;

            int nearestNodeIndex = -1;

            float minDistSquared = range * range;

            for (int i = 0; i < Nodes.Count; i++)
            {
                Triple v = Nodes[i].Position - clickRayOrigin;
                v = new Triple(v.Dot(camX), v.Dot(camY), v.Dot(camZ));
                Triple nodePosition2D = v / v.Z;

                float distSquared = (mousePosition2D - nodePosition2D).LengthSquared;

                if (distSquared < minDistSquared)
                {
                    minDistSquared   = distSquared;
                    nearestNodeIndex = i;
                }
            }

            return(nearestNodeIndex);
        }