/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bounceboxframework;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
/**
*
* @author p0073862
*/
public class BounceController implements ActionListener {
BounceModel model;
Timer timer;
int refreshInterval;
double doubleInterval;
public BounceController(BounceModel model, int refreshInterval) {
this.model = model;
this.refreshInterval = refreshInterval;
timer = new Timer(refreshInterval,this);
doubleInterval = refreshInterval/1000.0;
}
public void start() {
timer.start();
}
public void actionPerformed(ActionEvent e) {
model.moveShapes(doubleInterval);
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bounceboxframework;
import java.util.List;
import java.util.LinkedList;
import java.util.Observable;
/**
*
* @author p0073862
*/
public class BounceModel extends Observable {
private List<Shape> shapes = new LinkedList<Shape>();
private List<Wall> walls = new LinkedList<Wall>();
public void addShape(Shape shape){
shapes.add(shape);
}
public void addWall(Wall wall) {
walls.add(wall);
}
public void moveShapes(double time) {
int first = 1;
int size = shapes.size();
for (Shape s:shapes) {
for (Wall w: walls) {
s.interactWall(w);
}
for(Shape s2: shapes.subList(first, size)) {
s.interactShape(s2);
}
first++;
}
for (Shape s:shapes) {
s.move(time);
}
setChanged();
notifyObservers();
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bounceboxframework;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JPanel;
/**
*
* @author p0073862
*/
public class BouncePanel extends JPanel {
private int width;
private int height;
private List<Drawable> drawshapes = new LinkedList<Drawable>();
public BouncePanel(int width, int height) {
super();
this.width = width;
this.height = height;
setPreferredSize(new Dimension(width, height));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, width, height);
for (Drawable d: drawshapes) {
d.draw(g2);
}
}
public void addDrawable(Drawable d) {
drawshapes.add(d);
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bounceboxframework;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
/**
*
* @author p0073862
*/
public class BounceView implements Observer {
private JFrame frame;
private BouncePanel panel;
private BounceModel model;
public BounceView(int width, int height, BounceModel model) {
this.model = model;
model.addObserver(this);
frame = new JFrame("Bounce Box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new BouncePanel(width, height);
frame.setContentPane(panel);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
}
public void update(Observable obs, Object arg) {
panel.repaint();
}
public void addDrawable(Drawable d) {
panel.addDrawable(d);
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bounceboxframework;
import java.awt.Graphics2D;
/**
*
* @author p0073862
*/
public interface Drawable {
public void draw(Graphics2D g);
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package bounceboxframework;
/**
*
* @author p0074487
*/
public interface Moveable {
public void move(double time);
public double getX();
public double getY();
public void setVelocity(double vx, double vy);
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bounceboxframework;
import java.awt.Color;
/**
*
* @author p0073862
*/
public abstract class Shape implements Drawable, Moveable{
private double x;
private double y;
private double vx = 0;
private double vy = 0;
private Color color = Color.BLACK;
public Shape(int x, int y) {
this.x = x;
this.y =y;
}
@Override
public double getX(){return x;}
@Override
public double getY(){return y;}
//public void setX(int x) {this.x = x;}
//public void setY(int y) {this.y = x;}
@Override
public void setVelocity(double vx, double vy) {
this.vx = vx;
this.vy = vy;
}
public void setColor(Color color) {
this.color = color;
}
public Color getColor() {return color;}
public void move(double time) {
x+= vx * time;
y+= vy * time;
}
private void reflect(double nx, double ny) {
double dot = Util.dotprod(nx,ny,vx,vy);
double absn = Util.mag(nx, ny);
vx -= 2*nx*dot/(absn*absn);
vy -= 2*ny*dot/(absn*absn);
}
/**
* Interact with a wall bounding the space ax+by+c>0 in which the shape can
* We assume (a,b) is normalised
* move
* @param a
* @param b
* @param c
*/
public void interactWall(Wall wall) {
double a = wall.getA();
double b = wall.getB();
double c = wall.getC();
//are we close enough to the wall to bounce
if (Util.dotprod(x, y, a, b) + c < getContactRadius()) {
//are we moving towards the wall
if (Util.dotprod(vx, vy, a, b)<0) {
reflect(a, b);
}
}
}
public void interactShape(Shape s) {
double dx = s.x-x;
double dy = s.y-y;
// are the two shapes close enough to interact
if (Util.mag(dx, dy) < (getContactRadius() + s.getContactRadius())) {
double dvx = s.vx-vx;
double dvy = s.vy-vy;
//are the two shapes moving together
if (Util.dotprod(dx, dy, dvx, dvy)<0) {
//ndx,ndy = normalised (dx,dy)
double magd = Util.mag(dx, dy);
double ndx = dx/magd;
double ndy = dy/magd;
//uperp = velocity of this perpendicular to line between shapes
double uperp = Util.dotprod(vx, vy, -ndy, ndx);
//usperp = velocity of s perpendicular to line between shapes
double usperp = Util.dotprod(s.vx, s.vy, -ndy, ndx);
//upar = init. velocity of this parallel to line between shapes
double upar = Util.dotprod(vx, vy, ndx, ndy);
//uspar = init. velocity of s parallel to line between shapes
double uspar = Util.dotprod(s.vx, s.vy, ndx, ndy);
double m = getMass();
double ms = s.getMass();
//vpar = final velocity of this parallel to line between shapes
double vpar = (upar*(m-ms)+2*ms*uspar)/(m+ms);
//vspar = final velocity of this parallel to line between shapes
double vspar = (uspar*(ms-m)+2*m*upar)/(m+ms);
vx = vpar*ndx-uperp*ndy;
vy = vpar*ndy+uperp*ndx;
s.vx = vspar*ndx-usperp*ndy;
s.vy = vspar*ndy+usperp*ndx;
}
}
}
public abstract double getContactRadius();
public abstract double getMass();
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bounceboxframework;
/**
*
* @author p0073862
*/
public class Util {
public static double dotprod(double x1, double y1, double x2, double y2) {
return x1*x2+y1*y2;
}
public static double mag(double x, double y) {
return Math.sqrt(x*x + y*y);
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bounceboxframework;
/**
*
* @author p0073862
*/
// a wall that restricts shapes to moving in the area ax+by+c>0
public class Wall {
private double a,b,c;
public Wall(double a, double b, double c) {
this.a=a; this.b=b; this.c=c;
}
public double getA(){return a;}
public double getB(){return b;}
public double getC(){return c;}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bouncebox;
import bounceboxframework.Shape;
import bounceboxframework.Wall;
import bounceboxframework.BounceModel;
import bounceboxframework.BounceController;
import bounceboxframework.BounceView;
/**
*
* @author p0073862
*/
public class BounceBox {
BounceModel model;
BounceView view;
BounceController controller;
public static final int TIMER_INTERVAL = 50;
public BounceBox(int width, int height) {
model = new BounceModel();
model.addWall(new Wall(1,0,0));
model.addWall(new Wall(-1, 0, width));
model.addWall(new Wall(0, 1, 0));
model.addWall(new Wall(0, -1, height));
view = new BounceView(width, height, model);
controller = new BounceController(model, TIMER_INTERVAL);
}
public void addShape(Shape s) {
model.addShape(s);
view.addDrawable(s);
}
public void start() {
controller.start();
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bouncebox;
import bounceboxframework.Shape;
import java.awt.Graphics2D;
/**
*
* @author p0073862
*/
public class Circle extends Shape {
private int radius;
public Circle(int x, int y, int radius) {
super(x,y);
this.radius = radius;
}
public int getRadius(){return radius;}
public double getContactRadius() {return radius;}
public double getMass() {return Math.PI*radius*radius;}
public void draw(Graphics2D g) {
g.setColor(getColor());
double left = getX() - getRadius();
double top = getY() - getRadius();
g.fillOval((int)left,(int)top,getRadius()*2,
getRadius()*2);
}
}
import bounceboxframework.Shape;
import java.awt.Graphics2D;
/**
*
* @author p0073862
*/
public class Square extends Shape {
private double contactRadius;
private int width;
public Square(int x, int y, int width) {
super(x,y);
this.width = width;
contactRadius = Math.sqrt(width*width/2);
}
public int getWidth(){return width;}
public double getContactRadius() {return contactRadius;}
public double getMass() {return width*width;}
public void draw(Graphics2D g) {
g.setColor(getColor());
int left = (int) (getX()-width/2);
int top = (int) (getY()-width/2);
g.fillRect(left,top, width, width);
}
}
上面是相关代码,图片是要求,写main代码
import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import bouncebox.BounceBox;
import bouncebox.Circle;
import bouncebox.Shape;
import bouncebox.Square;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
BounceBox bb = new BounceBox(600, 500);
int numCircles = 0, numSquares = 0;
double totalArea = 0.0;
Scanner scanner = new Scanner(new File("practical8.txt"));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] tokens = line.split("\\s+");
if (tokens[0].equals("Circle")) {
try {
int x = Integer.parseInt(tokens[1]);
int y = Integer.parseInt(tokens[2]);
int r = Integer.parseInt(tokens[3]);
Circle circle = new Circle(x, y, r);
bb.addShape(circle);
numCircles++;
totalArea += Math.PI * r * r;
if (tokens.length >= 6) {
double vx = Double.parseDouble(tokens[4]);
double vy = Double.parseDouble(tokens[5]);
circle.setVelocity(vx, vy);
if (tokens.length == 9) {
int red = Integer.parseInt(tokens[6]);
int green = Integer.parseInt(tokens[7]);
int blue = Integer.parseInt(tokens[8]);
Color color = new Color(red, green, blue);
circle.setColor(color);
}
}
} catch (NumberFormatException e) {
// ignore invalid input
}
} else if (tokens[0].equals("Square")) {
try {
int x = Integer.parseInt(tokens[1]);
int y = Integer.parseInt(tokens[2]);
int width = Integer.parseInt(tokens[3]);
Square square = new Square(x, y, width);
bb.addShape(square);
numSquares++;
totalArea += width * width;
if (tokens.length >= 6) {
double vx = Double.parseDouble(tokens[4]);
double vy = Double.parseDouble(tokens[5]);
square.setVelocity(vx, vy);
if (tokens.length == 9) {
int red = Integer.parseInt(tokens[6]);
int green = Integer.parseInt(tokens[7]);
int blue = Integer.parseInt(tokens[8]);
Color color = new Color(red, green, blue);
square.setColor(color);
}
}
} catch (NumberFormatException e) {
// ignore invalid input
}
}
}
scanner.close();
System.out.println("Number of circles: " + numCircles);
System.out.println("Number of squares: " + numSquares);
System.out.println("Total area of all shapes: " + totalArea);
bb.start();
}
}
仅供参考
import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import bouncebox.BounceBox;
import bouncebox.Circle;
import bouncebox.Shape;
import bouncebox.Square;
public class Test{
public static void main(String[] args) throws FileNotFoundException {
BounceBox bb = new BounceBox(500, 500);
int numCircles = 0, numSquares = 0;
double totalArea = 0.0;
Scanner scanner = new Scanner(new File("practical8.txt"));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] tokens = line.split("\\s+");
if (tokens[0].equals("Circle")) {
try {
int x = Integer.parseInt(tokens[1]);
int y = Integer.parseInt(tokens[2]);
int r = Integer.parseInt(tokens[3]);
Circle circle = new Circle(x, y, r);
bb.addShape(circle);
numCircles++;
totalArea += Math.PI * r * r;
if (tokens.length >= 6) {
double vx = Double.parseDouble(tokens[4]);
double vy = Double.parseDouble(tokens[5]);
circle.setVelocity(vx, vy);
if (tokens.length == 9) {
int red = Integer.parseInt(tokens[6]);
int green = Integer.parseInt(tokens[7]);
int blue = Integer.parseInt(tokens[8]);
Color color = new Color(red, green, blue);
circle.setColor(color);
}
}
} catch (NumberFormatException e) {
// ignore invalid input
}
} else if (tokens[0].equals("Square")) {
try {
int x = Integer.parseInt(tokens[1]);
int y = Integer.parseInt(tokens[2]);
int width = Integer.parseInt(tokens[3]);
Square square = new Square(x, y, width);
bb.addShape(square);
numSquares++;
totalArea += width * width;
if (tokens.length >= 6) {
double vx = Double.parseDouble(tokens[4]);
double vy = Double.parseDouble(tokens[5]);
square.setVelocity(vx, vy);
if (tokens.length == 9) {
int red = Integer.parseInt(tokens[6]);
int green = Integer.parseInt(tokens[7]);
int blue = Integer.parseInt(tokens[8]);
Color color = new Color(red, green, blue);
square.setColor(color);
}
}
} catch (NumberFormatException e) {
// ignore invalid input
}
}
}
scanner.close();
System.out.println("Number of circles: " + numCircles);
System.out.println("Number of squares: " + numSquares);
System.out.println("Total area of all shapes: " + totalArea);
bb.start();
}
}