Exemplo n.º 1
0
 public void TransformPointLight(Vector3D pointLightVector, Vector3D changeVector)
 {
     // Transform light vector.
     TranslateTransform3D pointLightTransform = new TranslateTransform3D();
     pointLightTransform.OffsetX = pointLightVector.X;
     pointLightTransform.OffsetY = pointLightVector.Y;
     pointLightTransform.OffsetZ = pointLightVector.Z;
     _ptLight.Position = pointLightTransform.Transform(_ptLight.Position);
 }
        public void Calculate(List<Point> listCross, int pos, int len, double angle)
        {
            m_bounds = new Rect3D();
            if (len <= 0)
            {
                return;
            }
            if (pos == 0)
            {
                m_Model3DGroup = GetNewGroup();
                myModelVisual3D.Content = m_Model3DGroup;

                Transform3DGroup transGroup = new Transform3DGroup();

                m_axB3d = new AxisAngleRotation3D(new Vector3D(0, 0, 1), sliderB.Value);
                RotateTransform3D myRotateTransform = new RotateTransform3D(m_axB3d);
                transGroup.Children.Add(myRotateTransform);

                m_axA3d = new AxisAngleRotation3D(new Vector3D(0, 1, 0), sliderA.Value);
                myRotateTransform = new RotateTransform3D(m_axA3d);
                transGroup.Children.Add(myRotateTransform);

                m_trans3d = new TranslateTransform3D(new Vector3D(0, 0, 0));
                transGroup.Children.Add(m_trans3d);

                m_Model3DGroup.Transform = transGroup;
                m_Model3DGroup.Children.Add(meshCubeModel);
            }
            GeometryModel3D myGeometryModel = new GeometryModel3D();
            m_Model3DGroup.Children.Add(myGeometryModel);

            MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D();

            Point3DCollection myPositionCollection = new Point3DCollection();

            myGeometryModel.Geometry = myMeshGeometry3D;

            List<Point3DCollection>  Discs = new List<Point3DCollection>();
            double cur_angle = 0;
            double ZIncrement = 1;
            if (MathHelper.IsZero(angle) &&
                (m_listCurve == null || m_listCurve.Count < 2) &&
                (m_listLimits == null || m_listLimits.Count < 2))
            {
                ZIncrement = len;
            }

            for (double Z = pos; Z <= pos + len; Z += ZIncrement)
            {
                Point3DCollection disc = new Point3DCollection();
                cur_angle += angle;

                AxisAngleRotation3D myRotation = new AxisAngleRotation3D(new Vector3D(0, 0, 1), cur_angle);
                RotateTransform3D myRotateTransform = new RotateTransform3D(myRotation);
                TranslateTransform3D transTransform = new TranslateTransform3D(0, 0, Z);
                //ScaleTransform3D ScaleTrans = new ScaleTransform3D(new Vector3D(Zoom, Zoom, 0), new Point3D(0, 0, Z));
                double RadLimit = GetRadiusLimit(Z);
                double RadIncrement = GetRadiusIncrement(Z);
                if (listCross.First() != listCross.Last())
                {//make closed loop
                    listCross.Add(listCross.First());
                }

                for (int i = 0; i < listCross.Count; i++ )
                {
                    double x = listCross[i].X;
                    double y = listCross[i].Y;

                    Vector3D vec = new Vector3D(x, y, 0);

                    if (!MathHelper.IsZero(RadIncrement))
                    {
                        Vector3D vecNorm = new Vector3D(x, y, 0);
                        double ZoomFactor = RadIncrement/10;
                        vec *= ZoomFactor;
                    }

                    if (vec.Length > RadLimit)
                    {
                        Vector3D vecNorm = new Vector3D(x, y, 0);
                        vecNorm.Normalize();
                        vec = vecNorm * RadLimit;
                    }

                    Point3D newPoint = (Point3D)myRotateTransform.Transform(vec);
                    newPoint = transTransform.Transform(newPoint);

                    disc.Add(newPoint);
                }

                if (Discs.Count == 0)
                {
                    //крышки над примитивами
                    Point3DCollection disc0 = new Point3DCollection();
                    for (int i = 0; i < disc.Count; i++)
                    {
                        Point3D pt = disc[i];
                        pt.X = 0;
                        pt.Y = 0;
                        disc0.Add(pt);
                    }
                    Discs.Add(disc0);
                }
                Discs.Add(disc);
            }

            SolidColorBrush mySolidBrush1 = new SolidColorBrush();
            mySolidBrush1.Color = Color.FromRgb(200, 110, 110);
            DiffuseMaterial FrontMaterial = new DiffuseMaterial(mySolidBrush1);

            SolidColorBrush mySolidBrush = new SolidColorBrush();
            mySolidBrush.Color = Color.FromRgb(110, 200, 110);
            DiffuseMaterial BackMaterial = new DiffuseMaterial(mySolidBrush);

            myGeometryModel.Material = FrontMaterial;
            myGeometryModel.BackMaterial = BackMaterial;

            for (int i = 1; i < Discs.Count; i++)
            {
                Point3DCollection disc1 = Discs[i - 1];
                Point3DCollection disc2 = Discs[i];

                for (int j = 1; j < disc1.Count; j++)
                {
                    Point3D p1 = disc1[j - 1];
                    Point3D p2 = disc1[j];
                    Point3D p3 = disc2[j];
                    Point3D p4 = disc2[j - 1];

                    myPositionCollection.Add(p4);
                    myPositionCollection.Add(p3);
                    myPositionCollection.Add(p1);

                    myPositionCollection.Add(p1);
                    myPositionCollection.Add(p3);
                    myPositionCollection.Add(p2);
                }
            }

            myMeshGeometry3D.Positions = myPositionCollection;
            m_bounds.Union(myMeshGeometry3D.Bounds);
            Size3D mySize = m_bounds.Size;
            string s = string.Format("X:{0},Y:{1},Z:{2}",(int)mySize.X,(int)mySize.Y,(int)mySize.Z);
            labelInfo.Content = s;
        }
