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

📄 affinetransform.java

📁 Hecl编程语言是一个高层次的脚本语言的Java实现。其用意是要小
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     * different depending on whether the SHEAR flag is also set.     * <pre>     *                     SCALE            SHEAR          TRANSLATE     *                    m00/m11          m01/m10          m02/m12     *     * IDENTITY             1.0              0.0              0.0     * TRANSLATE (TR)       1.0              0.0          not both 0.0     * SCALE (SC)       not both 1.0         0.0              0.0     * TR | SC          not both 1.0         0.0          not both 0.0     * SHEAR (SH)           0.0          not both 0.0         0.0     * TR | SH              0.0          not both 0.0     not both 0.0     * SC | SH          not both 0.0     not both 0.0         0.0     * TR | SC | SH     not both 0.0     not both 0.0     not both 0.0     * </pre>     */    void updateState() {	if (m01 == 0.0 && m10 == 0.0) {	    if (m00 == 1.0 && m11 == 1.0) {		if (m02 == 0.0 && m12 == 0.0) {		    state = APPLY_IDENTITY;		    type = TYPE_IDENTITY;		} else {		    state = APPLY_TRANSLATE;		    type = TYPE_TRANSLATION;		}	    } else {		if (m02 == 0.0 && m12 == 0.0) {		    state = APPLY_SCALE;		    type = TYPE_UNKNOWN;		} else {		    state = (APPLY_SCALE | APPLY_TRANSLATE);		    type = TYPE_UNKNOWN;		}	    }	} else {	    if (m00 == 0.0 && m11 == 0.0) {		if (m02 == 0.0 && m12 == 0.0) {		    state = APPLY_SHEAR;		    type = TYPE_UNKNOWN;		} else {		    state = (APPLY_SHEAR | APPLY_TRANSLATE);		    type = TYPE_UNKNOWN;		}	    } else {		if (m02 == 0.0 && m12 == 0.0) {		    state = (APPLY_SHEAR | APPLY_SCALE);		    type = TYPE_UNKNOWN;		} else {		    state = (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE);		    type = TYPE_UNKNOWN;		}	    }	}    }    /*     * Convenience method used internally to throw exceptions when     * a case was forgotten in a switch statement.     */    private void stateError() {//#ifdef notdef	throw new InternalError("missing case in transform state switch");//#else	System.out.println("missing case in transform state switch");//#endif    }        /**     * Retrieves the 6 specifiable values in the 3x3 affine transformation     * matrix and places them into an array of double precisions values.     * The values are stored in the array as      * {&nbsp;m00&nbsp;m10&nbsp;m01&nbsp;m11&nbsp;m02&nbsp;m12&nbsp;}.     * An array of 4 doubles can also be specified, in which case only the     * first four elements representing the non-transform     * parts of the array are retrieved and the values are stored into      * the array as {&nbsp;m00&nbsp;m10&nbsp;m01&nbsp;m11&nbsp;}     * @param flatmatrix the double array used to store the returned     * values.     * @see #getScaleX     * @see #getScaleY     * @see #getShearX     * @see #getShearY     * @see #getTranslateX     * @see #getTranslateY     */    public void getMatrix(double[] flatmatrix) {	flatmatrix[0] = m00;	flatmatrix[1] = m10;	flatmatrix[2] = m01;	flatmatrix[3] = m11;	if (flatmatrix.length > 5) {	    flatmatrix[4] = m02;	    flatmatrix[5] = m12;	}    }    /**     * Returns the X coordinate scaling element (m00) of the 3x3     * affine transformation matrix.     * @return a double value that is the X coordinate of the scaling     *  element of the affine transformation matrix.     * @see #getMatrix     */    public double getScaleX() {	return m00;    }    /**     * Returns the Y coordinate scaling element (m11) of the 3x3     * affine transformation matrix.     * @return a double value that is the Y coordinate of the scaling     *  element of the affine transformation matrix.     * @see #getMatrix     */    public double getScaleY() {	return m11;    }    /**     * Returns the X coordinate shearing element (m01) of the 3x3     * affine transformation matrix.     * @return a double value that is the X coordinate of the shearing     *  element of the affine transformation matrix.     * @see #getMatrix     */    public double getShearX() {	return m01;    }    /**     * Returns the Y coordinate shearing element (m10) of the 3x3     * affine transformation matrix.     * @return a double value that is the Y coordinate of the shearing     *  element of the affine transformation matrix.     * @see #getMatrix     */    public double getShearY() {	return m10;    }    /**     * Returns the X coordinate of the translation element (m02) of the     * 3x3 affine transformation matrix.     * @return a double value that is the X coordinate of the translation     *  element of the affine transformation matrix.     * @see #getMatrix     */    public double getTranslateX() {	return m02;    }    /**     * Returns the Y coordinate of the translation element (m12) of the     * 3x3 affine transformation matrix.     * @return a double value that is the Y coordinate of the translation     *  element of the affine transformation matrix.      * @see #getMatrix     */    public double getTranslateY() {	return m12;    }    /**     * Concatenates this transform with a translation transformation.     * This is equivalent to calling concatenate(T), where T is an     * <code>AffineTransform</code> represented by the following matrix:     * <pre>     *		[   1    0    tx  ]     *		[   0    1    ty  ]     *		[   0    0    1   ]     * </pre>     * @param tx the distance by which coordinates are translated in the     * X axis direction     * @param ty the distance by which coordinates are translated in the     * Y axis direction     */    public void translate(double tx, double ty) {	switch (state) {	  default:	    stateError();	    break;	    /* NOTREACHED */	  case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):	    m02 = tx * m00 + ty * m01 + m02;	    m12 = tx * m10 + ty * m11 + m12;	    if (m02 == 0.0 && m12 == 0.0) {		state = APPLY_SHEAR | APPLY_SCALE;		if (type != TYPE_UNKNOWN) {		    type -= TYPE_TRANSLATION;		}	    }	    return;	  case (APPLY_SHEAR | APPLY_SCALE):	    m02 = tx * m00 + ty * m01;	    m12 = tx * m10 + ty * m11;	    if (m02 != 0.0 || m12 != 0.0) {		state = APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE;		type |= TYPE_TRANSLATION;	    }	    return;	  case (APPLY_SHEAR | APPLY_TRANSLATE):	    m02 = ty * m01 + m02;	    m12 = tx * m10 + m12;	    if (m02 == 0.0 && m12 == 0.0) {		state = APPLY_SHEAR;		if (type != TYPE_UNKNOWN) {		    type -= TYPE_TRANSLATION;		}	    }	    return;	  case (APPLY_SHEAR):	    m02 = ty * m01;	    m12 = tx * m10;	    if (m02 != 0.0 || m12 != 0.0) {		state = APPLY_SHEAR | APPLY_TRANSLATE;		type |= TYPE_TRANSLATION;	    }	    return;	  case (APPLY_SCALE | APPLY_TRANSLATE):	    m02 = tx * m00 + m02;	    m12 = ty * m11 + m12;	    if (m02 == 0.0 && m12 == 0.0) {		state = APPLY_SCALE;		if (type != TYPE_UNKNOWN) {		    type -= TYPE_TRANSLATION;		}	    }	    return;	  case (APPLY_SCALE):	    m02 = tx * m00;	    m12 = ty * m11;	    if (m02 != 0.0 || m12 != 0.0) {		state = APPLY_SCALE | APPLY_TRANSLATE;		type |= TYPE_TRANSLATION;	    }	    return;	  case (APPLY_TRANSLATE):	    m02 = tx + m02;	    m12 = ty + m12;	    if (m02 == 0.0 && m12 == 0.0) {		state = APPLY_IDENTITY;		type = TYPE_IDENTITY;	    }	    return;	  case (APPLY_IDENTITY):	    m02 = tx;	    m12 = ty;	    if (tx != 0.0 || ty != 0.0) {		state = APPLY_TRANSLATE;		type = TYPE_TRANSLATION;	    }	    return;	}    }    /**     * Concatenates this transform with a rotation transformation.     * This is equivalent to calling concatenate(R), where R is an     * <code>AffineTransform</code> represented by the following matrix:     * <pre>     *		[   cos(theta)    -sin(theta)    0   ]     *		[   sin(theta)     cos(theta)    0   ]     *		[       0              0         1   ]     * </pre>     * Rotating with a positive angle theta rotates points on the positive     * x axis toward the positive y axis.     * @param theta the angle of rotation in radians     */    public void rotate(double theta) {	double sin = Math.sin(theta);	double cos = Math.cos(theta);	if (Math.abs(sin) < 1E-15) {	    if (cos < 0.0) {		m00 = -m00;		m11 = -m11;		int state = this.state;		if ((state & (APPLY_SHEAR)) != 0) {		    // If there was a shear, then this rotation has no		    // effect on the state.		    m01 = -m01;		    m10 = -m10;		} else {		    // No shear means the SCALE state may toggle when		    // m00 and m11 are negated.		    if (m00 == 1.0 && m11 == 1.0) {			this.state = state & ~APPLY_SCALE;		    } else {			this.state = state | APPLY_SCALE;		    }		}		type = TYPE_UNKNOWN;	    }	    return;	}	if (Math.abs(cos) < 1E-15) {	    if (sin < 0.0) {		double M0 = m00;		m00 = -m01;		m01 = M0;		M0 = m10;		m10 = -m11;		m11 = M0;	    } else {		double M0 = m00;		m00 = m01;		m01 = -M0;		M0 = m10;		m10 = m11;		m11 = -M0;	    }	    int state = rot90conversion[this.state];	    if ((state & (APPLY_SHEAR | APPLY_SCALE)) == APPLY_SCALE &&		m00 == 1.0 && m11 == 1.0)	    {		state -= APPLY_SCALE;	    }	    this.state = state;	    type = TYPE_UNKNOWN;	    return;	}	double M0, M1;	M0 = m00;	M1 = m01;	m00 =  cos * M0 + sin * M1;	m01 = -sin * M0 + cos * M1;	M0 = m10;	M1 = m11;	m10 =  cos * M0 + sin * M1;	m11 = -sin * M0 + cos * M1;	updateState();    }    private static int rot90conversion[] = {	APPLY_SHEAR, APPLY_SHEAR | APPLY_TRANSLATE,	APPLY_SHEAR, APPLY_SHEAR | APPLY_TRANSLATE,	APPLY_SCALE, APPLY_SCALE | APPLY_TRANSLATE,	APPLY_SHEAR | APPLY_SCALE,	APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE,    };    /**     * Concatenates this transform with a transform that rotates     * coordinates around an anchor point.     * This operation is equivalent to translating the coordinates so     * that the anchor point is at the origin (S1), then rotating them     * about the new origin (S2), and finally translating so that the     * intermediate origin is restored to the coordinates of the original     * anchor point (S3).     * <p>     * This operation is equivalent to the following sequence of calls:     * <pre>     *		translate(x, y);	// S3: final translation     *		rotate(theta);		// S2: rotate around anchor     *		translate(-x, -y);	// S1: translate anchor to origin     * </pre>     * Rotating with a positive angle theta rotates points on the positive     * x axis toward the positive y axis.     * @param theta the angle of rotation in radians     * @param x,&nbsp;y the coordinates of the anchor point of the     * rotation     */    public void rotate(double theta, double x, double y) {	// REMIND: Simple for now - optimize later	translate(x, y);	rotate(theta);	translate(-x, -y);    }    /**     * Concatenates this transform with a scaling transformation.     * This is equivalent to calling concatenate(S), where S is an     * <code>AffineTransform</code> represented by the following matrix:     * <pre>     *		[   sx   0    0   ]     *		[   0    sy   0   ]     *		[   0    0    1   ]     * </pre>     * @param sx the factor by which coordinates are scaled along the        * X axis direction     * @param sy the factor by which coordinates are scaled along the     * Y axis direction     */    public void scale(double sx, double sy) {	int state = this.state;	switch (state) {	default:	    stateError();	    break;	    /* NOTREACHED */	case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE):	case (APPLY_SHEAR | APPLY_SCALE):	    m00 *= sx;	    m11 *= sy;	    /* NOBREAK */	case (APPLY_SHEAR | APPLY_TRANSLATE):	case (APPLY_SHEAR):	    m01 *= sy;	    m10 *= sx;	    if (m01 == 0 && m10 == 0) {		this.state = state - APPLY_SHEAR;		// REMIND: Is it possible for m00 and m11 to be both 1.0?	    }	    this.type = TYPE_UNKNOWN;	    return;	case (APPLY_SCALE | APPLY_TRANSLATE):	case (APPLY_SCALE):	    m00 *= sx;	    m11 *= sy;	    if (m00 == 1.0 && m11 == 1.0) {		this.state = (state &= APPLY_TRANSLATE);		this.type = (state == APPLY_IDENTITY			     ? TYPE_IDENTITY			     : TYPE_TRANSLATION);	    } else {		this.type = TYPE_UNKNOWN;	    }	    return;	case (APPLY_TRANSLATE):	case (APPLY_IDENTITY):

⌨️ 快捷键说明

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