📄 parametricbicubicpatch.java
字号:
mz[0][0] = vp00[0].z; mx[0][1] = vp01[0].x; my[0][1] = vp01[0].y; mz[0][1] = vp01[0].z; mx[1][0] = vp10[0].x; my[1][0] = vp10[0].y; mz[1][0] = vp10[0].z; mx[1][1] = vp11[0].x; my[1][1] = vp11[0].y; mz[1][1] = vp11[0].z; // Partial derivatives with respect to S direction // For Hermite contour mx[2][0] = (vp00[2].x); my[2][0] = (vp00[2].y); mz[2][0] = (vp00[2].z); mx[2][1] = -(vp01[1].x); my[2][1] = -(vp01[1].y); mz[2][1] = -(vp01[1].z); mx[3][0] = (vp10[1].x); my[3][0] = (vp10[1].y); mz[3][0] = (vp10[1].z); mx[3][1] = -(vp11[2].x); my[3][1] = -(vp11[2].y); mz[3][1] = -(vp11[2].z); // Partial derivatives with respect to T direction // For Hermite contour mx[0][2] = -(vp00[1].x); my[0][2] = -(vp00[1].y); mz[0][2] = -(vp00[1].z); mx[0][3] = -(vp01[2].x); my[0][3] = -(vp01[2].y); mz[0][3] = -(vp01[2].z); mx[1][2] = (vp10[2].x); my[1][2] = (vp10[2].y); mz[1][2] = (vp10[2].z); mx[1][3] = (vp11[1].x); my[1][3] = (vp11[1].y); mz[1][3] = (vp11[1].z); // Ferguson patch: twist vectors (second order partial derivatives) // are all 0, as noted on [FOLE1992].11.3.1, equation [FOLE1992].11.84 mx[2][2] = 0; my[2][2] = 0; mz[2][2] = 0; mx[2][3] = 0; my[2][3] = 0; mz[2][3] = 0; mx[3][2] = 0; my[3][2] = 0; mz[3][2] = 0; mx[3][3] = 0; my[3][3] = 0; mz[3][3] = 0; // Final result Gx_MATRIX.M = mx; Gy_MATRIX.M = my; Gz_MATRIX.M = mz; //printGeometryMatrices(); } /** This method evaluates current patch position in the parameter space position (s, t), computing the equation set 11.76 in [FOLE1992]. The following class attributes are used: <UL> <LI> S_MATRIX Column vector for storing s parameter polynomial as explain in section [FOLE1992].11.3 <LI> Tt_MATRIX Row vector for storing t parameter polynomial <LI> M_MATRIX Patch's blending function <LI> Mt_MATRIX M's transpose <LI> Gx_MATRIX Geometry matrix for x <LI> Gy_MATRIX Geometry matrix for y <LI> Gz_MATRIX Geometry matrix for z </UL> PRE: calculateMAtrices() should be called before calling this method. */ public void evaluate(Vector3D p, double s, double t) { S_MATRIX.M[0][0] = s * s * s; S_MATRIX.M[0][1] = s * s; S_MATRIX.M[0][2] = s; S_MATRIX.M[0][3] = 1; Tt_MATRIX.M[0][0] = t * t * t; Tt_MATRIX.M[1][0] = t * t; Tt_MATRIX.M[2][0] = t; Tt_MATRIX.M[3][0] = 1; Matrix4x4 S_M_Gx_Mt_MATRIX = S_MATRIX.multiply(M_Gx_Mt_MATRIX); Matrix4x4 S_M_Gy_Mt_MATRIX = S_MATRIX.multiply(M_Gy_Mt_MATRIX); Matrix4x4 S_M_Gz_Mt_MATRIX = S_MATRIX.multiply(M_Gz_Mt_MATRIX); Matrix4x4 Qx_MATRIX = S_M_Gx_Mt_MATRIX.multiply(Tt_MATRIX); Matrix4x4 Qy_MATRIX = S_M_Gy_Mt_MATRIX.multiply(Tt_MATRIX); Matrix4x4 Qz_MATRIX = S_M_Gz_Mt_MATRIX.multiply(Tt_MATRIX); // The result is a 1x1 matrix. p.x = Qx_MATRIX.M[0][0]; p.y = Qy_MATRIX.M[0][0]; p.z = Qz_MATRIX.M[0][0]; } public void evaluateTangent(Vector3D dQds, double s, double t) { S_MATRIX_DS.M[0][0] = 3 * s * s; S_MATRIX_DS.M[0][1] = 2 * s; S_MATRIX_DS.M[0][2] = 1; S_MATRIX_DS.M[0][3] = 0; Tt_MATRIX.M[0][0] = t * t * t; Tt_MATRIX.M[1][0] = t * t; Tt_MATRIX.M[2][0] = t; Tt_MATRIX.M[3][0] = 1; Matrix4x4 S_M_Gx_Mt_MATRIX = S_MATRIX_DS.multiply(M_Gx_Mt_MATRIX); Matrix4x4 S_M_Gy_Mt_MATRIX = S_MATRIX_DS.multiply(M_Gy_Mt_MATRIX); Matrix4x4 S_M_Gz_Mt_MATRIX = S_MATRIX_DS.multiply(M_Gz_Mt_MATRIX); Matrix4x4 Qx_MATRIX = S_M_Gx_Mt_MATRIX.multiply(Tt_MATRIX); Matrix4x4 Qy_MATRIX = S_M_Gy_Mt_MATRIX.multiply(Tt_MATRIX); Matrix4x4 Qz_MATRIX = S_M_Gz_Mt_MATRIX.multiply(Tt_MATRIX); // The result is a 1x1 matrix. Vector3D result = new Vector3D(); result.x = Qx_MATRIX.M[0][0]; result.y = Qy_MATRIX.M[0][0]; result.z = Qz_MATRIX.M[0][0]; result.normalize(); dQds.clone(result); } public void evaluateBinormal(Vector3D dQdt, double s, double t) { S_MATRIX.M[0][0] = s * s * s; S_MATRIX.M[0][1] = s * s; S_MATRIX.M[0][2] = s; S_MATRIX.M[0][3] = 1; Tt_MATRIX_DT.M[0][0] = 3 * t * t; Tt_MATRIX_DT.M[1][0] = 2 * t; Tt_MATRIX_DT.M[2][0] = 1; Tt_MATRIX_DT.M[3][0] = 0; Matrix4x4 S_M_Gx_Mt_MATRIX = S_MATRIX.multiply(M_Gx_Mt_MATRIX); Matrix4x4 S_M_Gy_Mt_MATRIX = S_MATRIX.multiply(M_Gy_Mt_MATRIX); Matrix4x4 S_M_Gz_Mt_MATRIX = S_MATRIX.multiply(M_Gz_Mt_MATRIX); Matrix4x4 Qx_MATRIX = S_M_Gx_Mt_MATRIX.multiply(Tt_MATRIX_DT); Matrix4x4 Qy_MATRIX = S_M_Gy_Mt_MATRIX.multiply(Tt_MATRIX_DT); Matrix4x4 Qz_MATRIX = S_M_Gz_Mt_MATRIX.multiply(Tt_MATRIX_DT); // The results are 1x1 matrices. Vector3D result = new Vector3D(); result.x = Qx_MATRIX.M[0][0]; result.y = Qy_MATRIX.M[0][0]; result.z = Qz_MATRIX.M[0][0]; result.normalize(); dQdt.clone(result); } /** This method evaluates current patch gradient in the parameter space position (s, t), computing the patch normal as explain in section [FOLE1992].11.3.4. The following class attributes are used: <UL> <LI> S_MATRIX Column vector for storing s parameter polynomial as explain in section [FOLE1992].11.3 <LI> Tt_MATRIX Row vector for storing t parameter polynomial <LI> M_MATRIX Patch's blending function <LI> Mt_MATRIX M's transpose <LI> Gx_MATRIX Geometry matrix for x <LI> Gy_MATRIX Geometry matrix for y <LI> Gz_MATRIX Geometry matrix for z </UL> PRE: calculateMAtrices() should be called before calling this method. */ public void evaluateNormal(Vector3D n, double s, double t) { Vector3D dQds = new Vector3D(); Vector3D dQdt = new Vector3D(); evaluateTangent(dQds, s, t); evaluateBinormal(dQdt, s, t); Vector3D nn = dQds.crossProduct(dQdt); nn.normalize(); n.clone(nn); } /** Check the general interface contract in superclass method Geometry.doIntersection. @todo implement the method */ public boolean doIntersection(Ray r) { return false; } /** Check the general interface contract in superclass method Geometry.doExtraInformation. Check the discusion in [WAYN1990] about solving this problem. Two main strategies are known for solving this: a numeric root finding (trying different values for Ray.t until a given error tolerance is reached) and converting the patch to a mesh and test the mesh. This method implements the numerical approach, while an explicit convertion to a Mesh could be managed by the user/programmer directly. WARNING: The numerical approach is really, really slow... @todo implement the method */ public void doExtraInformation(Ray inRay, double intT, GeometryIntersectionInformation outData) { return; } /** Returns an approximate bounding volume minmax for current patch, from the minmax of its contour curve. @bug current contour curve asumption is not valid */ public double[] getMinMax() { if ( contourCurve != null ) { return contourCurve.getMinMax(); } else { // This gives convex hull's minmax double minX = Double.MAX_VALUE; double minY = Double.MAX_VALUE; double minZ = Double.MAX_VALUE; double maxX = -Double.MAX_VALUE; double maxY = -Double.MAX_VALUE; double maxZ = -Double.MAX_VALUE; double minMax[] = new double[6]; int i, j; for ( i = 0; i < 4; i++ ) { for ( j = 0; j < 4; j++ ) { Vector3D p = controlMeshPoints[i][j]; if ( p.x < minX ) minX = p.x; if ( p.y < minY ) minY = p.y; if ( p.z < minZ ) minZ = p.z; if ( p.x > maxX ) maxX = p.x; if ( p.y > maxY ) maxY = p.y; if ( p.z > maxZ ) maxZ = p.z; } } minMax[0] = minX; minMax[1] = minY; minMax[2] = minZ; minMax[3] = maxX; minMax[4] = maxY; minMax[5] = maxZ; return minMax; } }}//===========================================================================//= EOF =//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -