static ArrayList Triangulate(ref Vec3D[] v, Face f) { //verdeel Face f in meerdere kleine faces van 3 vertices //Er wordt vanuit gegaan dat een face meer dan drie vertices heeft als deze in deze methode komt. //en geef deze in een arraylist terug, MOGELIJK in een array. //BEGIN Naive/Simple implementation, ONLY works on convex polygons. ArrayList q = new ArrayList(); for (int i = 1; i < f.numberOfVertices - 1; i++) { int[] verts = new int[3]; verts[0] = f.vertices[0]; verts[1] = f.vertices[i]; verts[2] = f.vertices[i + 1]; Vec3D a, b, c; a = v[verts[0]]; b = v[verts[1]]; c = v[verts[2]]; Vec3D norm = (b.subtract(a)).cross(c.subtract(a)); double area = 0.5 * System.Math.Abs((c.subtract(a).cross(b.subtract(a)).length())); q.Add(new Face(verts, norm,area)); } return q; //END Naive/Simple implementation }
/** * Methode die het punt bepaald waarop een ray, gerepresenteerd door a en b in een array, in een face f. * De vertices van de Face f zitten in de model waar f in zit. */ static double RayTriangleIntersection(ref unitVector direction, ref Model3D model, ref Face f) { double r = 0.0; Vec3D[] v = model.vertices; Vec3D h = f.normal;// v[f.vertices[1]].subtract(v[f.vertices[0]]).cross(v[f.vertices[2]].subtract(v[f.vertices[0]])); if (h.length() > double.Epsilon) { Vec3D normal = f.normal.normalize(); //normalize the normal, then dot it with the direction vector double NU = System.Math.Abs(normal.dot(direction.vector)); if (NU > double.Epsilon) { double d = (normal.dot(v[f.vertices[0]])) / NU; if (d > r) { Vec3D P = direction.vector.times(d); //is P on the triangle? if ((v[f.vertices[0]].subtract(P).cross(v[f.vertices[1]].subtract(P))).dot(f.normal) >= 0 && (v[f.vertices[1]].subtract(P).cross(v[f.vertices[2]].subtract(P))).dot(f.normal) >= 0 && (v[f.vertices[2]].subtract(P).cross(v[f.vertices[0]].subtract(P))).dot(f.normal) >= 0) return d; } } } //the ray will not intersect with the triangle return double.NaN; }
/** * Methode die het punt bepaald waarop een ray, gerepresenteerd door a en b in een array, in een face f. * De vertices van de Face f zitten in de model waar f in zit. */ static double RayTriangleIntersection2(ref unitVector direction, ref Model3D model, ref Face f) { double r = 0.0; double d = 0.0; Vec3D[] v = model.vertices; Vec3D u = direction.vector; Vec3D A = v[f.vertices[0]]; Vec3D B = v[f.vertices[1]]; Vec3D C = v[f.vertices[2]]; Vec3D CA = A.subtract(C); Vec3D CB = B.subtract(C); Vec3D p = u.cross(CB); double det = CA.dot(p); if (det > double.Epsilon) { double AlphaS = C.times(-1.0).dot(p); if (AlphaS >= 0 && AlphaS <= det) { Vec3D q = CA.cross(C); double BetaS = u.dot(q); if (BetaS >= 0 && AlphaS + BetaS <= det) d = (CB.dot(q)) / det; } } else if(det < 0-Double.Epsilon) { double AlphaS = C.times(-1).dot(p); if (AlphaS <= 0 && AlphaS >= det) { Vec3D q = CA.cross(C); double BetaS = u.dot(q); if (BetaS <= 0 && AlphaS + BetaS >= det) d = (CB.dot(q)) / det; } } if (d > r) r = d; //the ray will not intersect with the triangle return r; }
static double[] getMinMaxPhiTheta(ref Face f, ref Vec3D[] v, ref Model3D model) { /* int minPhi = phiTheta[0]; int minTheta = phiTheta[1]; int maxPhi = phiTheta[2]; int maxTheta = phiTheta[3]; */ double[] minmax = new double[4]; minmax[0] = double.MaxValue; minmax[1] = double.MaxValue; minmax[2] = double.MinValue; minmax[3] = double.MinValue; double minX = double.MaxValue, maxX = double.MinValue, minY = double.MaxValue, maxY = double.MinValue, minZ = double.MaxValue, maxZ = double.MinValue, meanX = 0, meanY = 0, meanZ = 0; for(int k=0; k < f.numberOfVertices; k++) { Vec3D vec = v[f.vertices[k]]; updateMinMaxMeanXYZ(ref minX,ref maxX,ref meanX,vec.x,ref minY,ref maxY,ref meanY,vec.y,ref minZ,ref maxZ,ref meanZ,vec.z,k); double phi, theta; phi = System.Math.Atan2(vec.y, vec.x); theta = System.Math.Acos((vec.z) / (vec.length())); if (minmax[0] > phi) minmax[0] = phi; if (minmax[1] > theta) minmax[1] = theta; if (minmax[2] < phi) minmax[2] = phi; if (minmax[3] < theta) minmax[3] = theta; } /* //Because of the possibility of an polygon lying on all equal or close theta, the correct theta may not be found with only the points. //Trying to solve this here. Vec3D dotPoint = new Vec3D(double.NaN,double.NaN,double.NaN); double dotDist = double.MaxValue; for (int k = 0; k < f2.numberOfVertices; k++) { Vec3D a, b, edge; a = v[f.vertices[k]].copy().normalize(); b = v[f.vertices[(k + 1) % f.numberOfVertices]].copy().normalize(); edge = a.subtract(b).normalize(); double dotO = b.dot(edge); if (dotO < 0.0) { Vec3D tempPoint = b.addition(edge.times(dotO)); double tempDist = tempPoint.squaredLength(); if (dotDist > tempDist) { dotDist = tempDist; dotPoint = tempPoint; } } } minmax[3] = System.Math.Acos((dotPoint.z) / (dotPoint.length())); */ //Check om te bepalen of de polygon in het xy vlak (z is up), //zo ja, check of erboven of eronder is en pas theta aan om volledig door te lopen. if (minX < 0 && maxX > 0 && minY < 0 && maxY > 0) if (meanZ > 0) minmax[1] = 0; else minmax[3] = System.Math.PI; return minmax; }