|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--edu.umd.cs.jazz.ZSceneGraphObject | +--edu.umd.cs.jazz.ZNode | +--edu.umd.cs.jazz.ZGroup | +--edu.umd.cs.jazz.ZTransformGroup
ZTransformGroup is a group node that specifies an arbitrary affine transform. The transform applies to all the children of this node. In addition, it provides some extra manipulators on the transform. This provides the ability to relatively or absolutely change the translation, scale, rotation and shear of the transform - either immediately, or animated over time.
In order to use transforms effectively, it is important to have a solid understanding
of affine transforms, matrix multiplication, and the standard use of matrices for
graphics coordinate systems. The best place to start is by reading the documentation
on AffineTransform
. After that, a good next bit is to read
a standard 3D graphics text such as "Interactive Computer Graphics: a Top-Down Approach
with OpenGL" 2nd Edition by Angel (Addison-Wesley), or "Computer Graphics: Principles
and Practice, Second Edition in C" by Foley, van Dam, Feiner, Hughes, and Phillips
(Addison-Wesley).
Here is a very short lesson on matrices and graphics. A 2D affine transform is typically represented by a 3x3 matrix which we typically call M, and sometimes denote [M]. An affine transform can represent any 2D translation, scale, rotation, shear or any combination of these 4 operators. Matrices which are pure translations, scales, and rotations are typically denoted T, S, or R ([T], [S], or [R]), respectively. The identity matrix is typically denoted I or [I].
The reason these transforms are so powerful is because they can be combined in a semantically straightforward way by simply concatenating the matrices. Creating a transform results in I. Calling one of the transformation methods on a transform is exactly equivalent to concatenating the transform with a new transform that specifies the transformation. Thus, transform.translate(dx, dy) is equivalent to [M][T] where M represents the original transform, and T represents the translation matrix of dx, dy. Similarly, transform.scale(ds) is equivalent to [M][S]. And, these build up, so
ZTransformGroup t = new ZTransformGroup(); t.scale(ds); t.translate(dx, dy); t.rotate(Math.PI * 0.5);is equivalent to generating a node with transform of these four matrices concatenated together with standard matrix multiplication [I][S][T][R]
However, a crucial place for confusion with these transforms is that the transforms get applied in the reverse order of how you placed the calls to the transforms in your code. To understand this, you must realize that the object paint methods get called after the transformations are applied. Your paint methods specify geometry (such as points) which get transformed by the current transformation before being painted. For a simple example, think of a point P. Well, the point post-multiplies the current transformation. In the example above, that works out to a new point P' being computed as P' = [S][T][R]P. You can think about this as the original point P first getting multiplied (on the left) by R, then the result gets multipled (on the left) by T, and that gets multiplied (on the left) by S.
Let's go through a simple example with actual numbers. Suppose you want to take a rectangle at (0, 0) with width 50 and height 50, and first translate it 50 units to the right, and then scale the whole thing by 2 about the origin. The result should be that the rectangle actually gets rendered at (100, 0) with dimensions of (100x100). The following code in Jazz implements this example.
ZRectangle rect = new ZRectangle(0, 0, 50, 50); ZVisualLeaf leaf = new ZVisualLeaf(rect); ZTransformGroup node = new ZTransformGroup(); node.addChild(leaf); layer.addChild(node); // Note how we call scale first even though // the translation will actually be applied before the scale. node.scale(2); node.translate(50, 0);
Sometimes it is useful to transform an object in global coordinates - even though that object has a transform of its own. For instance, suppose you are implementing an event handler for selection, and want to move an object so that it follows the pointer. In order to do this, you need to translate the object in global coordinates. Since the node you want to move may have a transform already (for instance, it may be scaled), if you simply translate the object, that transform will be applied after the scale, and thus the translation will be modified by the scale. That is, the object may have the matrix [M]. Calling translate will generate [M][T]. If M represents a scale of 2, then the translation will actually translate twice as much as you intended.
The solution is to convert your translation into the local coordinate system of the object. Since there this node is actually part of a tree, there coul be other transforms as well, not to mention the camera transform. So, the goal is to take the amount you want to translate the object in the original coordinate system (in this case the window coords), and convert it into the object's local coordinate system. We do this by building up the concatenation of all the transforms from the window to the node, taking the inverse of that matrix, and finally transform the translation by the resulting inverse matrix. Jazz provides a utility method to make this easier. So, the resulting code would look like this. It takes a desired translation in window coordinates, and uses the utility method ZCamera.cameraToLocal to convert it to the local coordinate system of the specified node, and finally translates the node by the resulting amount.
Point2D pt = new Point2D.Double(x, y); camera.cameraToLocal(pt, node); node.translate(pt.getX(), pt.getY());
ZSceneGraphEditor
provides a convenience mechanism to locate, create
and manage nodes of this type.
Warning: Serialized and ZSerialized objects of this class will not be compatible with future Jazz releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Jazz. A future release of Jazz will provide support for long term persistence.
AffineTransform
, Serialized FormFields inherited from class edu.umd.cs.jazz.ZGroup |
children, childrenFindable_DEFAULT, childrenPickable_DEFAULT, hasOneChild_DEFAULT |
Fields inherited from class edu.umd.cs.jazz.ZNode |
findable_DEFAULT, pickable_DEFAULT, savable_DEFAULT, selectable_DEFAULT |
Fields inherited from class edu.umd.cs.jazz.ZSceneGraphObject |
bounds, listenerList, volatileBounds, volatileBounds_DEFAULT |
Constructor Summary | |
ZTransformGroup()
Constructs an empty ZTransformGroup. |
|
ZTransformGroup(ZNode child)
Constructs a new transform group node with the specified node as a child of the new group. |
Method Summary | |
void |
addTransformListener(ZTransformListener l)
Adds the specified transform listener to receive transform events from this node |
static void |
animate(ZTransformable[] nodes,
java.awt.geom.AffineTransform[] txs,
int millis,
ZDrawingSurface surface)
Set the transforms of the specified array of nodes to the specified array of transforms, and animate the change over the specified number of milliseconds using a slow-in slow-out animation. |
static void |
animate(ZTransformable[] nodes,
java.awt.geom.AffineTransform[] txs,
int millis,
ZDrawingSurface surface,
ZLerp lerpTimeFunction)
Set the transforms of the specified array of nodes to the specified array of transforms, and animate the change over the specified number of milliseconds using a slow-in slow-out animation. |
static void |
animate(ZTransformable node,
java.awt.geom.AffineTransform tx,
int millis,
ZDrawingSurface surface)
Set the transform of the specified node to the specified transform, and animate the change from its current transformation over the specified number of milliseconds using a slow-in slow-out animation. |
static void |
animate(ZTransformable node,
java.awt.geom.AffineTransform at,
int millis,
ZDrawingSurface surface,
ZLerp lerpTimeFunction)
Set the transform of the specified node to the specified transform, and animate the change from its current transformation over the specified number of milliseconds using a slow-in slow-out animation. |
protected void |
computeBounds()
Recomputes and caches the bounds for this node. |
protected void |
computeInverseTransform()
Internal method to compute the inverse transform based on the transform. |
static double |
computeScale(java.awt.geom.AffineTransform at)
Given an AffineTransform, this returns the "scale" of the transform. |
void |
concatenate(java.awt.geom.AffineTransform at)
Concatenates an AffineTransform at to this node's transform in
the standard way. |
java.lang.String |
dump()
Generate a string that represents this object for debugging. |
protected java.lang.Object |
duplicateObject()
Returns a clone of this object. |
java.awt.geom.AffineTransform |
getInverseTransform()
Returns the inverse of the transform associated with this node. |
java.awt.geom.AffineTransform |
getLocalToGlobalTransform()
Return the transform that converts local coordinates at this node to global coordinates at the root node. |
void |
getMatrix(double[] flatmatrix)
Retrieves the 6 specifiable values in the affine transformation, and places them into an array of double precisions values. |
double |
getRotation()
Returns the current rotation of this node |
double |
getScale()
Returns the current scale of this transform. |
java.awt.geom.AffineTransform |
getTransform()
Returns a copy of the transform that that this node specifies. |
java.awt.geom.AffineTransform |
getTransformReference()
Returns a reference to the transform that that this node specifies. |
double |
getTranslateX()
Returns the current X translation of this node |
double |
getTranslateY()
Returns the current Y translation of this node |
java.awt.geom.Point2D |
getTranslation()
Returns the current translation of this node |
static double |
lerp(double t,
double a,
double b)
Linearly interpolates between a and b, based on t. |
boolean |
pick(java.awt.geom.Rectangle2D rect,
ZSceneGraphPath path)
Returns the first object under the specified rectangle (if there is one) in the subtree rooted with this as searched in reverse (front-to-back) order. |
void |
position(java.awt.geom.Point2D srcPt,
java.awt.geom.Point2D destPt,
java.awt.geom.Rectangle2D destBounds,
int millis,
ZDrawingSurface surface)
This will calculate the necessary transform in order to make this node appear at a particular position relative to the specified bounding box. |
void |
position(java.awt.geom.Point2D srcPt,
java.awt.geom.Point2D destPt,
ZNode refNode,
int millis,
ZDrawingSurface surface)
This will calculate the necessary transform in order to make this node appear at a particular position relative to the specified node. |
void |
preConcatenate(java.awt.geom.AffineTransform at)
Pre-Concatenates an AffineTransform at to this node's transform in a less commonly
used way such that at gets pre-multipled with the existing transform rather
than the more normal post-multiplication. |
void |
removeTransformListener(ZTransformListener l)
Removes the specified transform listener so that it no longer receives transform events from this transform. |
void |
render(ZRenderContext renderContext)
Renders this node which results in its children getting painted. |
void |
repaint(ZBounds repaintBounds)
Method to pass repaint methods up the tree. |
void |
repaint(ZSceneGraphObject obj,
java.awt.geom.AffineTransform at,
ZBounds clipBounds)
Method to pass repaint methods up the tree. |
void |
rotate(double theta)
Rotate the node by the specified amount |
void |
rotate(double theta,
double xctr,
double yctr)
Rotate the node by the specified amount around the specified anchor point |
void |
rotate(double theta,
double xctr,
double yctr,
int millis,
ZDrawingSurface surface)
Rotate the node, via animation, theta radians about the specified anchor point |
void |
rotate(double theta,
int millis,
ZDrawingSurface surface)
Rotate the node, via animation, theta radians |
void |
scale(double dz)
Scale the node from its current scale to the scale specified by muliplying the current scale and dz. |
void |
scale(double dz,
double x,
double y)
Scale the node around the specified point (x, y) from its current scale to the scale specified by muliplying the current scale and dz. |
void |
scale(double dz,
double x,
double y,
int millis,
ZDrawingSurface surface)
Animate the node around the specified point (x, y) from its current scale to the scale specified by muliplying the current scale and dz |
void |
scale(double dz,
int millis,
ZDrawingSurface surface)
Animate the node from its current scale to the scale specified by muliplying the current scale and deltaZ |
void |
setRotation(double theta)
Set the absolute rotation of this node. |
void |
setRotation(double theta,
double xctr,
double yctr)
Set the absolute rotation of this node, rotating around the specified anchor point. |
void |
setRotation(double theta,
double xctr,
double yctr,
int millis,
ZDrawingSurface surface)
Set the absolute rotation of this node, via animation, theta radians about the specified anchor point. |
void |
setRotation(double theta,
int millis,
ZDrawingSurface surface)
Set the absolute rotation of this node, animating the change over time. |
void |
setScale(double finalz)
Sets the scale of the transform |
void |
setScale(double finalz,
double x,
double y)
Set the scale of the node to the specified target scale, scaling the node around the specified point (x, y). |
void |
setScale(double finalz,
double x,
double y,
int millis,
ZDrawingSurface surface)
Animate the node around the specified point (x, y) to the specified target scale. |
void |
setScale(double finalz,
int millis,
ZDrawingSurface surface)
Animate the node from its current scale to the specified target scale. |
void |
setState(java.lang.String fieldType,
java.lang.String fieldName,
java.lang.Object fieldValue)
Set some state of this object as it gets read back in. |
void |
setTransform(java.awt.geom.AffineTransform newTransform)
Sets the transform associated with this node. |
void |
setTransform(double m00,
double m10,
double m01,
double m11,
double m02,
double m12)
Sets the transform associated with this node. |
void |
setTranslateX(double x)
Sets the current X translation of this node |
void |
setTranslateY(double y)
Sets the current Y translation of this node |
void |
setTranslation(double x,
double y)
Translate the node to the specified position |
void |
setTranslation(double x,
double y,
int millis,
ZDrawingSurface surface)
Animate the node from its current position to the position specified by x, y |
static void |
transform(java.awt.geom.Rectangle2D rect,
java.awt.geom.AffineTransform at)
Apply the specified transform to the specified rectangle, modifying the rect. |
static void |
transform(ZBounds bounds,
java.awt.geom.AffineTransform at)
Apply the specified transform to the specified bounds, modifying the bounds. |
void |
translate(double dx,
double dy)
Translate the node by the specified deltaX and deltaY |
void |
translate(double dx,
double dy,
int millis,
ZDrawingSurface surface)
Animate the node from its current position by the specified deltaX and deltaY |
void |
writeObject(ZObjectOutputStream out)
Write out all of this object's state. |
void |
writeObjectRecurse(ZObjectOutputStream out)
Specify which objects this object references in order to write out the scenegraph properly |
Methods inherited from class edu.umd.cs.jazz.ZNode |
addClientProperty, addNodeListener, editor, getClientProperty, getGlobalBounds, getGlobalToLocalTransform, getParent, getRoot, globalToLocal, globalToLocal, hasNodeListener, isAncestorOf, isDescendentOf, isFindable, isPickable, isSavable, isSelectable, localToGlobal, localToGlobal, lower, lowerTo, percolateEventUpSceneGraph, putClientProperty, raise, raiseTo, remove, repaint, reparent, replaceWith, setEditorFactory, setFindable, setParent, setPickable, setSavable, setSelectable, updateBounds, updateObjectReferences, writeReplace |
Methods inherited from class edu.umd.cs.jazz.ZSceneGraphObject |
addMouseListener, addMouseMotionListener, clone, fireEvent, fireMouseEvent, getBounds, getBoundsReference, getListenerList, hasLisenerOfType, hasMouseListener, processMouseEvent, removeEventListener, removeMouseListener, removeMouseMotionListener, reshape, setBounds, setVolatileBounds |
Methods inherited from class java.lang.Object |
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
public ZTransformGroup()
public ZTransformGroup(ZNode child)
child
- Child of the new group node.Method Detail |
protected java.lang.Object duplicateObject()
duplicateObject
in class ZGroup
ZSceneGraphObject.duplicateObject()
public void render(ZRenderContext renderContext)
The transform, clip, and composite will be set appropriately when this object is rendered. It is up to this object to restore the transform, clip, and composite of the Graphics2D if this node changes any of them. However, the color, font, and stroke are unspecified by Jazz. This object should set those things if they are used, but they do not need to be restored.
This transform node applies its transform before painting its children.
render
in class ZGroup
renderContext
- The graphics context to use for rendering.protected void computeBounds()
computeBounds
in class ZGroup
public void repaint(ZBounds repaintBounds)
repaint
in class ZNode
repaintBounds
- The bounds to repaintpublic void repaint(ZSceneGraphObject obj, java.awt.geom.AffineTransform at, ZBounds clipBounds)
repaint
in class ZNode
obj
- The object to repaintat
- The affine transformclipBounds
- The bounds to clip to when repaintingpublic boolean pick(java.awt.geom.Rectangle2D rect, ZSceneGraphPath path)
pick
in class ZGroup
rect
- Coordinates of pick rectangle in local coordinatespath
- The path through the scenegraph to the picked node. Modified by this call.ZDrawingSurface.pick(int, int)
public void addTransformListener(ZTransformListener l)
l
- the transform listenerpublic void removeTransformListener(ZTransformListener l)
l
- the transform listenerpublic java.awt.geom.AffineTransform getTransform()
public java.awt.geom.AffineTransform getTransformReference()
public void getMatrix(double[] flatmatrix)
getMatrix
in interface ZTransformable
flatmatrix
- the double array used to store the returned
values.public void setTransform(java.awt.geom.AffineTransform newTransform)
newTransform
- public void setTransform(double m00, double m10, double m01, double m11, double m02, double m12)
setTransform
in interface ZTransformable
m00, m01, m02, m10, m11, m12
- the
6 values that compose the 3x3 transformation matrixpublic void concatenate(java.awt.geom.AffineTransform at)
at
to this node's transform in
the standard way. This has the affect of applying at
in this
node's local coordinate system.at
- The transform to concatenatepreConcatenate(java.awt.geom.AffineTransform)
public void preConcatenate(java.awt.geom.AffineTransform at)
at
to this node's transform in a less commonly
used way such that at
gets pre-multipled with the existing transform rather
than the more normal post-multiplication. This has the affect of applying the transform at
in the coordinate system above this node, rather than within the local coordinate system
of this node.at
- The transform to pre-concatenateconcatenate(java.awt.geom.AffineTransform)
public java.awt.geom.AffineTransform getLocalToGlobalTransform()
getLocalToGlobalTransform
in class ZNode
protected void computeInverseTransform()
public java.awt.geom.AffineTransform getInverseTransform()
public java.awt.geom.Point2D getTranslation()
public double getTranslateX()
public void setTranslateX(double x)
public double getTranslateY()
public void setTranslateY(double y)
public void translate(double dx, double dy)
dx
- X-coord of translationdy
- Y-coord of translationpublic void translate(double dx, double dy, int millis, ZDrawingSurface surface)
dx
- X-coord of translationdy
- Y-coord of translationmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public void setTranslation(double x, double y)
x
- X-coord of translationy
- Y-coord of translationpublic void setTranslation(double x, double y, int millis, ZDrawingSurface surface)
x
- X-coord of translationy
- Y-coord of translationmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public double getScale()
public void scale(double dz)
dz
- scale factorpublic void scale(double dz, double x, double y)
dz
- scale factorx
- X coordinate of the point to scale aroundy
- Y coordinate of the point to scale aroundpublic void scale(double dz, int millis, ZDrawingSurface surface)
dz
- scale factormillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public void scale(double dz, double x, double y, int millis, ZDrawingSurface surface)
dz
- scale factorx
- X coordinate of the point to scale aroundy
- Y coordinate of the point to scale aroundmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public void setScale(double finalz)
the
- new scalepublic void setScale(double finalz, double x, double y)
finalz
- scale factorx
- X coordinate of the point to scale aroundy
- Y coordinate of the point to scale aroundpublic void setScale(double finalz, int millis, ZDrawingSurface surface)
finalz
- scale factormillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public void setScale(double finalz, double x, double y, int millis, ZDrawingSurface surface)
finalz
- scale factorx
- X coordinate of the point to scale aroundy
- Y coordinate of the point to scale aroundmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public double getRotation()
public void setRotation(double theta)
theta
- angle to rotate (in radians)public void setRotation(double theta, int millis, ZDrawingSurface surface)
theta
- angle to rotate (in radians)millis
- Time to animate scale in millisecondssurface
- The surface to updated during animation.public void setRotation(double theta, double xctr, double yctr)
theta
- angle to rotate (in radians)xctr
- X-coord of anchor pointyctr
- Y-coord of anchor pointpublic void setRotation(double theta, double xctr, double yctr, int millis, ZDrawingSurface surface)
theta
- angle to rotate (in radians)xctr
- X-coord of anchor pointyctr
- Y-coord of anchor pointmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public void rotate(double theta)
theta
- angle to rotate (in radians)public void rotate(double theta, double xctr, double yctr)
theta
- angle to rotate (in radians)xctr
- X-coord of anchor pointyctr
- Y-coord of anchor pointpublic void rotate(double theta, int millis, ZDrawingSurface surface)
theta
- angle to rotate (in radians)millis
- Time to animate scale in millisecondssurface
- The surface to updated during animation.public void rotate(double theta, double xctr, double yctr, int millis, ZDrawingSurface surface)
theta
- angle to rotate (in radians)xctr
- X-coord of anchor pointyctr
- Y-coord of anchor pointmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public void position(java.awt.geom.Point2D srcPt, java.awt.geom.Point2D destPt, ZNode refNode, int millis, ZDrawingSurface surface)
For example, If you have two nodes, A and B, and you call
Point2D srcPt = new Point2D.Double(1.0, 0.0); Point2D destPt = new Point2D.Double(0.0, 0.0); A.position(srcPt, destPt, B, 750, null);The result is that A will move so that its upper-right corner is at the same place as the upper-left corner of B, and the transition will be smoothly animated over a period of 750 milliseconds.
srcPt
- The anchor point on this transform's node (normalized to a unit square)destPt
- The anchor point on destination bounds (normalized to a unit square)destBounds
- The bounds used to calculate this transform's nodemillis
- Number of milliseconds over which to perform the animationsurface
- The surface to be updated during animation.public void position(java.awt.geom.Point2D srcPt, java.awt.geom.Point2D destPt, java.awt.geom.Rectangle2D destBounds, int millis, ZDrawingSurface surface)
For example, If you have two nodes, A and B, and you call
Point2D srcPt = new Point2D.Double(1.0, 0.0); Point2D destPt = new Point2D.Double(0.0, 0.0); A.position(srcPt, destPt, B.getGlobalBounds(), 750, null);The result is that A will move so that its upper-right corner is at the same place as the upper-left corner of B, and the transition will be smoothly animated over a period of 750 milliseconds.
srcPt
- The anchor point on this transform's node (normalized to a unit square)destPt
- The anchor point on destination bounds (normalized to a unit square)destBounds
- The bounds (in global coordinates) used to calculate this transform's nodemillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public static double computeScale(java.awt.geom.AffineTransform at)
public static double lerp(double t, double a, double b)
a
- from pointb
- to Pointt
- variable 'time' parameterpublic static void transform(ZBounds bounds, java.awt.geom.AffineTransform at)
bounds
- The bounds to be transformedat
- The transform to use to transform the rectanglepublic static void transform(java.awt.geom.Rectangle2D rect, java.awt.geom.AffineTransform at)
rect
- The rectangle to be transformedat
- The transform to use to transform the rectanglepublic static void animate(ZTransformable node, java.awt.geom.AffineTransform tx, int millis, ZDrawingSurface surface)
If millis is 0, then the transform is updated once, and the scene is not repainted immediately, but rather a repaint request is queued, and will be processed by an event handler.
node
- The node to be animatedtx
- Final transformationmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public static void animate(ZTransformable node, java.awt.geom.AffineTransform at, int millis, ZDrawingSurface surface, ZLerp lerpTimeFunction)
If millis is 0, then the transform is updated once, and the scene is not repainted immediately, but rather a repaint request is queued, and will be processed by an event handler.
The timing of the animation is controlled by the lerpTimeFunction. This is used to specify the rate the animation occurs over time. If this parameter is specified as null, then a standard linear interpolation is used, and the animation goes at a constant speed from beginning to end. The caller can specify alternate functions, however, which can do things like perform a slow-in, slow-out animation.
node
- The node to be animatedat
- Final transformationmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.lerpTimeFunction
- The function that determines how the timing of the animation should be calculatedpublic static void animate(ZTransformable[] nodes, java.awt.geom.AffineTransform[] txs, int millis, ZDrawingSurface surface)
If the size of the nodes and txs arrays are not equal, then only those nodes for which transforms are specified will be animated. That is, the smaller of the two array sizes will be used.
If millis is 0, then the transform is updated once, and the scene is not repainted immediately, but rather a repaint request is queued, and will be processed by an event handler.
The following code fragment demonstrates the use of this animate method. It creates three rectangles, and animates two of them simultaneously.
ZRectangle rect1, rect2, rect3; ZVisualLeaf leaf1, leaf2, leaf3; ZTransformable node1, node2, node3; rect1 = new ZRectangle(0, 0, 50, 50); rect1.setFillColor(Color.red); leaf1 = new ZVisualLeaf(rect1); node1 = new ZTransformable(); node1.addChild(leaf1); layer.addChild(node1); rect2 = new ZRectangle(25, 25, 50, 50); rect2.setFillColor(Color.blue); leaf2 = new ZVisualLeaf(rect2); node2 = new ZNode(); node2.addChild(leaf2); layer.addChild(node2); rect3 = new ZRectangle(100, 100, 50, 50); rect3.setFillColor(Color.orange); leaf3 = new ZVisualLeaf(rect3); node3 = new ZNode(rect3); node3.addChild(leaf3); layer.addChild(node3); ZTransformable[] nodes = new ZTransformable[2]; nodes[0] = node1; nodes[1] = node2; AffineTransform[] txs = new AffineTransform[2]; txs[0] = new AffineTransform(); txs[0].scale(2.0, 2.0); txs[1] = new AffineTransform(); txs[1].translate(100.0, 25.0); txs[1].scale(0.5, 0.5); ZTransform.animate(nodes, txs, 1000, surface);
nodes
- The array of nodes to be animatedtxs
- The array of final transformations of the nodesmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.public static void animate(ZTransformable[] nodes, java.awt.geom.AffineTransform[] txs, int millis, ZDrawingSurface surface, ZLerp lerpTimeFunction)
If the size of the nodes and txs arrays are not equal, then only those nodes for which transforms are specified will be animated. That is, the smaller of the two array sizes will be used.
If millis is 0, then the transform is updated once, and the scene is not repainted immediately, but rather a repaint request is queued, and will be processed by an event handler.
The timing of the animation is controlled by the lerpTimeFunction. This is used to specify the rate the animation occurs over time. If this parameter is specified as null, then a standard linear interpolation is used, and the animation goes at a constant speed from beginning to end. The caller can specify alternate functions, however, which can do things like perform a slow-in, slow-out animation.
The following code fragment demonstrates the use of this animate method. It creates three rectangles, and animates two of them simultaneously.
ZRectangle rect1, rect2, rect3; ZVisualLeaf leaf1, leaf2, leaf3; ZTransformable node1, node2, node3; rect1 = new ZRectangle(0, 0, 50, 50); rect1.setFillColor(Color.red); leaf1 = new ZVisualLeaf(rect1); node1 = new ZTransformable(); node1.addChild(leaf1); layer.addChild(node1); rect2 = new ZRectangle(25, 25, 50, 50); rect2.setFillColor(Color.blue); leaf2 = new ZVisualLeaf(rect2); node2 = new ZNode(); node2.addChild(leaf2); layer.addChild(node2); rect3 = new ZRectangle(100, 100, 50, 50); rect3.setFillColor(Color.orange); leaf3 = new ZVisualLeaf(rect3); node3 = new ZNode(rect3); node3.addChild(leaf3); layer.addChild(node3); ZTransformable[] nodes = new ZTransformable[2]; nodes[0] = node1; nodes[1] = node2; AffineTransform[] txs = new AffineTransform[2]; txs[0] = new AffineTransform(); txs[0].scale(2.0, 2.0); txs[1] = new AffineTransform(); txs[1].translate(100.0, 25.0); txs[1].scale(0.5, 0.5); ZTransform.animate(nodes, txs, 1000, surface);
nodes
- The array of nodes to be animatedtxs
- The array of final transformations of the nodesmillis
- Number of milliseconds over which to perform the animationsurface
- The surface to updated during animation.lerpTimeFunction
- The function that determines how the timing of the animation should be calculatedpublic java.lang.String dump()
dump
in class ZGroup
ZDebug.dump(edu.umd.cs.jazz.ZNode)
public void writeObject(ZObjectOutputStream out) throws java.io.IOException
writeObject
in interface ZSerializable
writeObject
in class ZGroup
out
- The stream that this object writes intopublic void writeObjectRecurse(ZObjectOutputStream out) throws java.io.IOException
writeObjectRecurse
in interface ZSerializable
writeObjectRecurse
in class ZGroup
out
- The stream that this object writes intopublic void setState(java.lang.String fieldType, java.lang.String fieldName, java.lang.Object fieldValue)
setState
in interface ZSerializable
setState
in class ZGroup
fieldType
- The fully qualified type of the fieldfieldName
- The name of the fieldfieldValue
- The value of the field
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |