Plane::Plane(GzCoord aVertexList[]){ GzCoord temp1, temp2; for(int i = 0; i < 3; i++){ for(int j = 0; j < 3; j++){ vertexList[i][j] = aVertexList[i][j]; } } vectorConstruct(vertexList[0], vertexList[1], temp1); vectorConstruct(vertexList[0], vertexList[2], temp2); vectorCrossProduct(temp1, temp2, normal); vectorNormalize(normal); distance = vectorDotProduct(normal, vertexList[0]); }
int Plane::findIntersectPoint(Ray& aRay, GzCoord aPoint){ GzCoord w0, temp; if(vectorZero(normal)) return -1; //triangle degenerate to a point vectorConstruct(vertexList[0], aRay.origin, w0); float a = -vectorDotProduct(normal, w0); float b = vectorDotProduct(normal, aRay.direction); if(fabs(b) < SMALL_NUM){ //ray is parallel to triangle if(a == 0){ return 2; //ray lies in triangle plane }else{ return 0; //ray disjoint from triangle plane } } float r = a/b; if(r < 0.0) return 0; //ray goes away from triangle vectorScale(r, aRay.direction, temp); vectorAdd(aRay.origin, temp, aPoint); return 1; //one intersect point }
/* DESCRIPTION: * ------------ * The function calculates the sum of the parameter vectors v1 and v2, both * containing s elements. The memory for the result must be dynamically * allocated. * * The sum between the two vectors is simply calculated by adding the * corresponding values of the two vectors and using the sums as the values of * the new vector: * * result[i] = v1[i] + v2[i] * * The function should check that neither of the parameter vectors is NULL by * using assert. * * PARAMETERS: * ------------ * double const* v1: a vector containing s elements. * double const* v2: a vector containing s elements. * size_t s: number of elements in the parameter vectors. * * RETURNS: * ------------ * A dynamically allocated vector, containing the sum of the two parameter * vectors. */ double* vectorSum(double const* v1, double const* v2, size_t size) { assert(v1); assert(v2); double* result = vectorConstruct(size, 0.0); for (size_t i = 0; i < size; i++) { result[i] = v1[i] + v2[i]; } return result; }
bool Plane::checkPointInTriangle(GzCoord aPoint){ GzCoord vector0, vector1, vector2; //compute vectors vectorConstruct(vertexList[0], vertexList[2], vector0); vectorConstruct(vertexList[0], vertexList[1], vector1); vectorConstruct(vertexList[0], aPoint, vector2); //compute dot products float dot00 = vectorDotProduct(vector0, vector0); float dot01 = vectorDotProduct(vector0, vector1); float dot02 = vectorDotProduct(vector0, vector2); float dot11 = vectorDotProduct(vector1, vector1); float dot12 = vectorDotProduct(vector1, vector2); //compute barycentric coordinates float invDenom = 1.0/(dot00*dot11 - dot01*dot01); float u = (dot11*dot02 - dot01*dot12) * invDenom; float v = (dot00*dot12 - dot01*dot02) * invDenom; //check if point is in the triangle return (u >= 0) && (v >= 0) && (u + v < 1.0); }
/* DESCRIPTION: * ------------ * The function appends all the elements of v2 (size s2) to the end of v1. * * The memory allocated for v1 must be reallocated to fit the new elements and * the new address and size are returned via the pointer parameters v1 and s1 * as pass-by-pointer. * * Pass-by-pointer means, that the function doesn't use return to return the * values, but stores the results to the address pointed to by a parameter * pointer. * * All the parameter pointer values should be asserted as not NULL. * * PARAMETERS: * ------------ * double** v1: a vector containing s1 elements. * size_t* s1: the number of elements in v1. * double const* v2: a vector containing s2 elements. * size_t s2: the number of elements in v2. * * RETURNS: * ------------ * Nothing. */ void vectorAppend(double** pv1, size_t* psize1, double const* v2, size_t size2) { assert(pv1); assert(psize1); assert(v2); double* v1 = *pv1; size_t size1 = *psize1; size_t result_size = size1 + size2; double* result = vectorConstruct(result_size, 0.0); for (size_t i = 0; i < size1; i++) { result[i] = v1[i]; } for (size_t i = 0; i < size2; i++) { result[i + size1] = v2[i]; } free(*pv1); *pv1 = result; *psize1 = result_size; }