Gå til innhold

Simulering av roterende bokser--får NaN!


Anbefalte innlegg

Hei,

 

Jeg driver å forbedrer meg litt på fysikk og tenkte jeg skulle prøve å få til korrekt implementasjon av rotasjon ved påføring av krefter. Jeg har kommet meg langt nok til at simmen skulle funke, men når jeg kjører den, dukker det ikke opp noen ting, og når jeg la til litt tekst til hjelp på skjermen viste det seg at de fleste variablene ble not a number. Trenger hjelp!

 

RotatingShapes.java:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Date;

class RotatingShapes extends JFrame implements KeyListener
{
boolean isLeftPressed, isRightPressed, isUpPressed, isDownPressed, isAPressed, isDPressed, isWPressed, isSPressed, isZPressed, isXPressed;

View view;

Rect rect;

DrawingPanel drawingPanel;

Timer calcTimer, dispTimer;

public RotatingShapes()
{
 setTitle("RotatingShapes");
 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 setLocation(50, 50);
 addKeyListener(this);
 
 reset();
 
 drawingPanel = new DrawingPanel();
 getContentPane().add(drawingPanel);
 
 calcTimer = new Timer(1, new CalcLoop());
 calcTimer.start();
 dispTimer = new Timer(1, new DispLoop());
 dispTimer.start();
 
 setVisible(true);
 pack();
}

public void reset()
{
 view = new View(new Dimension(800, 600), new Vector(0, 0), 0.02);
 
 rect = new Rect(
 	new Vector(0, 0),
 	new Vector(0, 0),
 	0,
 	0,
 	4,
 	new Vector(0, 0),
 	0.2,
 	2
 );
}

class DrawingPanel extends JPanel
{
 Dimension preferredSize = new Dimension(view.size.width, view.size.height);
 
 public DrawingPanel()
 {
 	super();
 }
 
 public Dimension getPreferredSize()
 {
 	return preferredSize;
 }
 
 public void paintComponent(Graphics g)
 {
 	super.paintComponent(g);
 	
 	Graphics2D g2D = (Graphics2D)g;
 	
 	// MAIN DRAW AREA
 	
 	// draw rect
 	int[] xGeom = new int[rect.xGeom.length];
 	int[] yGeom = new int[rect.yGeom.length];
 	for (int i = 0; i < rect.xGeom.length; i++)
 	{
   Vector point = view.getPointInView(rect.pos.getAdded(new Vector(rect.xGeom[i], rect.yGeom[i]).getAngled(rect.angle)));
   xGeom[i] = (int)point.x;
   yGeom[i] = (int)point.y;
 	}
 	g2D.setColor(Color.GREEN);
 	g2D.fillPolygon(xGeom, yGeom, xGeom.length);
 	
 	// draw info
 	g2D.setColor(Color.BLACK);
 	g2D.drawString("xPos: " + rect.pos.x, 5, 30);
 	g2D.drawString("yPos: " + rect.pos.y, 5, 50);
 	g2D.drawString("xVel: " + rect.velocity.x, 5, 70);
 	g2D.drawString("yVel: " + rect.velocity.y, 5, 90);
 	g2D.drawString("angle: " + rect.angle, 5, 110);
 	g2D.drawString("angleSpeed: " + rect.angleSpeed, 5, 130);
 }
}

class CalcLoop implements ActionListener
{
 Date lastRun = new Date();
 double calcPerSec;
 double fractions;
 
 public void actionPerformed(ActionEvent e)
 {
 	Date thisRun = new Date();
 	long dT = thisRun.getTime() - lastRun.getTime();
 	lastRun = thisRun;
 	if (dT > 0)
   calcPerSec = 1000 / dT;
 	else
   calcPerSec = 1000;
 	
 	// MAIN CALCULATION AREA
 	
 	if (isLeftPressed)
   rect.applyForce(new Vector(-5, 0).getAngled(rect.angle), new Vector(0, 2).getAngled(rect.angle), fractions);
 	if (isRightPressed)
   rect.applyForce(new Vector(5, 0).getAngled(rect.angle), new Vector(0, 2).getAngled(rect.angle), fractions);
 	if (isUpPressed)
   rect.applyForce(new Vector(0, 5).getAngled(rect.angle), new Vector(0, 2).getAngled(rect.angle), fractions);
 	if (isDownPressed)
   rect.applyForce(new Vector(0, -5).getAngled(rect.angle), new Vector(0, 2).getAngled(rect.angle), fractions);
 	
 	rect.move(fractions);
 	rect.rotate(fractions);
 	
 	if (isAPressed)
   view.pos.x -= 300 * view.scale / calcPerSec;
 	if (isDPressed)
   view.pos.x += 300 * view.scale / calcPerSec;
 	if (isWPressed)
   view.pos.y -= 300 * view.scale / calcPerSec;
 	if (isSPressed)
   view.pos.y += 300 * view.scale / calcPerSec;
 	
 	if (isZPressed)
   view.scale += 2 * view.scale / calcPerSec;
 	if (isXPressed)
   view.scale -= 2 * view.scale / calcPerSec;
 }
}

class DispLoop implements ActionListener
{
 public void actionPerformed(ActionEvent e)
 {
 	drawingPanel.repaint();
 }
}

public void keyPressed(KeyEvent e)
{
 int key = e.getKeyCode();
 if (key == KeyEvent.VK_LEFT)
 	isLeftPressed = true;
 else if (key == KeyEvent.VK_RIGHT)
 	isRightPressed = true;
 else if (key == KeyEvent.VK_UP)
 	isUpPressed = true;
 else if (key == KeyEvent.VK_DOWN)
 	isDownPressed = true;
 else if (key == KeyEvent.VK_A)
 	isAPressed = true;
 else if (key == KeyEvent.VK_D)
 	isDPressed = true;
 else if (key == KeyEvent.VK_W)
 	isWPressed = true;
 else if (key == KeyEvent.VK_S)
 	isSPressed = true;
 else if (key == KeyEvent.VK_Z)
 	isZPressed = true;
 else if (key == KeyEvent.VK_X)
 	isXPressed = true;
}

public void keyReleased(KeyEvent e)
{
 int key = e.getKeyCode();
 if (key == KeyEvent.VK_LEFT)
 	isLeftPressed = false;
 else if (key == KeyEvent.VK_RIGHT)
 	isRightPressed = false;
 else if (key == KeyEvent.VK_UP)
 	isUpPressed = false;
 else if (key == KeyEvent.VK_DOWN)
 	isDownPressed = false;
 else if (key == KeyEvent.VK_A)
 	isAPressed = false;
 else if (key == KeyEvent.VK_D)
 	isDPressed = false;
 else if (key == KeyEvent.VK_W)
 	isWPressed = false;
 else if (key == KeyEvent.VK_S)
 	isSPressed = false;
 else if (key == KeyEvent.VK_Z)
 	isZPressed = false;
 else if (key == KeyEvent.VK_X)
 	isXPressed = false;
 else if(key == KeyEvent.VK_C)
 	reset();
}

public void keyTyped(KeyEvent e)
{
}

public static void main(String[] args)
{
 new RotatingShapes();
}
}

