org.eclipse.swt.graphics.Transform Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package org.eclipse.swt.graphics;
import java.util.Arrays;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
/**
* Instances of this class represent transformation matrices for
* points expressed as (x, y) pairs of floating point numbers.
*
* Application code must explicitly invoke the Transform.dispose()
* method to release the operating system resources managed by each instance
* when those instances are no longer required.
*
*
* @since 3.1
*/
public class Transform extends Resource {
private final static float[] IDENTITY_MATRIX = { 1, 0, 0, 1, 0, 0 };
private float[] elements;
/**
* Constructs a new identity Transform.
*
* This operation requires the operating system's advanced
* graphics subsystem which may not be available on some
* platforms.
*
*
* @param device the device on which to allocate the Transform
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if device is null and there is no current device
*
*
* @see #dispose()
*/
public Transform( Device device ) {
this( device, IDENTITY_MATRIX );
}
/**
* Constructs a new Transform given an array of elements that represent the matrix that describes
* the transformation.
*
* This operation requires the operating system's advanced graphics subsystem which may not be
* available on some platforms.
*
*
* @param device the device on which to allocate the Transform
* @param elements an array of floats that describe the transformation matrix
* @exception IllegalArgumentException
*
* - ERROR_NULL_ARGUMENT - if device is null and there is no current device, or the
* elements array is null
* - ERROR_INVALID_ARGUMENT - if the elements array is too small to hold the matrix
* values
*
* @see #dispose()
*/
public Transform( Device device, float[] elements ) {
this( device,
checkTransform( elements )[ 0 ],
elements[ 1 ],
elements[ 2 ],
elements[ 3 ],
elements[ 4 ],
elements[ 5 ] );
}
/**
* Constructs a new Transform given all of the elements that represent the matrix that describes
* the transformation.
*
* This operation requires the operating system's advanced graphics subsystem which may not be
* available on some platforms.
*
*
* @param device the device on which to allocate the Transform
* @param m11 the first element of the first row of the matrix
* @param m12 the second element of the first row of the matrix
* @param m21 the first element of the second row of the matrix
* @param m22 the second element of the second row of the matrix
* @param dx the third element of the first row of the matrix
* @param dy the third element of the second row of the matrix
* @exception IllegalArgumentException
*
* - ERROR_NULL_ARGUMENT - if device is null and there is no current device
*
* @see #dispose()
*/
public Transform( Device device,
float m11,
float m12,
float m21,
float m22,
float dx,
float dy )
{
super( device );
elements = new float[] { m11, m12, m21, m22, dx, dy };
}
static float[] checkTransform( float[] elements ) {
if( elements == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
if( elements.length < 6 ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
return elements;
}
@Override
void destroy() {
elements = null;
}
/**
* Fills the parameter with the values of the transformation matrix that the receiver represents,
* in the order {m11, m12, m21, m22, dx, dy}.
*
* @param elements array to hold the matrix values
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
* @exception IllegalArgumentException
*
* - ERROR_NULL_ARGUMENT - if the parameter is null
* - ERROR_INVALID_ARGUMENT - if the parameter is too small to hold the matrix
* values
*
*/
public void getElements( float[] elements ) {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
if( elements == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
if( elements.length < 6 ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
System.arraycopy( this.elements, 0, elements, 0, 6 );
}
/**
* Modifies the receiver to represent a new transformation given all of the elements that
* represent the matrix that describes that transformation.
*
* @param m11 the first element of the first row of the matrix
* @param m12 the second element of the first row of the matrix
* @param m21 the first element of the second row of the matrix
* @param m22 the second element of the second row of the matrix
* @param dx the third element of the first row of the matrix
* @param dy the third element of the second row of the matrix
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
*/
public void setElements( float m11, float m12, float m21, float m22, float dx, float dy ) {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
elements = new float[] { m11, m12, m21, m22, dx, dy };
}
/**
* Modifies the receiver such that the matrix it represents becomes the identity matrix.
*
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
*/
public void identity() {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
System.arraycopy( IDENTITY_MATRIX, 0, elements, 0, 6 );
}
/**
* Returns true
if the Transform represents the identity matrix and false otherwise.
*
* @return true
if the receiver is an identity Transform, and false
* otherwise
*/
public boolean isIdentity() {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
return Arrays.equals( elements, IDENTITY_MATRIX );
}
/**
* Modifies the receiver such that the matrix it represents becomes the mathematical inverse of
* the matrix it previously represented.
*
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
* - ERROR_CANNOT_INVERT_MATRIX - if the matrix is not invertible
*
*/
public void invert() {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
float d = elements[ 0 ] * elements[ 3 ] - elements[ 1 ] * elements[ 2 ];
elements = new float[] {
elements[ 3 ] / d,
-elements[ 1 ] / d,
-elements[ 2 ] / d,
elements[ 0 ] / d,
( elements[ 2 ] * elements[ 5 ] - elements[ 4 ] * elements[ 3 ] ) / d,
( elements[ 4 ] * elements[ 1 ] - elements[ 5 ] * elements[ 0 ] ) / d
};
}
/**
* Modifies the receiver such that the matrix it represents becomes the the result of multiplying
* the matrix it previously represented by the argument.
*
* @param matrix the matrix to multiply the receiver by
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
* @exception IllegalArgumentException
*
* - ERROR_NULL_ARGUMENT - if the parameter is null
* - ERROR_INVALID_ARGUMENT - if the parameter has been disposed
*
*/
public void multiply( Transform matrix ) {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
if( matrix == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
if( matrix.isDisposed() ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
float[] elements = new float[ 6 ];
matrix.getElements( elements );
multiply( elements[ 0 ],
elements[ 1 ],
elements[ 2 ],
elements[ 3 ],
elements[ 4 ],
elements[ 5 ] );
}
/**
* Modifies the receiver so that it represents a transformation that is equivalent to its previous
* transformation translated by (offsetX, offsetY).
*
* @param offsetX the distance to translate in the X direction
* @param offsetY the distance to translate in the Y direction
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
*/
public void translate( float offsetX, float offsetY ) {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
multiply( 1, 0, 0, 1, offsetX, offsetY );
}
/**
* Modifies the receiver so that it represents a transformation that is equivalent to its previous
* transformation scaled by (scaleX, scaleY).
*
* @param scaleX the amount to scale in the X direction
* @param scaleY the amount to scale in the Y direction
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
*/
public void scale( float scaleX, float scaleY ) {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
multiply( scaleX, 0, 0, scaleY, 0, 0 );
}
/**
* Modifies the receiver so that it represents a transformation that is equivalent to its previous
* transformation rotated by the specified angle. The angle is specified in degrees and for the
* identity transform 0 degrees is at the 3 o'clock position. A positive value indicates a
* clockwise rotation while a negative value indicates a counter-clockwise rotation.
*
* @param angle the angle to rotate the transformation by
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
*/
public void rotate( float angle ) {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
double radians = Math.toRadians( angle );
float m11 = ( float )Math.cos( radians );
float m12 = ( float )Math.sin( radians );
float m21 = -( float )Math.sin( radians );
float m22 = ( float )Math.cos( radians );
multiply( m11, m12, m21, m22, 0, 0 );
}
/**
* Modifies the receiver so that it represents a transformation that is equivalent to its previous
* transformation sheared by (shearX, shearY).
*
* @param shearX the shear factor in the X direction
* @param shearY the shear factor in the Y direction
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
*/
public void shear( float shearX, float shearY ) {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
multiply( 1, shearY, shearX, 1, 0, 0 );
}
/**
* Given an array containing points described by alternating x and y values, modify that array
* such that each point has been replaced with the result of applying the transformation
* represented by the receiver to that point.
*
* @param pointArray an array of alternating x and y values to be transformed
* @exception IllegalArgumentException
*
* - ERROR_NULL_ARGUMENT - if the point array is null
*
* @exception SWTException
*
* - ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed
*
*/
public void transform( float[] pointArray ) {
if( isDisposed() ) {
SWT.error( SWT.ERROR_GRAPHIC_DISPOSED );
}
if( pointArray == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
for( int i = 1; i < pointArray.length; i += 2 ) {
float dx = pointArray[ i - 1 ];
float dy = pointArray[ i ];
pointArray[ i - 1 ] = elements[ 0 ] * dx + elements[ 2 ] * dy + elements[ 4 ];
pointArray[ i ] = elements[ 1 ] * dx + elements[ 3 ] * dy + elements[ 5 ];
}
}
/**
* Returns a string containing a concise, human-readable description of the receiver.
*
* @return a string representation of the receiver
*/
@Override
public String toString() {
if( isDisposed() ) {
return "Transform {*DISPOSED*}";
}
return "Transform {"
+ elements[ 0 ]
+ ","
+ elements[ 1 ]
+ ","
+ elements[ 2 ]
+ ","
+ elements[ 3 ]
+ ","
+ elements[ 4 ]
+ ","
+ elements[ 5 ]
+ "}";
}
private void multiply( float m11, float m12, float m21, float m22, float dx, float dy ) {
elements = new float[] {
elements[ 0 ] * m11 + elements[ 2 ] * m12,
elements[ 1 ] * m11 + elements[ 3 ] * m12,
elements[ 0 ] * m21 + elements[ 2 ] * m22,
elements[ 1 ] * m21 + elements[ 3 ] * m22,
elements[ 0 ] * dx + elements[ 2 ] * dy + elements[ 4 ],
elements[ 1 ] * dx + elements[ 3 ] * dy + elements[ 5 ]
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy