📄 geometry.java
字号:
geometry, `OUTSIDE` current geometry or `LIMIT` if it is near the geometry at some specified `distanceTolerance`. Note that the `INSIDE` and `OUTSIDE` cases are only feasible in `Solid`s, while `LIMIT` cases can be defined in 0D, 1D and 2D geometries. */ public int doContainmentTest(Vector3D p, double distanceTolerance) { return OUTSIDE; } /** Check the related interface contract for method Geometry.doIntersection. SPECIFIC IMPLEMENTATION: this method solve the intersection problem for one triangle in two stages: <UL> <LI>Calculates the plane containing the Triangle and checks if the Ray intersects with that plane. <LI>If the Ray intersects the plane, a check is done to determine if the intersection is inside the Triangle. </UL> That logic y repeated for all the Triangles in the TriangleMesh, and the shortest length intersected Triangle is reported.<P> Precondition:\f[ \mathbf{Q} := inOut\_Ray.direction.length() = 1 \;\f] NOTES: <UL> <LI>The plane normal is determined for each triangle as the cross product of two Triangle edge Vector3D's, algorithm step (1). <LI>The canonic equation for a plane with normal n is\f[ nx*x + ny*y +nz*z + d = 0\f] <LI>The parametric equation for the ray inOut_Ray (call it r) is\f[ \vec p = \vec{r.o} + t * \vec{r.d}\f] <LI>Combining those two equations and solving for parameter t, algorithm step (2), gives\f[ t = \frac{ -(nx*ox+ny*oy+nz*oz+d) }{ nx*dx+ny*dy+nz*dz }\f] and observing that the appearing vector components can be expressed as dot product, this equation can be rewritten in the condensed vectorial form\f[ t = \frac{ -(\vec n \cdot \vec{r.o} +d) } { \vec n \cdot \vec{r.d} }\f] <LI>Scalar value d in that equation can be solve replacing the coordinates of any of the Triangle points into the plane equation. <LI>To check if an intersected point lies inside the triangle, a left/right test is done with each one of the three directed edge vectors. If all three tests pass, then the point is inside the triangle. <LI>If the normal and the direction of the ray are in the same direction (more than 90 degrees of vector angle) then the normal is inverted to manage meshes with reversed triangles. </UL> */ public static boolean doIntersectionWithTriangle(Ray inOut_Ray, Vector3D v0, Vector3D v1, Vector3D v2, Vector3D outPoint, Vector3D outNormal) { Vector3D p; // Point of intersection between ray and plane Vector3D u, v, n; // Edge vectors and normal double t, a, b, d; // Coefficients for solving equation (2) double s1, s2, s3; // Side test for each of triangle border // The vectors u & v are two triangle edges, and define the // normal (1) u = v1.substract(v0); v = v2.substract(v1); n = v.crossProduct(u); n.normalize(); // This is the result of replacing point v0 on plane equation, // solving for d d = -n.dotProduct(v0); // Calculate numerator and denominator for equation (2) a = n.dotProduct(inOut_Ray.origin) + d; b = n.dotProduct(inOut_Ray.direction); // The denominator is big when the ray is not parallel to the plane if ( Math.abs(b) > VSDK.EPSILON ) { // Solution for equation (2), only if non-zero denominator t = (-a) / b; if ( t < 0.0 ) return false; // Calculate the intersection point between ray and plane p = inOut_Ray.origin.add(inOut_Ray.direction.multiply(t)); // Check if the point is inside the triangle s1 = u.crossProduct(p.substract(v0)).dotProduct(n); s2 = (v2.substract(v1)).crossProduct(p.substract(v1)).dotProduct(n); s3 = (v0.substract(v2)).crossProduct(p.substract(v2)).dotProduct(n); if ( (s1 >= 0 && s2 >= 0 && s3 >= 0) || (s1 <= 0 && s2 <= 0 && s3 <= 0) ) { inOut_Ray.t = t; outNormal.clone(n); outPoint.clone(p); return true; } } return false; } /** This method implements a general voxelization strategy based on containment test. Note that in the case of multiple fragment geometries (i.e. meshes and polylines) this method is usually inefficient, and for that cases voxelization should be explicit, and overload this method. Current method is usually well behaved for basic solid models. Note that `reporter` can be null. */ public void doVoxelization(VoxelVolume vv, Matrix4x4 M, ProgressMonitor reporter) { int nx = vv.getXSize(); int ny = vv.getYSize(); int nz = vv.getZSize(); int nmax; double minmax[] = getMinMax(); double greaterScale, sx, sy, sz; sx = minmax[3]-minmax[0]; sy = minmax[4]-minmax[1]; sz = minmax[5]-minmax[2]; greaterScale = sx; if ( sy > greaterScale ) { greaterScale = sy; } if ( sz > greaterScale ) { greaterScale = sz; } nmax = nx; if ( ny > nmax ) nmax = ny; if ( nz > nmax ) nmax = nz; int containmentStatus; int x, y, z; Vector3D p = new Vector3D(); Vector3D transformedP; if ( reporter != null ) { reporter.begin(); } for ( x = 0; x < nx; x++ ) { for ( y = 0; y < ny; y++ ) { if ( reporter != null ) { reporter.update(0, nx*ny, x*ny); } for ( z = 0; z < nz; z++ ) { p = vv.getVoxelPosition(x, y, z); transformedP = M.multiply(p); containmentStatus = doContainmentTest( transformedP, (1/((double)nmax) * greaterScale)); if ( containmentStatus == INSIDE || containmentStatus == LIMIT ) { vv.putVoxel(x, y, z, (byte)-1); } } } } if ( reporter != null ) { reporter.end(); } }}//===========================================================================//= EOF =//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -