⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transform3d.java

📁 JAVA3D矩陈的相关类
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
		} else {		    // Not even congruent, so isRigid must be false		    type &= ~RIGID;		}		dirtyBits &= ~RIGID_BIT;	    }	}	return ((type & RIGID) != 0);    }   /**     * Returns the least general type of this matrix; the order of     * generality from least to most is: ZERO, IDENTITY,     * SCALE/TRANSLATION, ORTHOGONAL, RIGID, CONGRUENT, AFFINE.     * If the matrix is ORTHOGONAL, calling the method     * getDeterminantSign() will yield more information.     * @return the least general matrix type     */    public final int getBestType() {	getType();   // force classify if necessary	if ((type & ZERO)                 != 0 ) return ZERO;	if ((type & IDENTITY)             != 0 ) return IDENTITY;	if ((type & SCALE)                != 0 ) return SCALE;	if ((type & TRANSLATION)          != 0 ) return TRANSLATION;	if ((type & ORTHOGONAL)           != 0 ) return ORTHOGONAL;	if ((type & RIGID)                != 0 ) return RIGID;	if ((type & CONGRUENT)            != 0 ) return CONGRUENT;	if ((type & AFFINE)               != 0 ) return AFFINE;	if ((type & NEGATIVE_DETERMINANT) != 0 ) return NEGATIVE_DETERMINANT;	return 0;    }    /*    private void print_type() {        if ((type & ZERO)                 > 0 ) System.err.print(" ZERO");	if ((type & IDENTITY)             > 0 ) System.err.print(" IDENTITY");	if ((type & SCALE)                > 0 ) System.err.print(" SCALE");	if ((type & TRANSLATION)          > 0 ) System.err.print(" TRANSLATION");	if ((type & ORTHOGONAL)           > 0 ) System.err.print(" ORTHOGONAL");	if ((type & RIGID)                > 0 ) System.err.print(" RIGID");	if ((type & CONGRUENT)            > 0 ) System.err.print(" CONGRUENT");	if ((type & AFFINE)               > 0 ) System.err.print(" AFFINE");	if ((type & NEGATIVE_DETERMINANT) > 0 ) System.err.print(" NEGATIVE_DETERMINANT");	}    */    /**     * Returns the sign of the determinant of this matrix; a return value     * of true indicates a non-negative determinant; a return value of false     * indicates a negative determinant. A value of true will be returned if     * the determinant is NaN. In general, an orthogonal matrix     * with a positive determinant is a pure rotation matrix; an orthogonal     * matrix with a negative determinant is a both a rotation and a     * reflection matrix.     * @return  determinant sign : true means non-negative, false means negative     */    public final boolean getDeterminantSign() {        double det = determinant();        if (Double.isNaN(det)) {            return true;        }        return det >= 0;    }    /**     * Sets a flag that enables or disables automatic SVD     * normalization.  If this flag is enabled, an automatic SVD     * normalization of the rotational components (upper 3x3) of this     * matrix is done after every subsequent matrix operation that     * modifies this matrix.  This is functionally equivalent to     * calling normalize() after every subsequent call, but may be     * less computationally expensive.     * The default value for this parameter is false.     * @param autoNormalize  the boolean state of auto normalization     */    public final void setAutoNormalize(boolean autoNormalize) {	this.autoNormalize = autoNormalize;	if (autoNormalize) {	    normalize();	}    }    /**     * Returns the state of auto-normalization.     * @return  boolean state of auto-normalization     */    public final boolean getAutoNormalize() {	return this.autoNormalize;    }    /**     * Transforms the point parameter with this transform and     * places the result into pointOut.  The fourth element of the     * point input paramter is assumed to be one.     * @param point  the input point to be transformed     * @param pointOut  the transformed point     */    void transform(Point3d point, Point4d pointOut) {                pointOut.x = mat[0]*point.x + mat[1]*point.y +                mat[2]*point.z + mat[3];        pointOut.y = mat[4]*point.x + mat[5]*point.y +                mat[6]*point.z + mat[7];        pointOut.z = mat[8]*point.x + mat[9]*point.y +                mat[10]*point.z + mat[11];        pointOut.w = mat[12]*point.x + mat[13]*point.y +                mat[14]*point.z + mat[15];    }               private static final boolean almostZero(double a) {	return ((a < EPSILON_ABSOLUTE) && (a > -EPSILON_ABSOLUTE));    }    private static final boolean almostOne(double a) {	return ((a < 1+EPSILON_ABSOLUTE) && (a > 1-EPSILON_ABSOLUTE));    }    private static final boolean almostEqual(double a, double b) {	double diff = a-b;	if (diff >= 0) {	    if (diff < EPSILON) {		return true;	    }	    // a > b	    if ((b > 0) || (a > -b)) {		return (diff < EPSILON_RELATIVE*a);	    } else {		return (diff < -EPSILON_RELATIVE*b);	    }	} else {	    if (diff > -EPSILON) {		return true;	    }	    // a < b	    if ((b < 0) || (-a > b)) {		return (diff > EPSILON_RELATIVE*a);	    } else {		return (diff > -EPSILON_RELATIVE*b);	    }	}    }    private final void classifyAffine() {        if (!isInfOrNaN() &&                almostZero(mat[12]) &&                almostZero(mat[13]) &&                almostZero(mat[14]) &&                almostOne(mat[15])) {	    type |= AFFINE;	} else {	    type &= ~AFFINE;	}	dirtyBits &= ~AFFINE_BIT;    }    // same amount of work to classify rigid and congruent    private final void classifyRigid() {	if ((dirtyBits & AFFINE_BIT) != 0) {	    // should not touch ORTHO bit	    type &= ORTHO;	    classifyAffine();	} else {	    // keep the affine bit if there is one	    // and clear the others (CONGRUENT/RIGID) bit	    type &= (ORTHO | AFFINE);	}	if ((type & AFFINE) != 0) {	    // checking orthogonal condition	    if (isOrtho()) {		if ((dirtyBits & SCALE_BIT) != 0) {		    double s0 = mat[0]*mat[0] + mat[4]*mat[4] +			mat[8]*mat[8];		    double s1 = mat[1]*mat[1] + mat[5]*mat[5] +			mat[9]*mat[9];		    if (almostEqual(s0, s1)) {			double s2 = mat[2]*mat[2] + mat[6]*mat[6] +			    mat[10]*mat[10];			if (almostEqual(s2, s0)) {			    type |= CONGRUENT;			    // Note that scales[0] = sqrt(s0);			    if (almostOne(s0)) {				type |= RIGID;			    }			}		    }		} else {		    if(scales == null)			scales = new double[3];		    double s = scales[0];		    if (almostEqual(s, scales[1]) &&			almostEqual(s, scales[2])) {			type |= CONGRUENT;			if (almostOne(s)) {			    type |= RIGID;			}		    }		}	    }	}	dirtyBits &= (~RIGID_BIT | ~CONGRUENT_BIT);    }    /**     * Classifies a matrix.     */    private final void classify() {	if ((dirtyBits & (RIGID_BIT|AFFINE_BIT|CONGRUENT_BIT)) != 0) {	    // Test for RIGID, CONGRUENT, AFFINE.	    classifyRigid();	}	// Test for ZERO, IDENTITY, SCALE, TRANSLATION,	// ORTHOGONAL, NEGATIVE_DETERMINANT	if ((type & AFFINE) != 0) {	    if ((type & CONGRUENT) != 0) {		if ((type & RIGID) != 0) {		    if (zeroTranslation()) {			type |= ORTHOGONAL;			if (rotateZero()) {			    // mat[0], mat[5], mat[10] can be only be			    // 1 or -1 when reach here			    if ((mat[0] > 0) &&				(mat[5] > 0) &&				(mat[10] > 0)) {				type |= IDENTITY|SCALE|TRANSLATION;			    }			}		    } else {			if (rotateZero()) {			    type |= TRANSLATION;			}		    }		} else {		    // uniform scale		    if (zeroTranslation() && rotateZero()) {			type |= SCALE;		    }		}	    }	} else {	    // last row is not (0, 0, 0, 1)	    if (almostZero(mat[12]) &&		almostZero(mat[13]) &&		almostZero(mat[14]) &&		almostZero(mat[15]) &&		zeroTranslation() &&		rotateZero() &&		almostZero(mat[0]) &&		almostZero(mat[5]) &&		almostZero(mat[10])) {		type |= ZERO;	    }	}	if (!getDeterminantSign()) {	    type |= NEGATIVE_DETERMINANT;	}	dirtyBits &= ~CLASSIFY_BIT;    }    final boolean zeroTranslation() {	return (almostZero(mat[3]) &&		almostZero(mat[7]) &&		almostZero(mat[11]));    }    final boolean rotateZero() {	return (almostZero(mat[1]) && almostZero(mat[2]) &&		almostZero(mat[4]) && almostZero(mat[6]) &&		almostZero(mat[8]) && almostZero(mat[9]));    }   /**     * Returns the matrix elements of this transform as a string.     * @return  the matrix elements of this transform     */    public String toString() {	// also, print classification?	return	    mat[0] + ", " + mat[1] + ", " + mat[2] + ", " + mat[3] + "\n" +	    mat[4] + ", " + mat[5] + ", " + mat[6] + ", " + mat[7] + "\n" +	    mat[8] + ", " + mat[9] + ", " + mat[10] + ", " + mat[11] + "\n" +	    mat[12] + ", " + mat[13] + ", " + mat[14] + ", " + mat[15]	    + "\n";    }    /**     * Sets this transform to the identity matrix.     */    public final void setIdentity() {	mat[0] = 1.0;  mat[1] = 0.0;  mat[2] = 0.0;  mat[3] = 0.0;	mat[4] = 0.0;  mat[5] = 1.0;  mat[6] = 0.0;  mat[7] = 0.0;	mat[8] = 0.0;  mat[9] = 0.0;  mat[10] = 1.0; mat[11] = 0.0;	mat[12] = 0.0; mat[13] = 0.0; mat[14] = 0.0; mat[15] = 1.0;	type = IDENTITY | SCALE |  ORTHOGONAL | RIGID | CONGRUENT |	       AFFINE | TRANSLATION | ORTHO;	dirtyBits = SCALE_BIT | ROTATION_BIT;	// No need to set SVD_BIT    }   /**     * Sets this transform to all zeros.     */    public final void setZero() {	mat[0] = 0.0;  mat[1] = 0.0;  mat[2] = 0.0;  mat[3] = 0.0;	mat[4] = 0.0;  mat[5] = 0.0;  mat[6] = 0.0;  mat[7] = 0.0;	mat[8] = 0.0;  mat[9] = 0.0;  mat[10] = 0.0; mat[11] = 0.0;	mat[12] = 0.0; mat[13] = 0.0; mat[14] = 0.0; mat[15] = 0.0;	type = ZERO | ORTHO;	dirtyBits = SCALE_BIT | ROTATION_BIT;    }   /**     * Adds this transform to transform t1 and places the result into     * this: this = this + t1.     * @param t1  the transform to be added to this transform     */    public final void add(Transform3D t1) {	for (int i=0 ; i<16 ; i++) {	    mat[i] += t1.mat[i];	}	dirtyBits = ALL_DIRTY;	if (autoNormalize) {	    normalize();	}    }    /**     * Adds transforms t1 and t2 and places the result into this transform.     * @param t1  the transform to be added     * @param t2  the transform to be added     */    public final void add(Transform3D t1, Transform3D t2) {	for (int i=0 ; i<16 ; i++) {	    mat[i] = t1.mat[i] + t2.mat[i];	}	dirtyBits = ALL_DIRTY;	if (autoNormalize) {	    normalize();	}    }    /**     * Subtracts transform t1 from this transform and places the result     * into this: this = this - t1.     * @param t1  the transform to be subtracted from this transform     */    public final void sub(Transform3D t1) {	for (int i=0 ; i<16 ; i++) {	    mat[i] -= t1.mat[i];	}	dirtyBits = ALL_DIRTY;	if (autoNormalize) {	    normalize();	}    }    /**     * Subtracts transform t2 from transform t1 and places the result into     * this: this = t1 - t2.     * @param t1   the left transform     * @param t2   the right transform     */    public final void sub(Transform3D t1, Transform3D t2) {	for (int i=0 ; i<16 ; i++) {	    mat[i] = t1.mat[i] - t2.mat[i];	}	dirtyBits = ALL_DIRTY;	if (autoNormalize) {	    normalize();	}    }   /**     * Transposes this matrix in place.     */    public final void transpose() {        double temp;        temp = mat[4];        mat[4] = mat[1];        mat[1] = temp;        temp = mat[8];        mat[8] = mat[2];        mat[2] = temp;        temp = mat[12];        mat[12] = mat[3];        mat[3] = temp;        temp = mat[9];        mat[9] = mat[6];        mat[6] = temp;        temp = mat[13];        mat[13] = mat[7];        mat[7] = temp;        temp = mat[14];        mat[14] = mat[11];        mat[11] = temp;	dirtyBits = ALL_DIRTY;	if (autoNormalize) {	    normalize();	}    }    /**     * Transposes transform t1 and places the value into this transform.     * The transform t1 is not modified.     * @param t1  the transform whose transpose is placed into this transform     */    public final void transpose(Transform3D t1) {       if (this != t1) {           mat[0] =  t1.mat[0];           mat[1] =  t1.mat[4];           mat[2] =  t1.mat[8];           mat[3] =  t1.mat[12];           mat[4] =  t1.mat[1];           mat[5] =  t1.mat[5];           mat[6] =  t1.mat[9];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -