I have tried to follow the Wikipedia page on 3d projection to draw my own 3d line using java and AWT with Swing.
The output file that is created as a result of the rendering doesn't contain anything.
What have I done wrong?
Why isn't this producing an image file that has points on it?
Are my formulas off?
I was following this Wikipedia page as my reference: https://en.wikipedia.org/wiki/3D_projection#Perspective_projection
I have a set of points which are generated using a loop.
I then calculate the position of the 3d coordinate to 2d without using matrices, like one of the suggested method in the link.
Have I miss-interpreted something or not implemented something?
Any help and feedback are welcome.
I known nothing is drawn to the window. That isn't a priority at the moment. The priority it's getting the algorithms to work.
public class Window {
JFrame f = new JFrame();
public Window() {
JPanel p = new JPanel();
render();
f.add(p);
f.setSize(500, 500);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Window w = new Window();
}
void render() {
BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(Color.red);
for (int i = 0; i < 10; i++) {
Vector3 point = new Vector3(1 + i, 2, 1 + i);
int x = calculateBX(point, new Vector3(0, 0, 0));
int y = calculateBY(point, new Vector3(1, 1, 1));
g.drawLine(x, y, x, y);
}
try {
File outputfile = new File("saved.png");
ImageIO.write(image, "png", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
double calculatDX(Vector3 v, Vector3 camera) {
double cx = Math.cos(0);
double cy = Math.cos(0);
double cz = Math.cos(0);
double sx = Math.sin(0);
double sy = Math.sin(0);
double sz = Math.sin(0);
int x = v.getX() - camera.getX();
int y = v.getY() - camera.getY();
int z = v.getZ() - camera.getZ();
double dx = cy * ((sz) * (y) + (cz) * (x)) - (sy) * (z);
return dx;
}
double calculatDY(Vector3 v, Vector3 camera) {
double cx = Math.cos(0);
double cy = Math.cos(0);
double cz = Math.cos(0);
double sx = Math.sin(0);
double sy = Math.sin(0);
double sz = Math.sin(0);
int x = v.getX() - camera.getX();
int y = v.getY() - camera.getY();
int z = v.getZ() - camera.getZ();
double dy = sx * ((cy) * (z) + (sy) * ((sz) * (y) + (cz) * (x))) + (cx) * (cz * (y) - sz * x);
return dy;
}
double calculatDZ(Vector3 v, Vector3 camera) {
double cx = Math.cos(0);
double cy = Math.cos(0);
double cz = Math.cos(0);
double sx = Math.sin(0);
double sy = Math.sin(0);
double sz = Math.sin(0);
int x = v.getX() - camera.getX();
int y = v.getY() - camera.getY();
int z = v.getZ() - camera.getZ();
double dz = cx * ((cy) * (z) + (sy) * ((sz) * (y) + (cz) * (x))) - (sx) * (cz * (y) - sz * x);
return dz;
}
int calculateBX(Vector3 v, Vector3 camera) {
int ez = camera.getZ();
int ex = camera.getX();
double dz = calculatDZ(v, camera);
double dx = calculatDX(v, camera);
return (int) ((ez / dz) * dx) - ex;
}
int calculateBY(Vector3 v, Vector3 camera) {
int ez = camera.getZ();
int ey = camera.getY();
double dz = calculatDZ(v, camera);
double dy = calculatDY(v, camera);
return (int) ((ez / dz) * dy) - ey;
}
}
Vector Class
public class Vector3 {
private int x, y, z;
public Vector3(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
}
Related
I have modified this arcball class so that every call to arcball.rollforward(PI/180); rotates a matrix 1 degree.
I have tried to set it up so arcball.rollback() is called with the accumulated float rotatebywithincludedfloaterror but it has had the same degree error as rolling back 360 degrees without the float error.
this is how far it is off after 1000 full rotations, it should be a 1:1 reflection of the top cube over x
here is main function with a loop of 1 * 360 degree rotation and framerate for testing (set framerate to 900 for multiple rotations so it dose not take forever)
Arcball arcball;
int i;
//framecount
int fcount, lastm;
float frate;
int fint = 3;
boolean[] keys = new boolean[13];
final int w = 0;
void setup() {
size(900, 700, P3D);
frameRate(60);
noStroke();
arcball = new Arcball(width/2, height/2, 100); //100 is radius
}
void draw() {
lights();
background(255,160,122);
print(" \n degree = " + i );
i++;
if(i <= (360 * 1)) { arcball.rollforward(PI/180); }
else { print(" break"); }
if(keys[w]) { arcball.rollforward(PI/180); }
translate(width/2, height/2-100, 0);
box(50);
translate(0, 200, 0);
arcball.run();
box(50);
fcount += 1;
int m = millis();
if (m - lastm > 1000 * fint) {
frate = float(fcount) / fint;
fcount = 0;
lastm = m;
println("fps: " + frate);
}
}
void keyPressed() {
switch(key) {
case 119:
keys[w] = true;
break;
}
}
void keyReleased() {
switch(key) {
case 119:
keys[w] = false;
break;
}
}
and the arcball class
// Ariel and V3ga's arcball class with a couple tiny mods by Robert Hodgin and smaller mods by cubesareneat
class Arcball {
float center_x, center_y, radius;
Vec3 v_down, v_drag;
Quat q_now, q_down, q_drag;
Vec3[] axisSet;
int axis;
float mxv, myv;
float x, y;
float degreeW_count = 0;
float degreeS_count = 0;
float rotatebywithincludedfloaterror =0;
Arcball(float center_x, float center_y, float radius){
this.center_x = center_x;
this.center_y = center_y;
this.radius = radius;
v_down = new Vec3();
v_drag = new Vec3();
q_now = new Quat();
q_down = new Quat();
q_drag = new Quat();
axisSet = new Vec3[] {new Vec3(1.0f, 0.0f, 0.0f), new Vec3(0.0f, 1.0f, 0.0f), new Vec3(0.0f, 0.0f, 1.0f)};
axis = -1; // no constraints...
}
void rollforward(float radians2turn) {
rotatebywithincludedfloaterror = rotatebywithincludedfloaterror + (-1 * (((sin(radians2turn) * radius))/2));
if(degreeW_count >= 360) {
arcball.rollback(rotatebywithincludedfloaterror);
degreeW_count = 0;
rotatebywithincludedfloaterror = 0;
}
rollortilt(0, -1 * (((sin(radians2turn) * radius))/2));
degreeW_count = degreeW_count + 1; // need to edit this later to work with rotations other then 1 degree
}
void rollback(float radians2turn) {
rollortilt(0, ((sin(radians2turn) * radius))/2);
}
void rollortilt(float xtra, float ytra){
q_down.set(q_now);
v_down = XY_to_sphere(center_x, center_y);
q_down.set(q_now);
q_drag.reset();
v_drag = XY_to_sphere(center_x + xtra, center_y + ytra);
q_drag.set(Vec3.dot(v_down, v_drag), Vec3.cross(v_down, v_drag));
}
/*
void mousePressed(){
v_down = XY_to_sphere(mouseX, mouseY);
q_down.set(q_now);
q_drag.reset();
}
void mouseDragged(){
v_drag = XY_to_sphere(mouseX, mouseY);
q_drag.set(Vec3.dot(v_down, v_drag), Vec3.cross(v_down, v_drag));
}
*/
void run(){
q_now = Quat.mul(q_drag, q_down);
applyQuat2Matrix(q_now);
x += mxv;
y += myv;
mxv -= mxv * .01;
myv -= myv * .01;
}
Vec3 XY_to_sphere(float x, float y){
Vec3 v = new Vec3();
v.x = (x - center_x) / radius;
v.y = (y - center_y) / radius;
float mag = v.x * v.x + v.y * v.y;
if (mag > 1.0f){
v.normalize();
} else {
v.z = sqrt(1.0f - mag);
}
return (axis == -1) ? v : constrain_vector(v, axisSet[axis]);
}
Vec3 constrain_vector(Vec3 vector, Vec3 axis){
Vec3 res = new Vec3();
res.sub(vector, Vec3.mul(axis, Vec3.dot(axis, vector)));
res.normalize();
return res;
}
void applyQuat2Matrix(Quat q){
// instead of transforming q into a matrix and applying it...
float[] aa = q.getValue();
rotate(aa[0], aa[1], aa[2], aa[3]);
}
}
static class Vec3{
float x, y, z;
Vec3(){
}
Vec3(float x, float y, float z){
this.x = x;
this.y = y;
this.z = z;
}
void normalize(){
float length = length();
x /= length;
y /= length;
z /= length;
}
float length(){
return (float) Math.sqrt(x * x + y * y + z * z);
}
static Vec3 cross(Vec3 v1, Vec3 v2){
Vec3 res = new Vec3();
res.x = v1.y * v2.z - v1.z * v2.y;
res.y = v1.z * v2.x - v1.x * v2.z;
res.z = v1.x * v2.y - v1.y * v2.x;
return res;
}
static float dot(Vec3 v1, Vec3 v2){
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
static Vec3 mul(Vec3 v, float d){
Vec3 res = new Vec3();
res.x = v.x * d;
res.y = v.y * d;
res.z = v.z * d;
return res;
}
void sub(Vec3 v1, Vec3 v2){
x = v1.x - v2.x;
y = v1.y - v2.y;
z = v1.z - v2.z;
}
}
static class Quat{
float w, x, y, z;
Quat(){
reset();
}
Quat(float w, float x, float y, float z){
this.w = w;
this.x = x;
this.y = y;
this.z = z;
}
void reset(){
w = 1.0f;
x = 0.0f;
y = 0.0f;
z = 0.0f;
}
void set(float w, Vec3 v){
this.w = w;
x = v.x;
y = v.y;
z = v.z;
}
void set(Quat q){
w = q.w;
x = q.x;
y = q.y;
z = q.z;
}
static Quat mul(Quat q1, Quat q2){
Quat res = new Quat();
res.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
res.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
res.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z;
res.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x;
return res;
}
float[] getValue(){
// transforming this quat into an angle and an axis vector...
float[] res = new float[4];
float sa = (float) Math.sqrt(1.0f - w * w);
if (sa < EPSILON){
sa = 1.0f;
}
res[0] = (float) Math.acos(w) * 2.0f;
res[1] = x / sa;
res[2] = y / sa;
res[3] = z / sa;
return res;
}
}
keep track of the floating error margin to return same number of degrees arcball.rollforward()
void rollforward(float radians2turn) {
rotatebywithincludedfloaterror = rotatebywithincludedfloaterror + (-1 * (((sin(radians2turn) * radius))/2));
if(degreeW_count >= 360) {
arcball.rollback(rotatebywithincludedfloaterror);
degreeW_count = 0;
rotatebywithincludedfloaterror = 0;
}
rollortilt(0, -1 * (((sin(radians2turn) * radius))/2));
degreeW_count = degreeW_count + 1; // need to edit this later to work with rotations other then 1 degree
}
using my idea in the question to reset every 2*PI
if(keys[w]) {
arcball.rollforward(PI/180);
degreeW_count = degreeW_count + 1;
}
if(degreeW_count == 360) {
arcball = new Arcball(width/2, height/2, 100); // setset to original arcball at 0 degrees
degreeW_count = 0;
}
in arcball
void rollforward(float degrees2turn) {
rollortilt(0, -1 * (((sin(degrees2turn) * radius))/2)); // one degree forward 180/PI
}
this totally circumvents the any rounding error that would accumulate with any data type using irrational numbers and periodic functions!
I want to create a button which is a circle but has a triangle in the middle.
For a send button. I tried using xml and drawable but there are always problems when it comes to screensize and views are not centered always etc..
So how can I do that using just a canvas?
Like how do I get the points I need to draw, say, given the radius of circle, and a scale of sorts, give me points for the triangle and draw the circle.
Here is a image of what I want
I recently created something very similar to what you want..
Take a look at this: https://www.desmos.com/calculator/2wpnxwwnty
To see how the math/scaling works.
This is the class which resulted:
public class TriangleInscribedCircle {
private Triangle inscribedTriangle;
private double s = 1;
private double r = 100;
public TriangleInscribedCircle(float radius, float scale) {
setScale(scale);
this.r = radius;
calculateTriangle();
}
public Triangle getInscribedTriangle() {
return this.inscribedTriangle;
}
public double getScale() {
return this.s;
}
public void setScale(double scale) {
if (scale < 0 || scale > 12) {
throw new IllegalArgumentException("Scale must be between 0 and 12.");
}
this.s = scale;
calculateTriangle();
}
public double getCircleRadius() {
return this.r;
}
public void setCircleRadius(double radius) {
this.r = radius;
calculateTriangle();
}
private void calculateTriangle() {
double u = -((r) / (s + 1)) + r;
double x = (6 * u + 10 * r - Math.sqrt(36 * Math.pow(r, 2) + 24 * r * u - 12 * Math.pow(u, 2))) / (8);
double ax = x;
double ay = -Math.tan(Math.toRadians(30)) * (x - 2 * r + u) + r;
double bx = -u + 2 * r;
double by = r;
double cx = x;
double cy = Math.tan(Math.toRadians(30)) * (x - 2 * r + u) + r;
Point a = new Point(ax, ay);
Point b = new Point(bx, by);
Point c = new Point(cx, cy);
if (this.inscribedTriangle == null) {
this.inscribedTriangle = new Triangle(a, b, c);
} else {
this.inscribedTriangle.setA(a);
this.inscribedTriangle.setB(b);
this.inscribedTriangle.setC(c);
}
}
}
then inside your custom view
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
int radius = width / 2;
canvas.drawCircle(width / 2, height / 2, radius, mTextFieldEmpty ? mCircleDisabledPaint : mCirclePaint);
canvas.drawPath(mTrianglePath, mTextFieldEmpty ? mTriangleDisabledPaint : mTrianglePaint);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mTriangle = new TriangleInscribedCircle(w / 2, 1);
calculatePath();
}
private void calculatePath() {
mTrianglePath.reset();
mTrianglePath.moveTo((int) mTriangle.getInscribedTriangle().getA().x, (int) mTriangle.getInscribedTriangle().getA().y);
mTrianglePath.lineTo((int) mTriangle.getInscribedTriangle().getB().x, (int) mTriangle.getInscribedTriangle().getB().y);
mTrianglePath.lineTo((int) mTriangle.getInscribedTriangle().getC().x, (int) mTriangle.getInscribedTriangle().getC().y);
mTrianglePath.lineTo((int) mTriangle.getInscribedTriangle().getA().x, (int) mTriangle.getInscribedTriangle().getA().y);
}
I need to create a GUI for a game and I will need to display on the screen the weapon and the shield. I need to modify the program so it displays the weapon and shield, however their properties are in another class. I know I will have to extend the JPanel class and overrite its paintComponent() method.
public class GraphicsUtil {
private static final int MUZZLE_FRACTION = 3;
private static final Color MUZZLE_COLOR = Color.MAGENTA;
public static void drawShield(IShield shield, Graphics g, GameSpace gameSpace, double origHealth) {
drawPiece(shield, g, gameSpace, origHealth);
}
public static void drawWeapon(IWeapon weapon, Graphics g,
GameSpace gameSpace, double origHealth) {
Color oldColor = g.getColor();
drawPiece(weapon, g, gameSpace, origHealth);
double orientation = weapon.getOrientation();
int x1 = gameSpace.convertToScreenX(weapon.getXPos());
int y1 = gameSpace.convertToScreenY(weapon.getYPos());
int radius = gameSpace.convertToScreenDistance(weapon.getRadius());
int x2 = gameSpace.convertToScreenX(weapon.getXPos()
+ weapon.getRadius() * Math.cos(weapon.getOrientation()));
int y2 = gameSpace.convertToScreenY(weapon.getYPos()
+ weapon.getRadius() * Math.sin(weapon.getOrientation()));
double frac = 1 - 1f / MUZZLE_FRACTION;
int muzzleCentreX
= x1 + (int) Math.round(frac * radius * Math.cos(orientation));
int muzzleCentreY
= y1 - (int) Math.round(frac * radius * Math.sin(orientation));
int muzzleRadius = radius / MUZZLE_FRACTION;
int topMuzzleX = muzzleCentreX - muzzleRadius;
int topMuzzleY = muzzleCentreY - muzzleRadius;
g.setColor(MUZZLE_COLOR);
g.fillOval(topMuzzleX, topMuzzleY, 2 * muzzleRadius, 2 * muzzleRadius);
g.setColor(Color.BLACK);
g.drawLine(x1, y1, x2, y2);
g.setColor(oldColor);
}
public static boolean isInMuzzle(IPiece piece, double x, double y) {
boolean result;
if (piece instanceof IWeapon) {
IWeapon weapon = (IWeapon) piece;
double radius = weapon.getRadius();
double orientation = weapon.getOrientation();
double frac = 1 - 1f / MUZZLE_FRACTION;
double cx = piece.getXPos() + frac * radius * Math.cos(orientation);
double cy = piece.getYPos() + frac * radius * Math.sin(orientation);
double dx = x - cx;
double dy = y - cy;
double dist = Math.sqrt(dx * dx + dy * dy);
result = dist <= radius / MUZZLE_FRACTION;
} else {
result = false;
}
return result;
}
public static double getAngle(double x1, double y1, double x2, double y2) {
double dx = x2 - x1;
double dy = y2 - y1;
double hypotenuse = Math.sqrt(dx * dx + dy * dy);
double angle;
if (dy > 0) {
angle = Math.acos(dx / hypotenuse);
} else {
angle = 2 * Math.PI - Math.acos(dx / hypotenuse);
}
return angle;
}
private static void drawPiece(IPiece piece, Graphics g, GameSpace gameSpace,
double maxHealth) {
Color oldColor = g.getColor();
int centreX = gameSpace.convertToScreenX(piece.getXPos());
int centreY = gameSpace.convertToScreenY(piece.getYPos());
int displayRadius = gameSpace.convertToScreenDistance(piece.getRadius());
int topX = centreX - displayRadius;
int topY = centreY - displayRadius;
if (piece.getOwner() == 0) {
g.setColor(Color.CYAN);
} else {
g.setColor(Color.PINK);
}
g.drawOval(topX, topY, 2 * displayRadius, 2 * displayRadius);
int healthRadius
= (int) Math.round(displayRadius * piece.getHealth() / maxHealth);
int topHealthX = centreX - healthRadius;
int topHealthY = centreY - healthRadius;
g.fillOval(topHealthX, topHealthY, 2 * healthRadius, 2 * healthRadius);
String name = piece.getName();
if (name != null) {
g.setColor(Color.BLACK);
g.drawString(name, centreX, centreY);
}
g.setColor(oldColor);
}
}
This is my main method:
public class Main extends JPanel {
public Main(){
setSize(new Dimension(400,400));
setPreferredSize(new Dimension(400,400));
GraphicsUtil object = new GraphicsUtil();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
}
public static void main(String[] args) {
Main window = new Main();
JFrame frame = new JFrame("RICOCHET");
frame.add(window);
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
How do I call those methods? What do I need to do in order to they appear in my frame? Thanks.
Presumably you have created one or more weapons or pieces. In your paintComponent() method, just call
GraphicsUtil.drawWeapon( myWeapon, g, ... );
I have a point following the path of a circle, and at a determined time, I want that point to "break" off and travel along the tangent line. How do I find this? I've been told that the derivative is
x = -sin(time)
and
y = -sin(time)
(not sure if I understand the "time" part of what I was told), but I don't see how that is enough to get my point to travel along this line. Any tips? Here is what I have currently.
/*
Rotor draws circle for random period of time, then moves
in a straight direction for a random period of time, beginning a
new circle
*/
Rotor r;
float timer = 0;
boolean freeze = false;
void setup() {
size(1000, 600);
smooth();
noFill();
frameRate(60);
background(255);
timeLimit();
r = new Rotor(100, 100, random(40, 100));
}
void draw() {
timer = timer + frameRate/1000;
if(timer > timeLimit()) {
timer = 0;
timeLimit();
if(freeze == true) {
freeze = false;
} else {
freeze = true;
}
}
if(!freeze) {
r.drawRotor();
} else {
r.holdSteady();
}
}
float timeLimit() {
float timeLimit = random(100);
return timeLimit;
}
Rotor Class:
class Rotor {
color c;
int thickness;
float xPoint;
float yPoint;
float nXPoint;
float nYPoint;
float radius;
float angle = 0;
float centerX;
float centerY;
float pointSpeed = frameRate/100;
Rotor(float cX, float cY, float rad) {
c = color(0);
thickness = 1;
stroke(c);
strokeWeight(thickness);
centerX = cX;
centerY = cY;
radius = rad;
}
void drawRotor() {
angle = angle + pointSpeed;
xPoint = centerX + cos(angle) * radius;
yPoint = centerY + sin(angle) * radius;
ellipse(xPoint, yPoint, thickness, thickness);
strokeWeight(2);
ellipse(centerX, centerY, 5, 5);
}
void holdSteady() {
xPoint = -sin(angle);//need tangent of circle
yPoint = -cos(angle);
ellipse(xPoint, yPoint, 4, 4);
//then set new center x and y
}
void drawNewRotor(float cX, float cy, float rad) {
}
}
You can use tan()
int f =100;
size(300,300);
stroke(0);
translate(width/2, height/2);
for(int i = 0; i< 360; i++){
point(cos(radians(i))*f,sin(radians(i))*f);
point(f,tan(radians(i))*f);
point(tan(radians(i))*f,f);
}
I have a two image that moves in a random direction. Now, if that images would bump each other I want it to disappear and that is my problem about making a collision detection. Could someone help me about this problem?
Here is the code:
public class HumanBeing extends Sprite implements ImageObserver
{
private java.awt.Image humanImage;
private final World world;
private double x;
private double y;
private double speed;
private double direction = 1;
private java.util.List<Sprite> objects = new ArrayList<Sprite>();
private double angle;
public HumanBeing(World world, double x, double y, double speed)
{
this.world =world;
this.x = x;
this.y = y;
this.speed = convertToMeterPerSecond(speed);
URL iU = this.getClass().getResource("human.jpg");
ImageIcon icon = new ImageIcon(iU);
humanImage = icon.getImage();
objects.add(this);
}
public Image getImage()
{
return humanImage;
}
#Override
public void move(long dt)
{
double dt_s = dt / 1e9;
double dx_m = speed * dt_s * Math.sin(angle);
double dy_m = speed * dt_s * Math.cos(angle);
final double right_wall = world.x1_world;
final double up_wall = world.y1_world;
final double down_wall = 0.0;
final double left_wall = 0.0;
x += dx_m;
y += dy_m;
if (x >= right_wall)
{
setRandomDirection();
}
if (y > up_wall)
{
setRandomDirection();
}
if (x <= left_wall)
{
setRandomDirection();
}
if (y < down_wall)
{
setRandomDirection();
}
}
public void setRandomDirection()
{
HumanBeing humanbeing = this;
humanbeing.setAngle(Math.PI * 2 * Math.random());
}
#Override
public void render(Graphics2D g2d)
{
AffineTransform t = g2d.getTransform();
final double humanHeight = 1.6;// meter
final double humanWidth = 1.8; //meter
final double foot_position_y = humanHeight;
final double foot_position_x = humanWidth / 2;
int xx = world.convertToPixelX(x - foot_position_x); // to find the upper-left corner
int yy = world.convertToPixelY(y + foot_position_y); // to find the upper-left corner
g2d.translate(xx, yy);
// ratio for actual Image size
double x_expected_pixels = humanHeight * board.meter;
double y_expected_pixels = humanWidth * board.meter;
double w = ((ToolkitImage) humanImage).getWidth();
double h = ((ToolkitImage) humanImage).getHeight();
double x_s = x_expected_pixels / w;
double y_s = y_expected_pixels / h;
g2d.scale(x_s, y_s);
g2d.drawImage(getImage(), 0, 0, this); // upper left corner
g2d.setColor(Color.BLACK);
g2d.setTransform(t);
}
#Override
public void moveAt(double distance_x, double distance_y)
{
this.x = distance_x;
this.y = distance_y;
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
return false;
}
public void setAngle(double angle)
{
this.angle = angle;
}
}
this is my HumanBeing class
public class Chicken extends Sprite implements ImageObserver
{
private java.awt.Image chickenImage;
private final World world;
private double x;
private double y;
private double speed;
private double angle;
public Chicken(World world, double x, double y, double speed)
{
this.world = world;
this.x = x;
this.y = y;
this.speed = convertToMeterPerSecond(speed);
URL iU = this.getClass().getResource("chicken.gif");
ImageIcon icon = new ImageIcon(iU);
chickenImage = icon.getImage();
}
public Image getImage()
{
return chickenImage;
}
public void move(long dt)
{
double dt_s = dt / 1e9;
double dx_m = speed * dt_s * Math.sin(angle);
double dy_m = speed * dt_s * Math.cos(angle);
final double right_wall = world.x1_world;
final double up_wall = world.y1_world;
final double down_wall = 0.0;
final double left_wall = 0.0;
x += dx_m;
y += dy_m;
if (x >= right_wall)
{
x = right_wall;
setRandomDirection();
}
if (y > up_wall)
{
y = up_wall;
setRandomDirection();
}
if (x <= left_wall)
{
x = left_wall;
setRandomDirection();
}
if (y < down_wall)
{
y = down_wall;
setRandomDirection();
}
}
public void setRandomDirection()
{
Chicken chicken = this;
chicken.setAngle(Math.PI * 2 * Math.random());
}
#Override
public void render(Graphics2D g2d)
{
AffineTransform t = g2d.getTransform();
double height = 0.3; //meter
double width = 0.3; //meter
double chicken_footy = height;
double chicken_footx = width/2;
int xx = world.convertToPixelX(x - chicken_footx);
int yy = world.convertToPixelY(y + chicken_footy);
g2d.translate(xx, yy);
double x_expected_pixels = width * board.meter;
double y_expected_pixels = height * board.meter;
double x_s = x_expected_pixels / ((ToolkitImage) chickenImage).getWidth();
double y_s = y_expected_pixels / ((ToolkitImage) chickenImage).getHeight();
g2d.scale(x_s, y_s);
g2d.drawImage(getImage(), 0, 0, this);
g2d.setColor(Color.BLACK);
g2d.setTransform(t);
}
public void moveAt(double distance_x, double distance_y)
{
this.x = (int) distance_x;
this.y = (int) distance_y;
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
return true;
}
public void setAngle(double angle)
{
this.angle = angle;
}
}
this is my chicken class
Draw invisible Rectangle around your sprites as like Box's and than use below method to check whether they are intersecting or not :)
http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Rectangle.html#intersects(java.awt.Rectangle)
if(rect.intersect(anotherRect))
{
disappear();
}
Good luck