/// <summary>
        /// Attempts to find the centroid or barycenter point of a mesh
        /// by using the average of the center of all triangles divided
        /// by their mass for an accurate representation.
        /// </summary>
        /// <param name="mesh">The mesh to find the barycenter point.</param>
        /// <returns>A <see cref="Vector3"/> containing the center.</returns>
        private static Vector3 FindBaryCenter(Shapes.IMesh mesh)
        {
            OpenTK.Vector3d totalSum  = new OpenTK.Vector3d();
            double          totalArea = 0;

            foreach (Vector3 face in mesh.Faces)
            {
                Vector3[] vertices = mesh.GetVerticesFromFace(face);

                double area = mesh.GetTriArea(vertices);
                if (area == 0)
                {
                    continue;
                }
                totalSum += OpenTK.Vector3d.Multiply(
                    (OpenTK.Vector3d)CenterOfTriangle(vertices), area);

                totalArea += area;
            }

            return((Vector3)OpenTK.Vector3d.Divide(totalSum, totalArea));
        }
Exemple #2
0
        private V3[] getExpDirections()
        {
            var v1 = new V3(1, 0, 0);

            if (radioButton1stY.Checked)
            {
                v1 = new V3(0, 1, 0);
            }
            else if (radioButton1stZ.Checked)
            {
                v1 = new V3(0, 0, 1);
            }

            var v2 = new V3(1, 0, 0);

            if (radioButton2ndY.Checked)
            {
                v2 = new V3(0, 1, 0);
            }
            else if (radioButton2ndZ.Checked)
            {
                v2 = new V3(0, 0, 1);
            }

            var v3 = new V3(1, 0, 0);

            if (radioButton3rdY.Checked)
            {
                v3 = new V3(0, 1, 0);
            }
            else if (radioButton3rdZ.Checked)
            {
                v3 = new V3(0, 0, 1);
            }

            return(new[] { v1, v2, v3 });
        }
