Ejemplo n.º 1
0
        /// <summary>
        /// Returns the angle to another vector.
        /// </summary>
        /// <remarks>
        /// The order of the directions plays a role.
        /// </remarks>
        /// <returns>Value between -PI and + PI.</returns>
        public double getAngle(Vertex dir, Vertex viewDir)
        {
            Vertex thisNomalized = new Vertex(this);

            thisNomalized.Normalize();

            Vertex viewDirNormalized = new Vertex(viewDir);

            viewDirNormalized.Normalize();

            double dotProduct = thisNomalized.ScalarProduct(viewDirNormalized);

            double arc = Math.Acos(dotProduct);

            // We construct three points from the two directions.
            // Which are then checked, to see how they are.
            Vertex vec1 = new Vertex(this);
            Vertex vec2 = new Vertex();
            Vertex vec3 = new Vertex(dir);

            try
            {
                if (vec1.areClockwise(vec2, vec3, viewDir))
                {
                    arc *= -1;
                }
                return(arc);
            }
            // The points lie on a straight line.
            catch (InvalidOperationException)
            {
                return(arc);
            }
        }
Ejemplo n.º 2
0
		public virtual void Read(BinaryReader stream)
		{
			centre = new Vertex(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle());
			directionX = new Vertex(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle());
			directionY = new Vertex(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle());
			directionZ = new Vertex(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle());

			//	The X axis in SharpGL is always (1, 0, 0).

			xAxis = new Vertex(1, 0, 0);
			float angleX = xAxis.ScalarProduct(directionX);
			yAxis = new Vertex(0, 1, 0);
			float angleY = yAxis.ScalarProduct(directionY);
			zAxis = new Vertex(0, 0, 1);
			float angleZ = zAxis.ScalarProduct(directionZ);
			angleX = (float)System.Math.Asin(angleX);
			angleY = (float)System.Math.Asin(angleY);
			angleZ = (float)System.Math.Asin(angleZ);

			angleX = (180 * angleX) / (float)Math.PI;
			angleY = (180 * angleY) / (float)Math.PI;
			angleZ = (180 * angleZ) / (float)Math.PI;

			rotate = new Vertex(-angleX, -angleY, -angleZ);

			xAxis = xAxisGL = directionX;
			yAxis = zAxisGL = directionY;
			zAxis = yAxisGL = directionZ;
			xAxisGL.X = -xAxisGL.X;

		}
