/*
Copyright 2006 by Sean Luke and George Mason University
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.app.mav;
import sim.portrayal.*;
import java.awt.geom.*;
import java.awt.*;
import java.io.*;
import java.awt.font.*;
public /*strictfp*/ class Region extends SimplePortrayal2D
{
private static final long serialVersionUID = 1;
// we hard-code the available shapes here. The reason for this is simple: shapes
// and areas aren't serializable. ARGH. So we can't save out a shape/area and
// load it back in again. Instead we have to save out a shape "number", and then
// load that number back in again. Suboptimal.
static final Shape[] shapes = new Shape[]
{
new Ellipse2D.Double(0,0,100,100),
AffineTransform.getRotateInstance(35*/*Strict*/Math.PI/180).createTransformedShape(
new RoundRectangle2D.Double(0,0,100,100,15,15)),
new Font("Serif", 0, 128).createGlyphVector(new FontRenderContext(
new AffineTransform(),false,true),"MAV").getOutline()
};
// the location of the object's origin.
public double originx;
public double originy;
int shapeNum;
static final Color[] surfacecolors = new Color[] {Color.white, Color.blue, Color.green, Color.red};
public Shape shape;
public Area area;
public int surface;
public Region (int num, int s,
double x,
double y) { shapeNum = num;
shape = shapes[shapeNum]; surface = s;
area = new Area(shape); originx = x; originy = y; }
// rule 1: don't fool around with graphics' own transforms because they effect its clip, ARGH.
// so we have to create our own transformed shape. To be more efficient, we only transform
// it if it's moved around.
Shape oldShape;
Rectangle2D.Double oldDraw = null;
public void draw(Object object, Graphics2D graphics, DrawInfo2D info)
{
if (oldDraw == null ||
oldDraw.x != info.draw.x ||
oldDraw.y != info.draw.y ||
oldDraw.width != info.draw.width ||
oldDraw.height != info.draw.height) // new location or scale, must create
{
oldDraw = info.draw;
AffineTransform transform = new AffineTransform();
transform.translate(oldDraw.x, oldDraw.y);
transform.scale(oldDraw.width, oldDraw.height);
oldShape = transform.createTransformedShape(shape);
}
// okay, now draw the shape, it's properly transformed
graphics.setColor(surfacecolors[surface]);
graphics.fill(oldShape);
}
/** If drawing area intersects selected area, add to the bag */
public boolean hitObject(Object object, DrawInfo2D range)
{
AffineTransform transform = new AffineTransform();
transform.translate(range.draw.x, range.draw.y);
transform.scale(range.draw.width, range.draw.height);
Shape s = transform.createTransformedShape(shape);
return (s.intersects(range.clip.x, range.clip.y, range.clip.width, range.clip.height));
}
// because we're using Areas, and for some bizarre reason Area isn't serializable,
// if WE want to be serializable or externalizable we need to handle our own read
// and write methods.
private void writeObject(java.io.ObjectOutputStream p)
throws IOException
{
p.writeDouble(originx);
p.writeDouble(originy);
p.writeInt(shapeNum);
p.writeInt(surface);
}
private void readObject(java.io.ObjectInputStream p)
throws IOException, ClassNotFoundException
{
originx = p.readDouble();
originy = p.readDouble();
shapeNum = p.readInt();
surface = p.readInt();
// reload shapes and areas, which aren't serializable (ugh)
shape = (Shape)(shapes[shapeNum]);
area = new Area(shape);
}
}