Vector.java:

class Vector
{
double x;
double y;

public Vector()
{
 this.x = 0;
 this.y = 0;
}

public Vector(double x, double y)
{
 this.x = x;
 this.y = y;
}

public Vector(Vector vector)
{
 x = vector.x;
 y = vector.y;
}

public void setX(double x)
{
 this.x = x;
}

public void setY(double y)
{
 this.y = y;
}

public void setAngle(double angle)
{
 double oldLength = getLength();
 x = oldLength * Math.sin(angle);
 y = oldLength * Math.cos(angle);
}

public void setLength(double length)
{
 double oldAngle = getAngle();
 x = length * Math.sin(oldAngle);
 y = length * Math.cos(oldAngle);
}

public double getX()
{
 return x;
}

public double getY()
{
 return y;
}

public double getAngle()
{
 return Math.atan2(y, x);
}

public double getLength()
{
 return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}

public void add(Vector other)
{
 x += other.getX();
 y += other.getY();
}

public void subtract(Vector other)
{
 x -= other.getX();
 y -= other.getY();
}

public void multiply(double num)
{
 x *= num;
 y *= num;
}

public void divide(double num)
{
 x /= num;
 y /= num;
}

public Vector getAdded(Vector other)
{
 return new Vector(x + other.getX(), y + other.getY());
}

public Vector getSubtracted(Vector other)
{
 return new Vector(x - other.getX(), y - other.getY());
}

public Vector getMultiplied(double num)
{
 return new Vector(x * num, y * num);
}

public Vector getDivided(double num)
{
 return new Vector(x / num, y / num);
}

public Vector getAngled(double angle)
{
 double newAngle = getAngle() + angle;
 return new Vector(getLength() * Math.sin(newAngle), getLength() * Math.cos(newAngle));
}
}

View.java:

import java.awt.Dimension;

class View
{
Dimension size;
Vector pos;
double scale;

public View(Dimension size, Vector pos, double scale)
{
 this.size = size;
 this.pos = pos;
 this.scale = scale;
}

public Vector getPointInView(Vector point)
{
 return new Vector(size.width / 2 + (point.getX() - pos.getX()) / scale, size.height / 2 + (point.getY() - pos.getY()) / scale);
}
}

Shape.java:

class Shape
{
Vector pos;
Vector velocity;

double angle;
double angleSpeed;

double mass;
Vector centerMass;

double inertia;

double[] xGeom;
double[] yGeom;

public void move(double fractions)
{
 pos.add(velocity.getDivided(fractions));
}

public void rotate(double fractions)
{
 angle += angleSpeed / fractions;
}

public void applyForce(Vector force, Vector disp, double fractions)
{
 velocity.add(force.getDivided(fractions));
 
 angleSpeed += (disp.getX() * force.getY() - disp.getX() * force.getX()) / inertia / fractions;
}
}

Rect.java:

class Rect extends Shape
{
double width;
double height;

public Rect(Vector pos, Vector velocity, double angle, double angleSpeed, double mass, Vector centerMass, double width, double height)
{
 this.pos = pos;
 this.velocity = velocity;
 
 this.angle = angle;
 this.angleSpeed = angleSpeed;
 
 this.mass = mass;
 this.centerMass = centerMass;
 
 this.width = width;
 this.height = height;
 
 inertia = mass * (Math.pow(width, 2) + Math.pow(height, 2)) / 12;
 
 xGeom = new double[]
 {
 	-width / 2,
 	width / 2,
 	width / 2,
 	-width / 2
 };
 yGeom = new double[]
 {
 	height / 2,
 	height / 2,
 	-height / 2,
 	-height / 2
 };
}
}

Whew! Jeg håper at noen i det hele tatt gidder å ta en liten titt på det hvertfall, for jeg skjønner ikke hvor feilen skjer... Tusen takk hvis noen gidder! :cry:

Lenke til kommentar
Videoannonse
Annonse

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...