예제 #1
0
		/// <summary>
		/// Copy constructor.
		/// </summary>
		/// <param name="?"></param>
		public Vector(Vector vectSource)
		{
			if (vectSource == null)
				throw new Exception("Error in Vector.Vector() - source vector cannot be null.");
			Resize(vectSource.arrVector.Length, false);
			for (int iIndex = 0; iIndex < vectSource.arrVector.Length; iIndex++)
			{
				arrVector[iIndex] = vectSource.arrVector[iIndex];
			}
		}
예제 #2
0
		private Color VectorToColor(Vector vectColor)
		{
			vectColor = vectColor.Limit(0, 1.0);
			Color clNewColor = Color.FromArgb((int)(vectColor[0] * 255), (int)(vectColor[1] * 255.0),
								(int)(vectColor[2] * 255.0));
			return clNewColor;
		}
예제 #3
0
		private Vector ColorToVector(Color clColor){
			Vector vectColor = new Vector(3, true);
			vectColor[0] = clColor.R / 255.0;		// red component
			vectColor[1] = clColor.G / 255.0;		// green component
			vectColor[2] = clColor.B / 255.0;		// blue component
			return vectColor;
		}
예제 #4
0
		public void SetupVectA()
		{
			vectA = new Vector(3);
			vectA[0] = 2;
			vectA[1] = -1;
			vectA[2] = 1;
		}
예제 #5
0
		public PointLightSource(double dXPos, double dYPos, double dZPos)
		{
			vectPosition = new Vector(dXPos, dYPos, dZPos);
		}
예제 #6
0
		public override double IntersectionTest(Vector vectRay, Vector vectOrigin)
		{
			throw new Exception("The method or operation is not implemented.");
		}
예제 #7
0
		public override double IntersectionTest(Vector vectRayStart, Vector vectRayEnd)
		{
			Vector vectRayDirection = (vectRayEnd - vectRayStart).Normalize();
			double dA = vectRayDirection.DotProduct(vectRayDirection);
			Vector vectSphereToRayOrigin = vectRayStart - vectPosition;
			double dB = 2 * vectRayDirection.DotProduct(vectSphereToRayOrigin);
			double dC = (vectSphereToRayOrigin).DotProduct(vectSphereToRayOrigin) - (dRadius * dRadius);
			double dDiscriminant = (dB * dB) - (4 * dA * dC);

			double dt = 0;
			double dt1, dt2;
			if (dDiscriminant >= 0)  // has a solution
			{
				dt1 = (-dB - Math.Sqrt(dDiscriminant)) / (2.0 * dA);
				dt2 = (-dB + Math.Sqrt(dDiscriminant)) / (2.0 * dA);
				if (dt1 < dt2)
					dt = dt1;
				else
					dt = dt2;
			}
			return dt;
		}
예제 #8
0
		/// <summary>
		/// An interstion test performs an analysis along a ray to determine if
		/// the ray passes through a 3d object in a scene. The value returned
		/// reflect the point along that ray where the insesction begins.
		/// 
		/// If zero is returned, then no intersection has occured.
		/// 
		/// To get the actual 3D position where the intersection occured, use the
		/// following formula (where t is a possible value returned):
		/// 
		/// p(t) = o + t(s - o)
		/// 
		/// Where o is the origin position (vectOrigin), t is the value returned 
		/// by this method, and s is the direction vector (vectRay).
		/// </summary>
		public abstract double IntersectionTest(Vector vectRayStart, Vector vectRayEnd);
예제 #9
0
		/// <summary>
		/// Creates a new vector that is the unit vector for
		/// for this vector.
		/// </summary>
		public Vector Normalize()
		{
			if (arrVector == null)
				return new Vector(0);
			Vector vectNormalized = new Vector(arrVector.Length, true);
			double dUnitLength = Length;
			if (arrVector != null && dUnitLength > 0)
			{
				for (int iIndex = 0; iIndex < arrVector.Length; iIndex++)
				{
					vectNormalized[iIndex] = arrVector[iIndex] / dUnitLength;
				}
			}
			return vectNormalized;
		}
예제 #10
0
		/// <summary>
		/// Returns the dot product of this and the second provided vector,
		/// </summary>
		/// <param name="vect"></param>
		/// <returns></returns>
		public double DotProduct(Vector vect)
		{
			if (vect == null)
				return 0;
			if (vect.arrVector == null || arrVector == null)
				throw new Exception ("Error in Vector.DotProduct(). The vector cannot be a null vector.");
			if (vect.Size != Size)
				throw new Exception ("Error in Vector.DotProduct(). Both vectors cannot be of the same size.");
			double dResult = 0;
			for (int iIndex = 0; iIndex < arrVector.Length; iIndex++)
			{
				dResult += vect.arrVector[iIndex] * arrVector[iIndex]; 
			}
			return dResult;
		}
예제 #11
0
		/// <summary>
		/// Calculates the angle betweeen two vectors. Angle returned is in degrees.
		/// </summary>
		public double Angle(Vector vect)
		{
			double dVal = DotProduct(vect) / (Length * vect.Length);
			return Math.Acos(dVal) * (180.0 / Math.PI);
		}
예제 #12
0
		public static Vector operator* (Vector vect1, Vector vect2) {
			if (vect1 == null || vect2 == null)
				throw new NullReferenceException();
			if (vect1.arrVector == null || vect2.arrVector == null)
				throw new Exception("Multiplying by null vector is not permitted.");
			if (vect1.arrVector.Length != vect2.arrVector.Length)
				throw new Exception("Multiplying two vectors together by different lengths is not permitted.");
			Vector vectResult = new Vector(vect1.arrVector.Length, true);
			for (int iIndex = 0; iIndex < vect1.arrVector.Length; iIndex++)
			{
				vectResult.arrVector[iIndex] = vect1.arrVector[iIndex] * vect2.arrVector[iIndex];
			}
			return vectResult;
		}
예제 #13
0
		public static Vector operator* (Vector vect, double dVal)
		{
			if (vect == null)
				throw new NullReferenceException();
			if (vect.arrVector == null)
				throw new Exception("Scaling a null vector is not permitted.");
			Vector vectResult = new Vector(vect.arrVector.Length, true);
			for (int iIndex = 0; iIndex < vect.arrVector.Length; iIndex++)
			{
				vectResult.arrVector[iIndex] = dVal * vect.arrVector[iIndex];
			}
			return vectResult;
		}
예제 #14
0
		public static Vector operator- (Vector vect1, Vector vect2)
		{
			if (vect1 == null || vect2 == null)
				throw new NullReferenceException();
			if (vect1.arrVector == null || vect2.arrVector == null)
				throw new Exception("Subtraction of null vectors is not permitted.");
			if (vect1.arrVector.Length != vect2.arrVector.Length)
				throw new Exception("Cannot subtract - vectors are not of the same size.");
			Vector vectResult = new Vector(vect1.arrVector.Length, true);
			for (int iIndex = 0; iIndex < vect1.arrVector.Length; iIndex++)
			{
				vectResult.arrVector[iIndex] = vect1.arrVector[iIndex] - vect2.arrVector[iIndex];
			}
			return vectResult;
		}
예제 #15
0
		public void SetupVectB()
		{
			vectB = new Vector(3);
			vectB[0] = 1;
			vectB[1] = 1;
			vectB[2] = 2;
		}
예제 #16
0
		public Camera(double dXPos, double dYPos, double dZPos,
			double dLookAtX, double dLookAtY, double dLookAtZ,
			double dUpX, double dUpY, double dUpZ)
		{
			vectPosition = new Vector(dXPos, dYPos, dZPos);
			vectLookAt = new Vector(dLookAtX, dLookAtY, dLookAtZ);
			vectUp = new Vector(dUpX, dUpY, dUpZ);
		}
예제 #17
0
		public Object3D(double dXPos, double dYPos, double dZPos)
		{
			vectPosition = new Vector(dXPos, dYPos, dZPos);
		}
예제 #18
0
		/// <summary>
		/// Adjusts the values of a vector so that they are within
		/// the limits imposed by Min and Max.
		/// </summary>
		/// <param name="dMin"></param>
		/// <param name="dMax"></param>
		/// <returns></returns>
		public Vector Limit(double dMin, double dMax)
		{
			if (arrVector == null)
				return new Vector(0);
			if (dMin > dMax)
			{
				double dTemp = dMin;
				dMin = dMax;
				dMax = dTemp;
			}
			Vector vectLimited = new Vector(arrVector.Length, true);
			for (int iIndex = 0; iIndex < vectLimited.Size; iIndex++)
			{
				if (arrVector[iIndex] < dMin)
					vectLimited[iIndex] = dMin;
				else if (arrVector[iIndex] > dMax)
					vectLimited[iIndex] = dMax;
				else
					vectLimited[iIndex] = arrVector[iIndex];
			}
			return vectLimited;
		}
예제 #19
0
		public abstract Vector GetSurfaceNormal(Vector vectSurfacePosition);
예제 #20
0
		/// <summary>
		/// Copy constructor with a vector.
		/// </summary>
		public Matrix (Vector vect)
		{
			Assign(vect);
		}
예제 #21
0
		public override Vector GetSurfaceNormal(Vector vectSurfacePosition)
		{
			return (vectSurfacePosition - vectPosition).Normalize();
		}
예제 #22
0
		/// <summary>
		/// Makes the matrix an exact duplicate of the provided vector.
		/// </summary>
		public void Assign(Vector vect)
		{
			int iColumns = vect.Size;
			arrMatrix = Create2DArray(1, iColumns);
			if (arrMatrix == null)
				return;
			for (int iCol = 0; iCol < iColumns; iCol++)
			{
				arrMatrix[0, iCol] = vect[iCol];
			}
		}
예제 #23
0
		public override Vector GetSurfaceNormal(Vector vectSurfacePosition)
		{
			Vector vectNormal = (vectSurfacePosition - vectPosition).Normalize(); // *(1.0 / dSize);
			return vectNormal;
		}
예제 #24
0
		/// <summary>
		/// Multiplies a vector by the matrix in order to produce a new vector.
		/// An exception is thrown if the vector has a size that is not equal
		/// to then number of rows in the matrix, or if the matrix is null or
		/// vector is null. Equivalent to VECT * MAT = VECT
		/// </summary>
		public Vector Multiply(Vector vect)
		{
			if (vect == null)
				throw new NullReferenceException("Error in Matrix.Multiply." +
					"Provided vector object is null.");
			if (arrMatrix == null)
				throw new Exception("Error in Matrix.Multiply. " + 
					"This matrix is a null matrix.");
			if (vect.IsNull)
				throw new Exception("Error in Matrix.Multiply. " + 
					"Provided vector is a null vector.");
			int iRows = Rows;
			int iColumns = Columns;
			if (iRows != vect.Size)
				throw new Exception("Error in Matrix.Multiply. " + 
					"The number vector is not the same size as the number " +
					"of rows in the matrix.");
			// convert the vector to a matrix
			Matrix matResult = new Matrix(vect);
			matResult = matResult.Multiply(this);
			// create a new matrix that is of the same # or rows as the result
			Vector vectResult = new Vector(iColumns);
			for (int iIndex = 0; iIndex < iColumns; iIndex++)
			{
				vectResult[iIndex] = matResult[0, iIndex];
			}
			return vectResult;
		}
예제 #25
0
		private Vector TraceRay(Vector vectRayStart, Vector vectRayEnd, int iRayCount)
		{
			// establish a vector of base intenisites (current "black").
			Vector vectIntensity = new Vector(3);
			Vector vectSpecular = new Vector(3);
			// make sure we don't recurse any more than we have to
			if (iRayCount > iMaxRecursion)
				return vectIntensity;
			// first, find the object that intersects the ray at the start position
			Object3D obj3dClosest = null;
			double dtClosest = 0;
			for (int iIndex = 0; iIndex < arrObjects.Count; iIndex++)
			{
				Object3D obj3dCurrent = (Object3D)arrObjects[iIndex];
				if (obj3dCurrent == null)
					continue;
				// convert the object to eye coordinates
				double dtCurrent = obj3dCurrent.IntersectionTest(vectRayStart, vectRayEnd);
				// check for any intersection
				if (dtCurrent <= 0)
					continue;
				// intersection - ray has hit an object
				if (obj3dClosest == null || dtCurrent < dtClosest)
				{
					obj3dClosest = obj3dCurrent;
					dtClosest = dtCurrent;
				}
			}
			// no object intersect the ray, so return black, or 0 intensity
			if (obj3dClosest == null)
				return vectIntensity;
			// shadow ray flag
			bool bIsShadowRay = false;

			// establish a base intensity of the object
			vectIntensity = vectAmbientLightIntensity * vectAmbientLightColor * obj3dClosest.AmbientColor;

			// now, go through all point light sources, and see if it
			// influences the color of the light

			// get 3d position where the ray touched the object
			Vector vectRay = (vectRayEnd - vectRayStart).Normalize();
			Vector vectSurfacePoint = vectRayStart + dtClosest * vectRay;
			// get the normal of the surface hit
			Vector vectSurfaceNormal = obj3dClosest.GetSurfaceNormal(vectSurfacePoint);
			// tiny adjustment
			vectSurfacePoint += (vectSurfaceNormal * 0.01);
			for (int iIndex = 0; iIndex < arrPointLightSources.Count; iIndex++)
			{
				// get the point light source in the scene
				PointLightSource plsLight = (PointLightSource)arrPointLightSources[iIndex];
				if (plsLight == null)
					continue;
				bIsShadowRay = false;
				// convert the light source to UVW coodinates
				//Vector vectLightRay = plsLight.Position - vectSurfacePoint;
				// test to see how far away the light intersects the vector
				// dt = obj3dClosest.IntersectionTest(plsLight.Position, vectSurfacePoint);
				// test to see if the ray is in the shadow of another object wrt
				// the light source - assuming that the light ray to the surface of
				// of the object is 1.0, then any objects between the light source
				// and the current object will have a value between 0 and 1
				for (int iIndex2 = 0; iIndex2 < arrObjects.Count; iIndex2++)
				{
					Object3D obj3dCurrent = (Object3D)arrObjects[iIndex2];
					if (obj3dCurrent == null || obj3dClosest == obj3dCurrent)
						continue;
					dtClosest = obj3dCurrent.IntersectionTest(vectSurfacePoint, plsLight.Position);
					// yes, there is another object in the way of this object, so the
					// ray cast by the light source is actually a shadow ray for this object

					if (dtClosest > 0)
					{
						bIsShadowRay = true;
						break;
					}
				}
				// if the ray is a shadow ray, then the light from the light source does not contribute
				// to the light in the ray, so just continue on to the next light source
				if (bIsShadowRay)
					continue;

				// ok, so the light source contributes to the light shown on the object
				Vector vectLightVector = (plsLight.Position - vectSurfacePoint).Normalize();

				//Vector vectLightVector = new Vector(0, 1, 0);
				// calculate diffuse component of the light source
				Vector vectDiffuse = (plsLight.Diffuse * obj3dClosest.DiffuseColor *
					vectSurfaceNormal.DotProduct(vectLightVector)).Limit(0,1);
				vectIntensity += vectDiffuse;
				// get the inverse of the viewing ray

				// calculate specular component of the light source
				// get the "Halfway" vector
				Vector vectH = (vectLightVector + vectRay * -1).Normalize();
				vectSpecular = (plsLight.Specular * obj3dClosest.SpecularColor *
					Math.Pow(vectH.DotProduct(vectSurfaceNormal), obj3dClosest.SpecularPow)).Limit(0, 1);
				vectIntensity += vectSpecular;

			}
			Vector vectRecursiveRay = vectRay - (2 * vectRay.DotProduct(vectSurfaceNormal) * vectSurfaceNormal);
			Vector vectReflectiveIntensity = (TraceRay(vectSurfacePoint, vectRecursiveRay + vectSurfacePoint, 
				++iRayCount)).Limit(0, 1);
			vectIntensity += obj3dClosest.SpecularColor * vectReflectiveIntensity;

			// add the final and reflective colors together
			return vectIntensity; //  +vectReflectiveIntensity;
		}
예제 #26
0
		public static Vector CrossProduct(Vector vectA, Vector vectB)
		{
			if (vectA == null || vectB == null)
				throw new NullReferenceException();
			if (vectA.Size == 0 || vectB.Size == 0)
				throw new Exception("Error in MatrixMath.CrossProduct. Neither vector can be a null vector.");
			if (vectA.Size != 3 || vectB.Size != 3)
				throw new Exception("Error in MatrixMath.CrossProduct. Both vectors must be of size 3.");
			return new Vector(
				vectA[1] * vectB[2] - vectA[2] * vectB[1],
				vectA[2] * vectB[0] - vectA[0] * vectB[2],
				vectA[0] * vectB[1] - vectA[1] * vectB[0]);
		}