Exemple #3
0
        public TorusKnot(int pathsteps, int shapevertices, double radius, int p, int q, int TexCount)
            : base(   )
        {
            Trace.Assert(pathsteps >= MINPathSteps, "A Path must have at least " + MINPathSteps + " Steps to form a volume.");
            Trace.Assert(shapevertices >= MINShapeVertices, "A Shape must contain at least " + MINShapeVertices + " Vertices to be considered valid and create a volume.");
            Trace.Assert(TexCount > 1, "at least 1 Texture set is required.");

            PrimitiveMode = OpenTK.Graphics.OpenGL.BeginMode.TriangleStrip;

            Vector3d[] PathPositions = new Vector3d[pathsteps];

            #region Find the center Points for each step on the path

            for (int i = 0; i < pathsteps; i++)
            {
                double Angle       = (i / (double)pathsteps) * TwoPi;
                double AngleTimesP = Angle * p;
                double AngleTimesQ = Angle * q;
                double r           = (0.5 * (2.0 + System.Math.Sin(AngleTimesQ)));

                PathPositions[i] = new Vector3d((r * System.Math.Cos(AngleTimesP)),
                                                (r * System.Math.Cos(AngleTimesQ)),
                                                (r * System.Math.Sin(AngleTimesP)));
            }
            #endregion Find the center Points for each step on the path

            #region Find the Torus length
            Vector3d result;
            double[] Lengths = new double[pathsteps];
            Vector3d.Subtract(ref PathPositions[pathsteps - 1], ref PathPositions[0], out result);
            Lengths[0] = result.Length;
            double TotalLength = result.Length;
            for (int i = 1; i < pathsteps; i++)   // skipping
            {
                Vector3d.Subtract(ref PathPositions[i - 1], ref PathPositions[i], out result);
                Lengths[i]   = result.Length;
                TotalLength += result.Length;
            }
            Trace.WriteLine("the TorusKnot's length is: " + TotalLength + " ");
            #endregion Find the Torus length

            VertexArray = new VertexT2dN3dV3d[pathsteps * shapevertices];

            #region Loft a circle Shape along the path
            double TwoPiThroughVert = TwoPi / shapevertices; // precalc for reuse
            for (uint i = 0; i < pathsteps; i++)
            {
                Vector3d last, next, normal, tangent;
                if (i == pathsteps - 1)
                {
                    next = PathPositions[0];
                }
                else
                {
                    next = PathPositions[i + 1];
                }
                if (i == 0)
                {
                    last = PathPositions[pathsteps - 1];
                }
                else
                {
                    last = PathPositions[i - 1];
                }

                Vector3d.Subtract(ref next, ref last, out tangent);   // Guesstimate tangent
                tangent.Normalize();

                Vector3d.Add(ref next, ref last, out normal);      // Approximate N
                normal.Normalize();
                Vector3d.Multiply(ref normal, radius, out normal); // scale the shape to desired radius

                for (uint j = 0; j < shapevertices; j++)
                {
                    uint index = i * (uint)shapevertices + j;

                    // Create a point on the plane and rotate it
                    OpenTK.Matrix4d RotationMatrix = OpenTK.Matrix4d.Rotate(tangent, -(j * TwoPiThroughVert));
                    OpenTK.Vector3d point          = OpenTK.Vector3d.TransformVector(normal, RotationMatrix);
                    OpenTK.Vector3d.Add(ref PathPositions[i], ref point, out VertexArray[index].Position);
                    // Since the used shape is a circle, the Vertex normal's heading is easy to find
                    OpenTK.Vector3d.Subtract(ref VertexArray[index].Position, ref PathPositions[i], out VertexArray[index].Normal);
                    VertexArray[index].Normal.Normalize();
                    // just generate some semi-useful UVs to fill blanks
                    VertexArray[index].TexCoord = new OpenTK.Vector2d((double)(i / TotalLength / TexCount), j / (shapevertices - 1.0));
                }
            }
            #endregion Loft a circle Shape along the path

            PathPositions = null; // not needed anymore

            uint currentindex = 0;

            #region Build a Triangle strip from the Vertices
            IndexArray = new uint[pathsteps * (shapevertices * 2 + 2)];   // 2 triangles per vertex, +2 due to added degenerate triangles
            for (uint i = 0; i < pathsteps; i++)
            {
                uint RowCurrent = i * (uint)shapevertices;
                uint RowBelow;
                if (i == pathsteps - 1)
                {
                    RowBelow = 0; // for the last row, the first row is the following
                }
                else
                {
                    RowBelow = (i + 1) * (uint)shapevertices;
                }

                // new ring begins here
                for (uint j = 0; j < shapevertices; j++)
                {
                    IndexArray[currentindex++] = RowCurrent + j;
                    IndexArray[currentindex++] = RowBelow + j;
                }
                // ring ends here, repeat first 2 vertices to insert 2 degenerate triangles to reach following ring
                IndexArray[currentindex++] = RowCurrent;
                IndexArray[currentindex++] = RowBelow;
            }
            #endregion Build a Triangle strip from the Vertices
        }
Exemple #4
0
 public VertexT2dN3dV3d(OpenTK.Vector2d texcoord, Vector3d normal, Vector3d position)
 {
     TexCoord = texcoord;
     Normal = normal;
     Position = position;
 }
Exemple #5
0
        /// <summary>
        /// ゴニオオブジェクトを生成
        /// </summary>
        /// <param name="gl"></param>
        /// <param name="dir"></param>
        /// <param name="angle"></param>
        private void setGonio(GLControlAlpha gl, V3[] dir, double[] angle)
        {
            gl.DeleteAllObjects();

            var r   = 0.05;
            var obj = new List <GLObject>();

            var rot = dir.Select((d, i) => Matrix3D.Rot(d, angle[i])).ToArray();

            //1st
            var mat = new Material(new C4(0.8f, 0.8f, 0f, 1f));

            obj.Add(new Cone(dir[0] * 2.1, dir[0] * -0.2, r * 2, mat, DrawingMode.Surfaces));//矢
            obj.Add(new TextObject(gl.Name.Contains("ReciPro") ? "Φ" : "1st", 12, dir[0] * 2.1 + dir[0].Normalized() * 0.01, 0.05, true, mat));

            if (!checkBoxEnable2nd.Checked)                                                                                                                    //2ndが存在しない時
            {
                obj.Add(new Cylinder(dir[0] * -1.9, dir[0] * 3.8, r, mat, DrawingMode.Surfaces));                                                              //軸
                obj.Add(new Torus(new V3(0, 0, 0), rot[0] * V3.Cross(dir[0], new V3(dir[0].Z, dir[0].X, dir[0].Y)), 1.6, r * 1.5, mat, DrawingMode.Surfaces)); //トーラス
            }
            else //2ndが存在する時
            {
                obj.Add(new Cylinder(dir[0] * -1.9, dir[0] * 0.3, r, mat, DrawingMode.Surfaces));                                //軸
                obj.Add(new Cylinder(dir[0] * 1.6, dir[0] * 0.3, r, mat, DrawingMode.Surfaces));                                 //軸
                //1stトーラスの法線は、1st軸と2nd軸が直交する方向
                obj.Add(new Torus(new V3(0, 0, 0), rot[0] * V3.Cross(dir[0], dir[1]), 1.6, r * 1.5, mat, DrawingMode.Surfaces)); //トーラス

                //以下2nd
                var rot01 = rot[0] * rot[1];
                mat = new Material(new C4(0f, 0.8f, 0.8f, 1f));
                var n = rot[0] * dir[1];
                obj.Add(new Cone(n * 2.0, -n * 0.2, r * 2, mat, DrawingMode.Surfaces));//矢
                obj.Add(new TextObject(gl.Name.Contains("ReciPro") ? "Θ" : "2nd", 12, n * 2.0 + n.Normalized() * 0.01, 0.05, true, mat));

                if (!checkBoxEnable3rd.Checked)
                {
                    obj.Add(new Cylinder(n * 1.9, -n * 3.8, r, mat, DrawingMode.Surfaces));                                                                       //軸
                    obj.Add(new Torus(new V3(0, 0, 0), rot01 * V3.Cross(dir[1], new V3(dir[1].Z, dir[1].X, dir[1].Y)), 1.1, r * 1.5, mat, DrawingMode.Surfaces)); //トーラス
                }
                else
                {
                    obj.Add(new Cylinder(n * 1.9, -n * 0.8, r, mat, DrawingMode.Surfaces));                                         //軸
                    obj.Add(new Cylinder(-n * 1.9, n * 0.8, r, mat, DrawingMode.Surfaces));                                         //軸
                    //2ndトーラスの法線は、2nd軸と3rd軸が直交する方向
                    obj.Add(new Torus(new V3(0, 0, 0), rot01 * V3.Cross(dir[1], dir[2]), 1.1, r * 1.5, mat, DrawingMode.Surfaces)); //トーラス

                    //以下、3rd
                    mat = new Material(new C4(0.8f, 0f, 0.8f, 1f));
                    var rot012 = rot[0] * rot[1] * rot[2];
                    n = rot[0] * rot[1] * dir[2];
                    obj.Add(new Cylinder(n * 1.3, -n * 2.6, r, mat, DrawingMode.Surfaces));  //軸
                    obj.Add(new Cone(n * 1.45, -n * 0.2, r * 2, mat, DrawingMode.Surfaces)); //矢
                    obj.Add(new TextObject(gl.Name.Contains("ReciPro") ? "Ψ" : "3rd", 12, n * 1.45 + n.Normalized() * 0.01, 0.05, true, mat));

                    if (dir[2].Z == 0)
                    {
                        obj.Add(new Torus(new V3(0, 0, 0), rot012 * new V3(0, 0, 1), 0.6, r * 1.5, mat, DrawingMode.Surfaces));//トーラス
                    }
                    else
                    {
                        obj.Add(new Torus(new V3(0, 0, 0), rot012 * new V3(0, 1, 0), 0.6, r * 1.5, mat, DrawingMode.Surfaces));//トーラス
                    }
                }
            }


            //中央の球
            obj.AddRange(createObject(gl, dir, angle));
            gl.AddObjects(obj);
            gl.Refresh();
        }
Exemple #6
0
 public VertexT2dN3dV3d(OpenTK.Vector2d texcoord, Vector3d normal, Vector3d position)
 {
     TexCoord = texcoord;
     Normal   = normal;
     Position = position;
 }