Exemplo n.º 3
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool MoveToANewPosition(Vertex pickedVertex, List<Face> lastTimeMovedFaces, Edge lastFoldingLine,
            Edge foldingLine, Point3D projectionPoint, Point3D lastProjectionPoint)
        {
            CloverController cloverController = CloverController.GetInstance();

            // 用于计算矩阵的两个关键向量
            Vector3D vectorFromLastFoldingLineToOriginVertex = new Vector3D();
            Vector3D vectorFromCurrentFoldingLineToProjVertex = new Vector3D();

            // 更新当前选中点到最新的状态
            Vertex currentVertex = cloverController.VertexLayer.GetVertex(pickedVertex.Index);

            // 从上次移动的面中找到带有选中点的那个面
            Face pickedFaceAfterCutting = null;

            // 从上次移动的面中找到带有选中点的那个面
            foreach (Face face in lastTimeMovedFaces)
            {
                foreach (Vertex v in face.Vertices)
                {
                    if (v == currentVertex)
                    {
                        if (pickedFaceAfterCutting == null || pickedFaceAfterCutting.Layer > face.Layer)
                            pickedFaceAfterCutting = face;
                        break;
                    }
                }
            }

            if (pickedFaceAfterCutting == null)
                return false;

            // 在选定的面上找到与折线边顶点位置相等的那条边
            Edge foldingLineOnFace = null;
            foreach (Edge e in pickedFaceAfterCutting.Edges)
            {
                if (CloverMath.AreTwoEdgesEqual(e, lastFoldingLine))
                    foldingLineOnFace = e;
            }

            if (null == foldingLineOnFace)
                return false;

            // 在找到选顶点与折线的一条连线边,计算出计算角度所需的向量1
            Edge edgeBeforeMoving = null;
            foreach (Edge e in pickedFaceAfterCutting.Edges)
            {
                if (e.Vertex1 == currentVertex && e.Vertex2 == foldingLineOnFace.Vertex1)
                {
                    edgeBeforeMoving = e;
                    break;
                }
                if (e.Vertex2 == currentVertex && e.Vertex1 == foldingLineOnFace.Vertex1)
                {
                    edgeBeforeMoving = e;
                    break;
                }
                if (e.Vertex1 == currentVertex && e.Vertex2 == foldingLineOnFace.Vertex2)
                {
                    edgeBeforeMoving = e;
                    break;
                }
                if (e.Vertex2 == currentVertex && e.Vertex1 == foldingLineOnFace.Vertex2)
                {
                    edgeBeforeMoving = e;
                    break;
                }
            }

            // 得到关键向量1
            vectorFromLastFoldingLineToOriginVertex = edgeBeforeMoving.Vertex2.GetPoint3D() - edgeBeforeMoving.Vertex1.GetPoint3D();

            // 在原始面中找到折线顶点所在的两条边,并用这两条边计算折线的纹理坐标
            foreach (Edge e in pickedFaceAfterCutting.Parent.Edges)
            {
                // 判断折线的两个顶点,更新坐标并计算纹理
                // 顶点1
                if (CloverMath.IsPointInTwoPoints(foldingLineOnFace.Vertex1.GetPoint3D(), e.Vertex1.GetPoint3D(), e.Vertex2.GetPoint3D()))
                {
                    cloverController.FoldingSystem.CalculateTexcoord(foldingLineOnFace.Vertex1, e);
                    if (CloverMath.IsPointInTwoPoints(foldingLine.Vertex1.GetPoint3D(), e.Vertex1.GetPoint3D(), e.Vertex2.GetPoint3D()))
                    {
                        foldingLineOnFace.Vertex1.SetPoint3D(foldingLine.Vertex1.GetPoint3D());
                        foldingLineOnFace.Vertex1.Moved = true;
                    }
                    else
                    {
                        foldingLineOnFace.Vertex1.SetPoint3D(foldingLine.Vertex2.GetPoint3D());
                        foldingLineOnFace.Vertex1.Moved = true;
                    }
                }

                // 顶点2
                if (CloverMath.IsPointInTwoPoints(foldingLineOnFace.Vertex2.GetPoint3D(), e.Vertex1.GetPoint3D(), e.Vertex2.GetPoint3D()))
                {
                    cloverController.FoldingSystem.CalculateTexcoord(foldingLineOnFace.Vertex2, e);
                    if (CloverMath.IsPointInTwoPoints(foldingLine.Vertex1.GetPoint3D(), e.Vertex1.GetPoint3D(), e.Vertex2.GetPoint3D()))
                    {
                        foldingLineOnFace.Vertex2.SetPoint3D(foldingLine.Vertex1.GetPoint3D());
                        foldingLineOnFace.Vertex2.Moved = true;
                    }
                    else
                    {
                        foldingLineOnFace.Vertex2.SetPoint3D(foldingLine.Vertex2.GetPoint3D());
                        foldingLineOnFace.Vertex2.Moved = true;
                    }
                }
            }
            // 设置选中点的新位置为projectinPoint;
            currentVertex.SetPoint3D(projectionPoint);
            currentVertex.Moved = true;

            // 找到选中点和折线之间的向量,得到关键向量2
            vectorFromCurrentFoldingLineToProjVertex = edgeBeforeMoving.Vertex2.GetPoint3D() - edgeBeforeMoving.Vertex1.GetPoint3D();

            // 计算所有上次移动面的折线,对于折线完全相等的直接更新到新的位置,对于不相等的要重新找打对应的边,然后计算折线位置,再更新折线
            foreach (Face face in lastTimeMovedFaces)
            {
                if (face == pickedFaceAfterCutting)
                    continue;

                Edge foldingLineForThisFace = null;
                foreach (Edge e in face.Edges)
                {
                    // 找到与原来折线共线的那条边
                    Point3D crossedPoint = new Point3D();
                    if (2 == CloverMath.GetIntersectionOfTwoSegments(lastFoldingLine, e, ref crossedPoint))
                    {
                        foldingLineForThisFace = e;
                        break;
                    }
                }

                // 假如木有折线,或者折线中的其中一个点和上面的折线拥有相同点返回
                if (foldingLineForThisFace == null)
                {
                    // 采用点更新法
                    foreach (Edge e in face.Edges)
                    {
                        // 假如其中有一条边的一个顶点等于新折线,而另一个顶点等于旧折线中的点,折更新旧点到新点
                    }
                    continue;
                }

                // 计算现在的折线位置
                Edge currentFoldingLineForThisFace = CloverTreeHelper.GetEdgeCrossedFace(face, foldingLine);
                if (currentFoldingLineForThisFace == null)
                    continue;

                // 通过该面的原始面查询折线并更新折线位置和纹理坐标
                foreach (Edge e in face.Parent.Edges)
                {
                    // 判断折线的两个顶点,更新坐标并计算纹理
                    // 顶点1
                    if (CloverMath.IsPointInTwoPoints(foldingLineForThisFace.Vertex1.GetPoint3D(), e.Vertex1.GetPoint3D(), e.Vertex2.GetPoint3D()) &&
                        !foldingLineForThisFace.Vertex1.Moved)
                    {
                        cloverController.FoldingSystem.CalculateTexcoord(foldingLineForThisFace.Vertex1, e);
                        if (CloverMath.IsPointInTwoPoints(currentFoldingLineForThisFace.Vertex1.GetPoint3D(), e.Vertex1.GetPoint3D(), e.Vertex2.GetPoint3D()))
                        {
                            foldingLineOnFace.Vertex1.SetPoint3D(currentFoldingLineForThisFace.Vertex1.GetPoint3D());
                            foldingLineOnFace.Vertex1.Moved = true;
                        }
                        else
                        {
                            foldingLineOnFace.Vertex1.SetPoint3D(currentFoldingLineForThisFace.Vertex2.GetPoint3D());
                            foldingLineOnFace.Vertex1.Moved = true;
                        }
                    }

                    // 顶点2
                    if (CloverMath.IsPointInTwoPoints(foldingLineForThisFace.Vertex2.GetPoint3D(), e.Vertex1.GetPoint3D(), e.Vertex2.GetPoint3D()) &&
                        !foldingLineForThisFace.Vertex2.Moved)
                    {
                        cloverController.FoldingSystem.CalculateTexcoord(foldingLineForThisFace.Vertex2, e);
                        if (CloverMath.IsPointInTwoPoints(currentFoldingLineForThisFace.Vertex1.GetPoint3D(), e.Vertex1.GetPoint3D(), e.Vertex2.GetPoint3D()))
                        {
                            foldingLineOnFace.Vertex2.SetPoint3D(currentFoldingLineForThisFace.Vertex1.GetPoint3D());
                            foldingLineOnFace.Vertex2.Moved = true;
                        }
                        else
                        {
                            foldingLineOnFace.Vertex2.SetPoint3D(currentFoldingLineForThisFace.Vertex2.GetPoint3D());
                            foldingLineOnFace.Vertex2.Moved = true;
                        }
                    }
                }
            }

            // 求得旋转量,并创建旋转矩阵
            Vector3D axis = Vector3D.CrossProduct(vectorFromCurrentFoldingLineToProjVertex, vectorFromLastFoldingLineToOriginVertex);
            axis.Normalize();
            axis.Negate();
            double angle = Vector3D.AngleBetween(vectorFromCurrentFoldingLineToProjVertex, vectorFromLastFoldingLineToOriginVertex);
            AxisAngleRotation3D asixRotation = new AxisAngleRotation3D(axis, angle);
            RotateTransform3D rotateTransform = new RotateTransform3D(asixRotation);
            rotateTransform.CenterX = projectionPoint.X;
            rotateTransform.CenterY = projectionPoint.Y;
            rotateTransform.CenterZ = projectionPoint.Z;

            // 创建平移矩阵
            Vector3D vectorFromProjToOrigin = projectionPoint - lastProjectionPoint;
            TranslateTransform3D translateTransform = new TranslateTransform3D(vectorFromProjToOrigin);

            // 移动所有没有移动过的顶点
            foreach (Face face in lastTimeMovedFaces)
            {
                foreach (Vertex v in face.Vertices)
                {
                    if (!v.Moved)
                    {
                        v.SetPoint3D(translateTransform.Transform(v.GetPoint3D()));
                        v.SetPoint3D(rotateTransform.Transform(v.GetPoint3D()));
                        v.Moved = true;
                    }
                }
            }

            // 最终更改所有顶点移动属性复位
            foreach (Face face in lastTimeMovedFaces)
            {
                foreach (Vertex v in face.Vertices)
                {
                    v.Moved = false;
                }
            }

            // 更新渲染层
            // 也许UpdateAll曾今给了你们许多欢乐的时光,但现在它应该退场了 ---kid
            //cloverController.RenderController.UpdateAll();
            //foreach (Face face in lastTimeMovedFaces)
            //{
            //    cloverController.RenderController.Update(face);
            //}
            // 好吧。。你们还是继续使用UpdateAll好了。。 ---kid
            cloverController.RenderController.UpdateAll();

            return true;
        }
        public void UpdatePosition2(Point3D intersection)
        {
            Point3DCollection millPositionCollection = new Point3DCollection();
            Vector3D vecTransform = new Vector3D(intersection.X, intersection.Y, 0);
            vecTransform.Normalize();
            vecTransform *= 50;
            TranslateTransform3D myRotateTransform = new TranslateTransform3D(vecTransform);
            {
                Point3D p2 = myRotateTransform.Transform(intersection);
                Point3D p3 = p2;
                p3.Z += 20;
                millPositionCollection.Add(intersection);
                millPositionCollection.Add(p2);
                millPositionCollection.Add(p3);
            }

            meshCube.Positions = millPositionCollection;
            Vector3D intersection1 = (Vector3D)intersection;
            intersection1.Z = 0;
            string s = string.Format("Len:{3}  X:{0},Y:{1},Z:{2}",
                (int)intersection.X, (int)intersection.Y, (int)intersection.Z,
                (int)intersection1.Length);

            labelInfo2.Content = s;
        }