Ejemplo n.º 3
0
        /// <summary>
        /// Tests the order of the points.
        ///
        /// Seen in the direction, indicated by the third parameter.
        /// </summary>
        /// <param name = "p1"> First point. </param>
        /// <param name = "p2"> Second point. </param>
        /// <param name = "viewDir"> View direction from which the sense of rotation should be calculated. </param>
        /// <exception cref="InvalidOperationException">if the points lie on a line</exception>
        public bool areClockwise(Vertex p1, Vertex p2, Vertex viewDir)
        {
            Vertex u = p2 - this;

            u.Normalize();

            Vertex v = p1 - this;

            v.Normalize();

            Vertex w = u.VectorProduct(v);

            double test = w.ScalarProduct(viewDir);

            if (Math.Abs(test) < 0.000001)
            {
                throw new InvalidOperationException("All points are on one line!");
            }

            return(test < 0);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// This function tests to see if a ray interesects the polygon.
        /// </summary>
        /// <param name="ray">The ray you want to test.</param>
        /// <param name="pointOfIntersection">The actual point of intersection (if any).</param>
        /// <returns>The distance from the origin of the ray to the intersection, or -1 if there
        /// is no intersection.</returns>
        public Intersection TestIntersection(Ray ray)
        {
            Intersection intersect = new Intersection();

            //	This code came from jgt intersect_triangle code (search dogpile for it).
            foreach (Face face in faces)
            {
                //	Assert that it's a triangle.
                if (face.Count != 3)
                {
                    continue;
                }


                //	Find the point of intersection upon the plane, as a point 't' along
                //	the ray.
                Vertex point1OnPlane = vertices[face.Indices[0].Vertex];
                Vertex point2OnPlane = vertices[face.Indices[1].Vertex];
                Vertex point3OnPlane = vertices[face.Indices[2].Vertex];
                Vertex midpointOpp1  = (point2OnPlane + point3OnPlane) / 2;
                Vertex midpointOpp2  = (point1OnPlane + point3OnPlane) / 2;
                Vertex midpointOpp3  = (point1OnPlane + point2OnPlane) / 2;

                Vertex planeNormal = face.GetSurfaceNormal(this);


                Vertex diff = point1OnPlane - ray.origin;
                float  s1   = diff.ScalarProduct(planeNormal);
                float  s2   = ray.direction.ScalarProduct(planeNormal);

                if (s2 == 0)
                {
                    continue;
                }
                float t = s1 / s2;
                if (t < 0)
                {
                    continue;
                }

                float denomintor = planeNormal.ScalarProduct(ray.direction);
                if (denomintor < 0.00001f && denomintor > -0.00001f)
                {
                    continue;                           //	doesn't intersect the plane.
                }
                //	Vertex v = point1OnPlane - ray.origin;
                //	float t = (v.ScalarProduct(planeNormal)) / denomintor;

                //	Now we can get the point of intersection.
                Vertex vIntersect = ray.origin + (ray.direction * t);

                //	Do my cool test.
                Vertex vectorTo1    = vIntersect - point1OnPlane;
                Vertex vectorTo2    = vIntersect - point2OnPlane;
                Vertex vectorTo3    = vIntersect - point3OnPlane;
                Vertex vectorMidTo1 = midpointOpp1 - point1OnPlane;
                Vertex vectorMidTo2 = midpointOpp2 - point2OnPlane;
                Vertex vectorMidTo3 = midpointOpp3 - point3OnPlane;

                if (vectorTo1.Magnitude() > vectorMidTo1.Magnitude())
                {
                    continue;
                }
                if (vectorTo2.Magnitude() > vectorMidTo2.Magnitude())
                {
                    continue;
                }
                if (vectorTo3.Magnitude() > vectorMidTo3.Magnitude())
                {
                    continue;
                }

                if (intersect.closeness == -1 || t < intersect.closeness)
                {
                    //	It's f*****g intersection city man
                    intersect.point       = vIntersect;
                    intersect.intersected = true;
                    intersect.normal      = planeNormal;
                    intersect.closeness   = t;
                }

                #region The Old Raytracing code

                ////	Get the three vertices in the face.
                //Vertex v1 = vertices[face.Indices[0].Vertex];
                //Vertex v2 = vertices[face.Indices[1].Vertex];
                //Vertex v3 = vertices[face.Indices[2].Vertex];

                ////	Find the vectors for the two edges of the tri that share v1.
                //Vertex edge1 = v2 - v1;
                //Vertex edge2 = v3 - v1;

                ////	Begin calculating the determinant, also used to calculate U parameter.
                //Vertex pVector = ray.direction.VectorProduct(edge2);
                //float determinant = edge1.ScalarProduct(pVector);

                ////	If the determinant is less than zero, it's behind the triangle i.e.
                ////	the back face. If it's very close to zero (errorvalue) it on the plane.
                //float errorvalue = 0.000001f;
                //if(determinant < errorvalue && determinant > -errorvalue)
                //    continue;

                ////	Calculate the distance from vertex 1 to ray origin.
                //Vertex tVector = ray.origin - v1;

                ////	Calculate the U parameter and test bounds.
                //float u = tVector.ScalarProduct(pVector);
                //if(u < 0 || u > determinant)
                //    continue;

                ////	Prepare to test V parameter.
                //Vertex qVector = tVector.VectorProduct(edge1);

                ////	Calculate the v parameter and test bounds.
                //float v = ray.direction.ScalarProduct(qVector);
                //if(v < 0 || v > determinant)
                //    continue;

                ////	Calculate t, scale parameters.
                //float t = edge2.ScalarProduct(qVector);
                //float inverseDeterminant = 1.0f / determinant;
                //t *= inverseDeterminant;
                //u *= inverseDeterminant;
                //v *= inverseDeterminant;

                ////	Now we have a point of intersection. Yeah. Let's got some
                ////	magnitude into the action.
                //Vertex pointOfIntersection = new Vertex(t, u, v);

                ////	OK! We've got an intersection, find how far away it it by simple
                ////	stuff: make a vector from the origin and the intersection, and
                ////	get it's magnitude.
                //Vertex vOriginToIntersection = pointOfIntersection - ray.origin;
                //float magnitude = (float)vOriginToIntersection.Magnitude();

                ////	Is this magnitude is smaller (closer) than any we've found so far?
                //if(intersect.closeness == -1 || magnitude < intersect.closeness)
                //{
                //    //	This is the closest intersection yet, so fill in the
                //    //	intersect structure.
                //    intersect.point.Set(t, u, v);
                //    intersect.intersected = true;
                //    intersect.normal = face.GetSurfaceNormal(this);
                //    intersect.closeness = magnitude;
                //}

                #endregion
            }

            return(intersect);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Rotates this vertex around an axel
 /// </summary>
 /// <param name="n">The vertex to rotate</param>
 /// <param name="a">The amount to rotate by (angle)</param>
 /// <param name="v">The axel to rotate around</param>
 /// <returns></returns>
 public static Vertex RotateAroundAxis(this Vertex n, float a, Vertex v)
 {
     return v*(float) Math.Cos(a) +
            ( n * v.ScalarProduct(n) * (1 - (float) Math.Cos(a)) + (n.VectorProduct(v)*(float) Math.Sin(a)));
 }