import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
public class View extends JFrame implements ActionListener, ChangeListener {
private double frameWidth = 900; // Start value*/
private double frameHeight = 700;
private double street[][] = { { 0, 640 }, { 900, 640 }, { 0, 690 },
{ 900, 690 } };
private double house[][] = { { 700, 400 }, { 830, 400 }, { 830, 400 },
{ 830, 280 }, { 830, 280 }, { 700, 280 }, { 700, 280 },
{ 700, 400 }, { 700, 280 }, { 775, 175 }, { 775, 175 },
{ 830, 280 }, { 770, 400 }, { 770, 340 }, { 770, 340 },
{ 810, 340 }, { 810, 340 }, { 810, 400 }/* Door */, { 720, 330 },
{ 750, 330 }, { 750, 330 }, { 750, 300 }, { 750, 300 },
{ 720, 300 }, { 720, 300 }, { 720, 330 }, { 765, 335 } /*
* control
* point-center
*/};
/*
* private double stickMan[][] = {{500,600},{525,550}, {525,550},{550,600},
* {525,550},{525,500}, {525,525},{500,500}, {525,525},{550,500},
* {525,540}/*control center point}; wieder auskommentieren
*/
private double stickMan[][] = { { 600, 400 }, { 625, 350 }, { 625, 350 },
{ 650, 400 }, { 625, 350 }, { 625, 300 }, { 625, 325 },
{ 600, 300 }, { 625, 325 }, { 650, 300 }, { 625, 340 } /*
* control
* center
* point
*/};
private double lorry[][] = { { 50, 650 }, { 250, 650 }, { 250, 650 },
{ 250, 620 }, { 250, 620 }, { 230, 620 }, { 230, 620 },
{ 230, 525 }, { 230, 525 }, { 170, 525 }, { 170, 525 },
{ 170, 600 }, { 170, 600 }, { 50, 600 }, { 50, 600 }, { 50, 650 },
{ 210, 565 }, { 180, 565 }, { 180, 565 }, { 180, 535 },
{ 180, 535 }, { 210, 535 }, { 210, 535 }, { 210, 565 },
{ 90, 650 }, { 180, 650 } }; // center points for 2 wheels
private double bezierPointsCloud1[][] = { { 100, 150 }, { 80, 130 },
{ 80, 110 }, { 100, 90 }, { 100, 90 }, { 120, 70 }, { 140, 70 },
{ 160, 100 }, { 160, 100 }, { 180, 50 }, { 200, 50 }, { 220, 100 },
{ 220, 100 }, { 240, 70 }, { 260, 70 }, { 280, 90 }, { 280, 90 },
{ 300, 110 }, { 300, 130 }, { 280, 150 } };
// Wolkengröße 2.Wolke ändern
private double bezierPointsCloud2[][] = { { 400, 250 }, { 380, 230 },
{ 380, 210 }, { 400, 190 }, { 400, 190 }, { 420, 170 },
{ 440, 170 }, { 460, 200 }, { 460, 200 }, { 480, 150 },
{ 500, 150 }, { 520, 200 }, { 520, 200 }, { 540, 170 },
{ 560, 170 }, { 580, 190 }, { 580, 190 }, { 600, 210 },
{ 600, 230 }, { 580, 250 } };
private double bezierPointsHorizon[][] = { { 0, 300 }, { 75, 250 },
{ 150, 270 }, { 225, 350 }, { 225, 350 }, { 400, 200 },
{ 550, 220 }, { 650, 330 }, { 650, 330 }, { 750, 280 },
{ 825, 300 }, { getFrameWidth(), 350 } /* {900,350} */};
// private double bezierPointsTree[][] = {};
private double windMillSails[][] = { { 150, 200 }, { 100, 200 },
{ 100, 200 }, { 100, 150 }, { 100, 150 }, { 150, 200 },
{ 150, 200 }, { 150, 150 }, { 150, 150 }, { 200, 150 },
{ 200, 150 }, { 150, 200 }, { 150, 200 }, { 200, 200 },
{ 200, 200 }, { 200, 250 }, { 200, 250 }, { 150, 200 },
{ 150, 200 }, { 150, 250 }, { 150, 250 }, { 100, 250 },
{ 100, 250 }, { 150, 200 }, { 150, 200 } /* center point */};
private double windMillFoot[][] = { { 150, 200 }, { 100, 400 },
{ 150, 200 }, { 200, 400 } };
private double fillHouse[][];// = {{650,350},{850,350},
// {650,351},{850,351}};
private double newFillHouse[][];
// absolute Notlösung wegen Feldunwissen
private double stickManCircleX = 510; // ruhig Startwerte hier ablegen..
private double stickManCircleY = 170; // Werte nur zum Test passen auf
// Stickman
private double stickManCircleRadius = 30; // same for paramemter 3 & 4 =>
// circle, no oval shape
private double oldHouseCenterX;
private double oldHouseCenterY;
private double oldStickManCenterX;
private double oldStickManCenterY;
private double oldLorryCenterX;
private double oldLorryCenterY;
private double lorryCircle1X = 80;
private double lorryCircle1Y = 630;
private double lorryCircle1Radius = 40;
private double lorryCircle2X = 170;
private double lorryCircle2Y = 630;
private double lorryCircle2Radius = 40;
boolean additionalTranslationFlag = false;
private Graphics offScreenGraphics; // for DoubleBuffering
private Image offScreenImage; // for DoubleBuffering
private Timer timerHouse; // get und set fehlen
private Timer timerStickMan; // get und set fehlen
private Timer timerLorry; // get und set fehlen
private Timer timerClouds; // get und set fehlen
private Timer timerWindMillSails; // get und set fehlen
private Timer timerPaintingHouse; // get und set fehlen
boolean timerFlag = true; // get und set
double shearingValue = 0.075;
double oldWindSpeed = 0;
boolean cloudSwitch = false;
private double counter = 0; // TEST LÖSCHEN ??
public final static double PI = 3.1415926535897932384626433832795;
// -----------------------------------------------------------------------------
// below this line variables for/from the Remote Control
private int object; // 1-House, 2-Lorry, 3-Stickman, 4-Tree, 5-Clouds
private int modification; // 1-Translate, 2-Scale, 3-Rotate, 4-Speed
private JSlider scaling2Slider;
private JFrame colorFrame;
private Color paint = new Color(255, 255, 255); // white !?
private JColorChooser chooseColor;
private int translationXValue;
private int translationYValue;
private double scaling1Value;
private double scaling2Value;
private double speedValue; // vorläufig
private double windSpeed;// = 10; //nur zum Test
private double lorrySpeed;// = 10;
private double[][] translationObject;
private double[][] speedObject;
private boolean paintHouse = false;
private boolean showStickMan = true; // TEST true ist ok
// private Color paintingColor = new Color(0,0,0); // black
private Color houseColor = new Color(255, 0, 0); // red
/** Main method creates a new View object and starts the timers */
public static void main( String args[] ) {
// View view = new View();
View rc = new View("Remote Control");
// view.startTimer();
}
/** Default-constructor creates a new Frame */
public View() {
super("Assignment World - Björn Nellinger");
setBackground(Color.white);
addWindowListener(new WindowAdapter() {
public void windowClosing( WindowEvent e ) {
System.exit(0);
}
});
setSize(new Dimension(900, 700));
setResizable(true); // ändern, wenn bekannt wie man nahc
// Fensterveränderung repaint aufrufen kann
setVisible(true);
startTimer();
}
public View( String name ) {
this();
JFrame rcFrame = new JFrame(name);
rcFrame.addWindowListener(new WindowAdapter() {
public void windowClosing( WindowEvent e ) {
System.exit(0);
}
});
// -----------TRANSLATION-------------------------------
JPanel translationPanel = new JPanel();
JButton translationButton = new JButton("Apply Translation");
translationButton.addActionListener(this);
JRadioButton translationRadioButtonStickman = new JRadioButton(
"Stickman");
JRadioButton translationRadioButtonLorry = new JRadioButton("Lorry");
ButtonGroup translationBG = new ButtonGroup();
translationBG.add(translationRadioButtonStickman);
translationBG.add(translationRadioButtonLorry);
translationRadioButtonStickman.addActionListener(this);
translationRadioButtonLorry.addActionListener(this);
translationRadioButtonLorry.setName("LorryTranslation");
JSlider translationSliderX = new JSlider(-300, 300, 0); // Min, Max,
// Value
translationSliderX.setName("TranslationX");
translationSliderX.setMinorTickSpacing(50);
translationSliderX.setMajorTickSpacing(100);
translationSliderX.setPaintTicks(true);
translationSliderX.setPaintLabels(true);
translationSliderX.addChangeListener(this);
JSlider translationSliderY = new JSlider(1, -300, 300, 0); // Orientation,
// Min, Max,
// Value
translationSliderY.setName("TranslationY");
translationSliderY.setMinorTickSpacing(50);
translationSliderY.setMajorTickSpacing(100);
translationSliderY.setPaintTicks(true);
translationSliderY.setPaintLabels(true);
translationSliderY.addChangeListener(this);
translationPanel.add(translationButton);
translationPanel.add(translationRadioButtonStickman);
translationPanel.add(translationRadioButtonLorry);
translationPanel.add(translationSliderY);
translationPanel.add(translationSliderX);
translationPanel.setToolTipText("Translation Panel");
// ------------------------------------------------------
// -----------SCALING----------------------------------------
JPanel scalingPanel = new JPanel();
JButton scalingButton = new JButton("Apply House Scaling");
scalingButton.addActionListener(this);
JSlider scaling1Slider = new JSlider(0, 200, 100); // Min, Max, Value
// in %
scaling1Slider.setName("Scaling1");
scaling1Slider.setMinorTickSpacing(50); // only for INT
scaling1Slider.setMajorTickSpacing(100);
scaling1Slider.setPaintTicks(true);
scaling1Slider.setPaintLabels(true);
scaling1Slider.addChangeListener(this);
scaling2Slider = new JSlider(0, 200, 100); // Min, Max, Value in %
scaling2Slider.setName("Scaling2");
scaling2Slider.setMinorTickSpacing(50); // only for INT
scaling2Slider.setMajorTickSpacing(100);
scaling2Slider.setPaintTicks(true);
scaling2Slider.setPaintLabels(true);
scaling2Slider.addChangeListener(this);
scalingPanel.add(scalingButton);
scalingPanel.add(scaling1Slider);
scalingPanel.add(scaling2Slider);
scalingPanel.setToolTipText("Scaling Panel");
// -----------SPEED----------------------------------------
JPanel speedPanel = new JPanel();
JButton speedButton = new JButton("Apply Speed");
speedButton.addActionListener(this);
JRadioButton speedRadioButtonWind = new JRadioButton("Wind");
JRadioButton speedRadioButtonLorry = new JRadioButton("Lorry");
speedRadioButtonLorry.setName("LorrySpeed");
ButtonGroup speedBG = new ButtonGroup();
speedBG.add(speedRadioButtonWind);
speedBG.add(speedRadioButtonLorry);
speedRadioButtonWind.addActionListener(this);
speedRadioButtonLorry.addActionListener(this);
JSlider speedSlider = new JSlider(0, 20, 10); // Min, Max, Value in %
speedSlider.setName("Speed");
speedSlider.setMinorTickSpacing(1); // only for INT
speedSlider.setMajorTickSpacing(5);
speedSlider.setPaintTicks(true);
speedSlider.setPaintLabels(true);
speedSlider.addChangeListener(this);
speedPanel.add(speedButton);
speedPanel.add(speedRadioButtonWind);
speedPanel.add(speedRadioButtonLorry);
speedPanel.add(speedSlider);
speedPanel.setToolTipText("Speed Panel");
// -----------------------------------------------------------
// --------------more Buttons & stuff-------------------------
colorFrame = new JFrame("Choose color and click on the button");
JPanel paintPanel = new JPanel();
JButton paintButton = new JButton("Paint House");
paintButton.addActionListener(this);
chooseColor = new JColorChooser(paint); // white ??
// JButton dayNight = new JButton("Day/Night");
paintPanel.add(paintButton);
paintPanel.add(chooseColor);
colorFrame.add(paintPanel); // NEU !!
colorFrame.setSize(450, 450);
colorFrame.setLocation(400, 250);
colorFrame.setVisible(false); // default=false just for better
// understanding
JPanel buttonPanel = new JPanel();
buttonPanel.setToolTipText("Button Panel");
JButton colorButton = new JButton("Choose Painting Color");
buttonPanel.setSize(100, 25); // funzt das überhaupt ??
colorButton.addActionListener(this);
buttonPanel.add(colorButton);
JButton showHide = new JButton("Show/Hide Stickman");
buttonPanel.add(showHide);
showHide.addActionListener(this);
// funzt noch nciht richtig
// -----------------------------------------------------------
// ----------------Panels-----------------------------------------
JPanel panel = new JPanel(); // main-panel; add Scrollbar if window
// is too small ??
panel.setLayout(new GridLayout(2, 2));
// Dimension minSize = new Dimension(200,200); //adjust
// panel.setMinimumSize(minSize); //does not work !?
translationPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Translation"), BorderFactory
.createEmptyBorder(2, 2, 2, 2))); // distances to the
// borders
panel.add(translationPanel);
scalingPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
.createTitledBorder("Scaling"), BorderFactory
.createEmptyBorder(2, 2, 2, 2)));
panel.add(scalingPanel);
Dimension maxSize = new Dimension(10, 10); // noch notwendig ??
speedPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
.createTitledBorder("Speed"), BorderFactory.createEmptyBorder(
2, 2, 2, 2)));
speedPanel.setMaximumSize(maxSize);
panel.add(speedPanel); // useless ?? Works without this command
panel.add(buttonPanel); // evtl oben dem Button eigenes Panel geben
// (besser)
rcFrame.setContentPane(panel);
rcFrame.setSize(450, 700);
rcFrame.setLocation(575, 0);
rcFrame.setResizable(false);
rcFrame.setVisible(true);
}
/**
* Funtion gets invoked everytime repaint() is beeing called. Creates a new
* dimension object and invokes my own paint method called myPaint() which
* is used for doubleBuffering
*/
public void paint( Graphics g ) // Called for us by the GUI framework
{
Dimension dim = getSize(); // get current FrameSize
setFrameWidth(dim.getWidth()); // need info for creating offscreen
// image
setFrameHeight(dim.getHeight());
myPaint();
if (offScreenImage != null) {
g.drawImage(offScreenImage, 0, 0, this);
}
}
/**
* My own paint method which creates an offScreenImage & Graphics. These are
* used to draw the new image without letting the user see it and when the
* whole drawing is done, this offScreenImage is drawn over the actual
* image, which can be seen by the user. => avoids flickering
*/
public void myPaint() // for DoubleBuffering Java Insel funzt nicht
{
System.out.println("Aktueller Wind Speed: " + getWindSpeed());
System.out.println("Aktueller showStickMan: " + getShowStickMan());
System.out.println("Wert von paintHouse: " + getPaintHouse());
// insert here die Aenderung der FrameSize
offScreenImage = createImage((int) getFrameWidth(),
(int) getFrameHeight());
// offScreenGraphics = offScreenImage.getGraphics();
setOffScreenGraphics(offScreenImage.getGraphics());
// Creates a graphics context for drawing to an off-screen image.
// Background is automatically cleared
// noch get Methode hier für oSG einfügen
draw(offScreenGraphics, getStreet());
draw(offScreenGraphics, getLorry());
offScreenGraphics.drawOval((int) getLorryCircle1X(),
(int) getLorryCircle1Y(), (int) getLorryCircle1Radius(),
(int) getLorryCircle1Radius());
offScreenGraphics.drawOval((int) getLorryCircle2X(),
(int) getLorryCircle2Y(), (int) getLorryCircle2Radius(),
(int) getLorryCircle2Radius());
drawBezierArray(getBezierPointsCloud1());
double underlineCloud1[][] = {
{ getBezierPointsCloud1()[0][0], getBezierPointsCloud1()[0][1] },
{
getBezierPointsCloud1()[getBezierPointsCloud1().length - 1][0],
getBezierPointsCloud1()[getBezierPointsCloud1().length - 1][1] } };
draw(offScreenGraphics, underlineCloud1);
drawBezierArray(getBezierPointsCloud2());
double underlineCloud2[][] = {
{ getBezierPointsCloud2()[0][0], getBezierPointsCloud2()[0][1] },
{
getBezierPointsCloud2()[getBezierPointsCloud2().length - 1][0],
getBezierPointsCloud2()[getBezierPointsCloud2().length - 1][1] } };
draw(offScreenGraphics, underlineCloud2);
drawBezierArray(getBezierPointsHorizon());
draw(offScreenGraphics, getWindMillFoot());
draw(offScreenGraphics, getWindMillSails());
if (getFillHouse() != null) // at the beginning the array is empty
{
System.out
.println("draw(offScreenGraphics, getFillHouse()); wird ausgeführt");
}
draw(offScreenGraphics, getHouse());
// System.out.println("DRAW Alles. ShowStickman: "+getShowStickMan());
if (getShowStickMan()) {
draw(offScreenGraphics, getStickMan());
offScreenGraphics
.drawOval(
(int) (getStickMan()[5][0] - 0.5 * getStickManCircleRadius()),
(int) (getStickMan()[5][1] - getStickManCircleRadius()),
(int) getStickManCircleRadius(),
(int) getStickManCircleRadius());
}
}
/**
* Manages the correct invoking of the drawBezierCurve() method. The
* parameter is a 2-dimensional double array and in this array four entries
* are grouped together to one bezier curve. These four points are converted
* to Point2D by convertArrayEntryToPoint2D because this method works only
* with Point2D
*/
public void drawBezierArray( double[][] bezierPoints ) // get und set für
// offScreenGraphics
// !?
{
for (int i = 0; i < (bezierPoints.length); i += 4) // 4 Points for each
// Bezier-Curve
{
drawBezierCurve(getOffScreenGraphics(), convertArrayEntryToPoint2D(
bezierPoints[i][0], bezierPoints[i][1]),
convertArrayEntryToPoint2D(bezierPoints[i + 1][0],
bezierPoints[i + 1][1]),
convertArrayEntryToPoint2D(bezierPoints[i + 2][0],
bezierPoints[i + 2][1]),
convertArrayEntryToPoint2D(bezierPoints[i + 3][0],
bezierPoints[i + 3][1]));
}
}
/**
* The "heart" of the animation. Here Timer objects are created and started
*/
public void startTimer() {
ActionListener timerListener = new ActionListener() {
public void actionPerformed( ActionEvent evt ) {
// hier Transformation Schritte ändern für weniger CPU Usage
if (evt.getSource() == timerHouse) {
// transform(getHouse(), 0, 0, 0.95, 1, 0, 0, 0);
// transform(getHouse(), 0, 0, 0.99, 0.99, 0, 0, 0);
transform(getHouse(), 0, 0, 1, 1, 0, 0, 0);
}
// if lorry drives out of the frame it becomes mirrored and
// drives back
if (evt.getSource() == timerLorry) {
double max = getLorry()[0][0];
double min = getLorry()[0][0];
for (int i = 0; i < getLorry().length; i++) {
if (min > getLorry()[i][0])
min = getLorry()[i][0];
if (min > 1.25 * getFrameWidth()) {
mirror(getLorry());
setLorrySpeed((-(getLorrySpeed())));
}
if (max < getLorry()[i][0])
max = getLorry()[i][0];
if (max <= -0.25 * getFrameWidth()) {
mirror(getLorry());
setLorrySpeed((-(getLorrySpeed())));
}
}
transform(getLorry(), getLorrySpeed(), 0, 1, 1, 0, 0, 0);
}
if (evt.getSource() == timerStickMan) {
double walkToX = 0.5 * (getHouse()[12][0] + getHouse()[17][0]); // middle
// of
// the
// door
double walkToY = getHouse()[12][1]; // Beginning of the door
if (getPaintHouse()) // hier hängt's !!
{
System.out
.println("PaintHouse == true IST WAHR =>StickMan GEHT LOS");
// System.out.println("Walk to X,Y:
// "+walkToX+","+walkToY+" distanceY:
// "+(getStickMan()[0][1] - walkToY));
if (getStickMan()[0][1] - walkToY > 5) // distance 5 to
// avoid endless
// translation
// if house is
// scaling while
// StickMan is
// moving
{
transform(getStickMan(), 0, -2, 0.99, 0.99, 0, 0, 0);
transformCircle(getStickMan(), 0, 0, 0.99, 0.99, 0,
0, 0);
}
// System.out.println("Walk to X,Y:
// "+walkToX+","+walkToY+" distanceX:
// "+(getStickMan()[0][0] - walkToX));
if (walkToX - getStickMan()[0][0] > 5)
transform(getStickMan(), 2, 0, 1, 1, 0, 0, 0);
if ((getStickMan()[0][1] - walkToY < 5)
&& (walkToX - getStickMan()[0][0] < 5)) {
// System.out.println("OKILIDOKELI");
// paintHouse(offScreenGraphics);
timerPaintingHouse.start();
setPaintHouse(false);
System.out
.println("StickMan nahe genug dran => paintHouse FALSE gesetzt");
}
}
}
if (evt.getSource() == timerClouds) {
// System.out.println("Current wind speed:
// "+getWindSpeed());
// clouds get sheared until the value fits the current
// windspeed
if (getCounter() == getWindSpeed()) {
setOldWindSpeed(getWindSpeed());
setShearingValue(0); // shearing is turned off
setCloudSwitch(true);
}
// System.out.println("getCounter == getWindSpeed()
// "+getCounter()+"=="+getWindSpeed());
if (getCounter() != getWindSpeed()) {
if (getCloudSwitch()) // noch Testen mit RC
{
if (getCounter() < getWindSpeed()) {
setCounter(getCounter()
+ Math.abs(getOldWindSpeed()
- getWindSpeed()));
setShearingValue(0.075);
}
if (getCounter() > getWindSpeed()) // not used ELSE
// to avoid >=
{
setCounter(getCounter()
- Math.abs(getOldWindSpeed()
- getWindSpeed()));
setShearingValue(-0.075);
}
}
setCounter(1); // increment the counter
}
transform(getBezierPointsCloud1(), -getWindSpeed(), 0, 1,
1, shearingValue, 0, 0);
transform(getBezierPointsCloud2(), -getWindSpeed(), 0, 1,
1, shearingValue, 0, 0);
// System.out.println("Shearing Value: "+shearingValue);
// if a cloud leaves the frame on the left side it reenters
// the frame on the right side
if (getBezierPointsCloud1()[getBezierPointsCloud1().length - 2][0] < 0)
transform(getBezierPointsCloud1(), +1.25
* getFrameWidth(), 0, 1, 1, 0, 0, 0);
if (getBezierPointsCloud2()[getBezierPointsCloud2().length - 2][0] < 0)
transform(getBezierPointsCloud2(), +1.25
* getFrameWidth(), 0, 1, 1, 0, 0, 0);
}
if (evt.getSource() == timerWindMillSails) // finished
{
transform(getWindMillSails(), 0, 0, 1, 1, 0, 0,
-getWindSpeed()); // only rotation
}
if (evt.getSource() == timerPaintingHouse) {
int linesToDraw = (int) (getHouse()[0][1] - getHouse()[3][1]);
newFillHouse = new double[2 * linesToDraw][2];
for (int i = 0; i < linesToDraw; i += 2) {
// System.out.println("Lines drawn: "+i+" Lines to be
// drawn: "+linesToDraw);
newFillHouse[i][0] = getHouse()[0][0];
newFillHouse[i][1] = getHouse()[0][1] - i;
newFillHouse[i + 1][0] = getHouse()[1][0];
newFillHouse[i + 1][1] = getHouse()[0][1] - i;
/*
* newFillHouse[i+2][0] = getHouse()[1][0];
* newFillHouse[i+2][1] = getHouse()[0][1]-i;
*/
// Fehler: !! nur jede 2.Linie wird gezeichnet
}
setFillHouse(newFillHouse);
}
repaint(); // the one and only call to repaint()
}
};
// Timer configuration
timerHouse = new Timer(500, timerListener);
timerStickMan = new Timer(500, timerListener);
timerLorry = new Timer(500, timerListener);
timerClouds = new Timer(500, timerListener);
timerWindMillSails = new Timer(500, timerListener);
timerPaintingHouse = new Timer(500, timerListener);
timerHouse.start();
timerLorry.start();
timerStickMan.start();
timerClouds.start();
timerWindMillSails.start();
}
/** Overwrites update() to get rid off the clearScreen() command */
public void update( Graphics g ) {
paint(g);
}
public void draw( Graphics g, double box[][] ) // actual object drawing
{
Graphics2D g2 = (Graphics2D) g;
if (box == getFillHouse()) {
g2.setColor(getHouseColor());
}
for (int i = 0; i < box.length - 1; i += 2) {
drawLine(g2, box[i][0], box[i][1], box[i + 1][0], box[i + 1][1]);
}
g2.setColor(new Color(0, 0, 0)); // black
}
/**
* Here is the essential part of the assignment. This method draws lines
* between two points whose coordinates are stored in a double array
*/
private void drawLine( Graphics2D g2, double x1, double y1, double x2,
double y2 ) {
// g2.setColor(getPaintingColor()); //only changes while painting the
// house
// to avoid lines being drawn which are outside of the frame
if ((x1 < getFrameWidth()) || (x2 < getFrameWidth())
&& ((x1 > 0) || (x2 > 0)))
g2.draw(new Line2D.Double(x1, y1, x2, y2));
}
/**
* This is the most "powerful" method in this assigment. It contents the
* affine transformations and applies them to double fields.
*/
public void transform( double[][] object, double deltaX, double deltaY,
double scaleFactor1, double scaleFactor2, double shearingX,
double shearingY, double degree ) {
int obj = 0;
// TRANSLATION WITH MATRIX
if ((deltaX != 0) || (deltaY != 0)) // to avoid multiplication with
// Identity matrix
{
double translationMatrix[][] = { { 1, 0, deltaX },
{ 0, 1, deltaY }, { 0, 0, 1 } };
for (int i = 0; i < object.length; i++) {
double newX = 0;
double newY = 0;
double[] originalMatrix = { object[i][0], object[i][1], 1 };
// this for-loop does the actual matrix calculation
for (int j = 0; j < originalMatrix.length; j++) {
newX += translationMatrix[0][j] * originalMatrix[j];
newY += translationMatrix[1][j] * originalMatrix[j];
}
object[i][0] = newX;
object[i][1] = newY;
}
saveNewCoordinates(object);
}
// -----------------------
if (object == getHouse()) {
// setHouse(object); //save new coordinates nicht nötig ?? nur ganz
// am Schluss !?
setHouseCenter(); // adjust new Center after translation to be
// able to retranslate to new wanted origin
}
if (object == getStickMan()) {
// setStickMan(object);
/*
* setStickManCircleX(getStickManCircleX()+deltaX);
* setStickManCircleY(getStickManCircleY()+deltaY);
*/
setStickManCenter(); // adjust new Center after translation to be
// able to retranslate to new wanted origin
}
if (object == getLorry()) {
// setLorry(object);
/*
* setLorryCircle1X(getLorryCircle1X()+deltaX);
* setLorryCircle1Y(getLorryCircle1Y()+deltaY);
* setLorryCircle2X(getLorryCircle2X()+deltaX);
* setLorryCircle2Y(getLorryCircle2Y()+deltaY);
*/
setLorryCenter(); // adjust new Center after translation to be
// able to retranslate to new wanted origin
}
// SCALING WITH MATRIX
if ((scaleFactor1 != 1) || (scaleFactor2 != 1)) { // to avoid
// multiplication
// with Identity
// matrix
double scalingMatrix[][] = { { scaleFactor1, 0, 0 },
{ 0, scaleFactor2, 0 }, { 0, 0, 1 } };
double originalX = object[object.length - 1][0];
double originalY = object[object.length - 1][1];
for (int i = 0; i < object.length; i++) {
double newX = 0;
double newY = 0;
double[] originalMatrix = { object[i][0], object[i][1], 1 };
// this for-loop does the actual matrix calculation
for (int j = 0; j < originalMatrix.length; j++) {
newX += scalingMatrix[0][j] * originalMatrix[j];
newY += scalingMatrix[1][j] * originalMatrix[j];
}
object[i][0] = newX; // saving of the new Values
object[i][1] = newY;
}
saveNewCoordinates(object);
// this is the translation to get rid off the implicit scaling
// translation
transform(object, originalX - object[object.length - 1][0],
originalY - object[object.length - 1][1], 1, 1, 0, 0, 0);
}
// -----------------------
// ROTATION WITH MATRIX
if (degree != 0) // to avoid multiplication with Identity matrix
{
double originalX = object[object.length - 1][0];
double originalY = object[object.length - 1][1];
double theta = PI * degree / 180; // convert degree to radiant
double rotationMatrix[][] = {
{ Math.cos(theta), -Math.sin(theta), 0 },
{ Math.sin(theta), Math.cos(theta), 0 }, { 0, 0, 1 } };
// first we need to translate the object to the origin. Rotate it
// there and then move it back to the old position
transform(object, -originalX, -originalY, 1, 1, 0, 0, 0);
for (int i = 0; i < object.length; i++) {
double newX = 0;
double newY = 0;
double[] originalMatrix = { object[i][0], object[i][1], 1 };
// this for-loop does the actual matrix calculation
for (int j = 0; j < originalMatrix.length; j++) {
newX += rotationMatrix[0][j] * originalMatrix[j];
newY += rotationMatrix[1][j] * originalMatrix[j];
}
object[i][0] = newX; // saving of the new Values
object[i][1] = newY;
}
transform(object, originalX, originalY, 1, 1, 0, 0, 0);
saveNewCoordinates(object);
}
// SHEARING WITH MATRIX
if ((shearingX != 0) || (shearingY != 0)) // to avoid multiplication
// with Identity matrix
{
double originalX = object[object.length - 1][0];
double originalY = object[object.length - 1][1];
double shearingMatrix[][] = { { 1, shearingX, 0 },
{ shearingY, 1, 0 }, { 0, 0, 1 } };
// first we need to translate the object to the origin. Rotate it
// there and then move it back to the old position
transform(object, -originalX, -originalY, 1, 1, 0, 0, 0);
for (int i = 0; i < object.length; i++) {
double newX = 0;
double newY = 0;
double[] originalMatrix = { object[i][0], object[i][1], 1 };
// this for-loop does the actual matrix calculation
for (int j = 0; j < originalMatrix.length; j++) {
newX += shearingMatrix[0][j] * originalMatrix[j];
newY += shearingMatrix[1][j] * originalMatrix[j];
}
object[i][0] = newX; // saving of the new Values
object[i][1] = newY;
}
transform(object, originalX, originalY, 1, 1, 0, 0, 0);
saveNewCoordinates(object);
}
}
/**
* Only used to mirror the lorry when it leaves the screen. This method
* finds the mirror line and mirrors the whole object onto that line so that
* the lorry can reenter the frame on the side he left it.
*/
public void mirror( double[][] object ) {
double min = object[0][0];
for (int i = object.length; i < object.length; i++)
// to find the mirror line
if (min > object[i][0])
min = object[i][0];
for (int j = 0; j < object.length; j++) {
object[j][0] -= 2 * (object[j][0] - min);
}
if (object == getLorry()) {
object[getLorry().length - 1][0] -= getLorryCircle1Radius();
object[getLorry().length - 2][0] -= getLorryCircle2Radius();
}
saveNewCoordinates(object);
}
/**
* Converts one array-entry of a two dimensional double array into one Point
* object. This is done becaues drawBezierCurve() only works with Points2D
* objects
*/
public Point2D.Double convertArrayEntryToPoint2D( double x, double y ) {
Point2D.Double newPoint = new Point2D.Double(x, y);
return newPoint;
}
/**
* This method draws a Bezier curve consisting out of four "orientation
* points".
*/
public void drawBezierCurve( Graphics g, Point2D.Double P0,
Point2D.Double P1, Point2D.Double P2, Point2D.Double P3 ) // evtl
// Anzahl
// Schleifendurhcläufe
// mit
// übergeben?
{
if ((Math.abs(P0.getX() - P3.getX()) <= 5)
&& ((Math.abs(P0.getY() - P3.getY())) <= 5))// letzter Teil der
// Bed. verursacht
// StackOverflow
{
g.drawLine((int) P0.getX(), (int) P0.getY(), (int) P3.getX(),
(int) P3.getY());
} else {
Point2D.Double A = getMiddle(P0, P1), B = getMiddle(P3, P2), C = getMiddle(
P1, P2), A1 = getMiddle(A, C), B1 = getMiddle(B, C), C1 = getMiddle(
A1, B1);
drawBezierCurve(g, P0, A, A1, C1);
drawBezierCurve(g, C1, B1, B, P3);
}
} // evtl. nicht ganz korrekt: wenn ein Punkt im negativen Bereich liegt
// o.ä.
/** Returns the midPoint between two points. Needed for drawBezierCurve() */
public Point2D.Double getMiddle( Point2D.Double point1,
Point2D.Double point2 ) {
double newX, newY;
newX = (point2.getX() + point1.getX()) / 2;
newY = (point2.getY() + point1.getY()) / 2;
Point2D.Double midPoint = new Point2D.Double(newX, newY);
// System.out.println("Mitte von "+point1.getX()+", "+point1.getY()+"
// ist "+point2.getX()+", "+point2.getY());
return midPoint;
}
/**
* Paints the house in the selected color. Like a raster system the house
* gets painted by drawing one line along the x-axes after another until the
* area is filled.
*/
/*
* public void paintHouse(Graphics g) { for (int i = 0; i < getHouse()[0][1] -
* getHouse()[3][1]; i++) { System.out.println("Haus wird angemalt");
* setPaintingColor(getHouseColor()); double[][] fillHouse =
* {{getHouse()[0][0],getHouse()[0][1]-i},
* {getHouse()[2][0],getHouse()[2][0]-i}}; //draw(g,
* getHouse()[0][0],getHouse()[0][1]-i,
* getHouse()[2][0],getHouse()[2][0]-i); draw(g, fillHouse);
* setPaintingColor(new Color(0,0,0)); //set color back to black } }
*/
public double[][] getStreet() {
return street;
}
public void setStreet( double[][] value ) {
for (int i = 0; i < value.length; i++) {
street[i][0] = value[i][0];
street[i][1] = value[i][1];
}
}
public double[][] getHouse() {
return house;
}
public void setHouse( double value[][] ) {
for (int i = 0; i < value.length; i++) {
house[i][0] = value[i][0];
house[i][1] = value[i][1];
}
}
public double[][] getStickMan() {
return stickMan;
}
public void setStickMan( double value[][] ) {
for (int i = 0; i < value.length; i++) {
stickMan[i][0] = value[i][0];
stickMan[i][1] = value[i][1];
}
}
public double[][] getLorry() {
return lorry;
}
public void setLorry( double value[][] ) {
for (int i = 0; i < value.length; i++) {
lorry[i][0] = value[i][0];
lorry[i][1] = value[i][1];
}
}
private double getStickManCircleX() {
return stickManCircleX;
}
private void setStickManCircleX( double newX ) {
stickManCircleX = newX;
}
private double getStickManCircleY() {
return stickManCircleY;
}
private void setStickManCircleY( double newY ) {
stickManCircleY = newY;
}
private double getStickManCircleRadius() {
return stickManCircleRadius;
}
private void setStickManCircleRadius( double newRadius ) {
stickManCircleRadius = newRadius;
}
private double getLorryCircle1X() {
return getLorry()[getLorry().length - 2][0];
}
/*
* private void setLorryCircle1X(double newX) { lorryCircle1X = newX; }
*/
private double getLorryCircle1Y() {
return getLorry()[getLorry().length - 2][1];
}
/*
* private void setLorryCircle1Y(double newY) { lorryCircle1Y = newY; }
*/
private double getLorryCircle1Radius() {
return lorryCircle1Radius;
}
private void setLorryCircle1Radius( double newRadius ) {
lorryCircle1Radius = newRadius;
}
private double getLorryCircle2X() {
return getLorry()[getLorry().length - 1][0];
}
/*
* private void setLorryCircle2X(double newX) { lorryCircle2X = newX; }
*/
private double getLorryCircle2Y() {
return getLorry()[getLorry().length - 2][1];
}
/*
* private void setLorryCircle2Y(double newY) { lorryCircle2Y = newY; }
*/
private double getLorryCircle2Radius() {
return lorryCircle2Radius;
}
private void setLorryCircle2Radius( double newRadius ) {
lorryCircle2Radius = newRadius;
}
public double getHouseCenterX() {
double temp[][] = getHouse();
return temp[temp.length - 1][0];
}
public double getHouseCenterY() // besser in einer Methode und dann getPoint
// oder so
{
double temp[][] = getHouse();
return temp[temp.length - 1][1];
}
public void setHouseCenter() // takes new values from transformed array
{
double temp[][] = getHouse();
oldHouseCenterX = temp[temp.length - 1][0];
oldHouseCenterY = temp[temp.length - 1][1];
}
public double getOldHouseCenterX() {
return oldHouseCenterX;
}
public double getOldHouseCenterY() {
return oldHouseCenterY;
}
public double getStickManCenterX() {
double temp[][] = getStickMan();
return temp[temp.length - 1][0];
}
public double getStickManCenterY() // besser in einer Methode und dann
// getPoint oder so
{
double temp[][] = getStickMan();
return temp[temp.length - 1][1];
}
public void setStickManCenter() // takes new values from transformed array
{
double temp[][] = getStickMan();
oldStickManCenterX = temp[temp.length - 1][0];
oldStickManCenterY = temp[temp.length - 1][1];
}
public double getOldStickManCenterX() {
return oldStickManCenterX;
}
public double getOldStickManCenterY() {
return oldStickManCenterY;
}
public double getLorryCenterX() {
double temp[][] = getLorry();
return temp[temp.length - 1][0];
}
public double getLorryCenterY() // besser in einer Methode und dann getPoint
// oder so
{
double temp[][] = getLorry();
return temp[temp.length - 1][1];
}
public void setLorryCenter() // takes new values from transformed array
{
double temp[][] = getLorry();
oldLorryCenterX = temp[temp.length - 1][0];
oldLorryCenterY = temp[temp.length - 1][1];
}
public double getOldLorryCenterX() {
return oldStickManCenterX;
}
public double getOldLorryCenterY() {
return oldStickManCenterY;
}
public boolean getAdditionalTranslationFlag() {
return additionalTranslationFlag;
}
public void setAdditionalTranslationFlag( boolean bool ) {
additionalTranslationFlag = bool;
}
public double getFrameWidth() {
return frameWidth;
}
public void setFrameWidth( double newWidth ) {
frameWidth = newWidth;
}
public double getFrameHeight() {
return frameHeight;
}
public void setFrameHeight( double newHeight ) {
frameHeight = newHeight;
}
public Graphics getOffScreenGraphics() {
return offScreenGraphics;
}
public void setOffScreenGraphics( Graphics newGraphic ) {
offScreenGraphics = newGraphic;
}
/*
* public Timer getTimer1() { return timer1; }
*/
public double[][] getBezierPointsCloud1() {
return bezierPointsCloud1;
}
public void setBezierPointsCloud1( double[][] newValues ) {
for (int i = 0; i < newValues.length; i++) {
bezierPointsCloud1[i][0] = newValues[i][0];
bezierPointsCloud1[i][1] = newValues[i][1];
}
}
public double[][] getBezierPointsCloud2() {
return bezierPointsCloud2;
}
public void setBezierPointsCloud2( double[][] newValues ) {
for (int i = 0; i < newValues.length; i++) {
bezierPointsCloud2[i][0] = newValues[i][0];
bezierPointsCloud2[i][1] = newValues[i][1];
}
}
public double[][] getBezierPointsHorizon() {
return bezierPointsHorizon;
}
public void setBezierPointsHorizon( double[][] newValues ) {
for (int i = 0; i < newValues.length; i++) {
bezierPointsHorizon[i][0] = newValues[i][0];
bezierPointsHorizon[i][1] = newValues[i][1];
}
}
public void saveNewCoordinates( double[][] object ) {
if (object == getHouse()) {
setHouse(object); // save new coordinates
setHouseCenter();
}
if (object == getStickMan()) {
setStickMan(object);
setStickManCenter();
}
if (object == getLorry()) {
setLorry(object);
setLorryCenter();
}
}
// NOT FINISHED //does not work and does not include shearing
public void transformCircle( double[][] object, double deltaX,
double deltaY, double scaleFactor1, double scaleFactor2,
double shearingX, double shearingY, double degree ) {
if (object == getStickMan()) {
if ((scaleFactor1 != 1) || (scaleFactor2 != 1)) {
setStickManCircleRadius(getStickManCircleRadius()
* scaleFactor1);
}
}
/*
* if (object == getLorry()) { if((deltaX != 0) || (deltaY != 0)) {
* setLorryCircle1X(getLorryCircle1X() + deltaX);
* setLorryCircle1Y(getLorryCircle1Y() + deltaY);
* setLorryCircle2X(getLorryCircle2X() + deltaX);
* setLorryCircle2Y(getLorryCircle2Y() + deltaY); } if((scaleFactor1 !=
* 1) || (scaleFactor2 != 1)) {
* setLorryCircle1Radius(getLorryCircle1Radius() * scaleFactor1);
* setLorryCircle2Radius(getLorryCircle2Radius() * scaleFactor1);
* //setLorryCircle1X(getLorryCircle1X() * (scaleFactor1));
* //setLorryCircle1Y(getLorryCircle1Y() * (1-(1-scaleFactor1))); } }
*/
}