So in my programming class we are learning to use draw classes. Basically draw a line and stuff and we did a y=mx+b line in class.
I wanted to jump ahead and start doing more crazy mathematical ones!
I'm having trouble using this one though, which I found on the U of Princeton website.
public class Spiral {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]); // # sides if decay = 1.0
double decay = Double.parseDouble(args[1]); // decay factor
double angle = 360.0 / N;
double step = Math.sin(Math.toRadians(angle/2.0));
Turtle turtle = new Turtle(0.5, 0.0, angle/2.0);
for (int i = 0; i < 10*N; i++) {
step /= decay;
turtle.goForward(step);
turtle.turnLeft(angle);
}
}
}
import java.awt.Color;
public class Turtle {
private double x, y; // turtle is at (x, y)
private double angle; // facing this many degrees counterclockwise from the x-axis
// start at (x0, y0), facing a0 degrees counterclockwise from the x-axis
public Turtle(double x0, double y0, double a0) {
x = x0;
y = y0;
angle = a0;
}
// rotate orientation delta degrees counterclockwise
public void turnLeft(double delta) {
angle += delta;
}
// move forward the given amount, with the pen down
public void goForward(double step) {
double oldx = x;
double oldy = y;
x += step * Math.cos(Math.toRadians(angle));
y += step * Math.sin(Math.toRadians(angle));
StdDraw.line(oldx, oldy, x, y);
}
// pause t milliseconds
public void pause(int t) {
StdDraw.show(t);
}
public void setPenColor(Color color) {
StdDraw.setPenColor(color);
}
public void setPenRadius(double radius) {
StdDraw.setPenRadius(radius);
}
public void setCanvasSize(int width, int height) {
StdDraw.setCanvasSize(width, height);
}
public void setXscale(double min, double max) {
StdDraw.setXscale(min, max);
}
public void setYscale(double min, double max) {
StdDraw.setYscale(min, max);
}
// sample client for testing
public static void main(String[] args) {
double x0 = 0.5;
double y0 = 0.0;
double a0 = 60.0;
double step = Math.sqrt(3)/2;
Turtle turtle = new Turtle(x0, y0, a0);
turtle.goForward(step);
turtle.turnLeft(120.0);
turtle.goForward(step);
turtle.turnLeft(120.0);
turtle.goForward(step);
turtle.turnLeft(120.0);
}
}
Turtle uses this class: StdDraw which is just way too many lines of code for me to paste here.
I keep getting an error when I go to execute spiral:
java.lang.ArrayIndexOutOfBoundsException: 0
at Spiral.main(Spiral.java:4)
Not sure why. Can anyone help me out so I can play around with this?
Did you specify two command-line arguments? It looks like it takes the number of steps and the decay as a parameter and will crash if you don't specify these.
For example:
java Spiral 10 1.1
Related
I have a simple class 2Dpoints with two fields, x and y. I want to write a code so that I could command one point to moves slowly to another point, like so that it moves on the vector line of their distances. But I don't know how?
I've first thought that it should contain a for loop so that it would know, it should move till it reaches the other point
something like for(int d=0 ; d<distance ; d++) but I don't know how should I then command it so that it would move on the line?
import java.lang.Math.*;
public class Punkt {
private int x;
private int y;
public Punkt(int x, int y) {
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int distance) {
x = x + distance;
}
public void setY(int distance) {
y = y + distance;
}
public void moveAbout(int dx, int dy) {
x = x + dx;
y = y + dy;
}
/// method for calculating the distance to another point
public double giveDistance(Punkt otherPoint) {
return Math.sqrt(
(otherPoint.getY() - y) *
(otherPoint.getY() - y) +
(otherPoint.getX() - x) *
(otherPoint.getX() - x));
}
}
I've commented the major lines:
import static java.lang.Math.*;
/**
* Immutable structure. Functional way
*/
class Point {
public final double x;
public final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
/**
* Here you are. This is what you want to implement.
* from.moveTo(0.0, to) => from
* from.moveTo(1.0, to) => to
*
* #param by - from 0.0 to 1.0 (from 0% to 100%)
* #param target - move toward target by delta
*/
public Point moveTo(double by, Point target) {
Point delta = target.sub(this);
return add(delta.dot(by));
}
public Point add(Point point) {
return new Point(x + point.x, y + point.y);
}
public Point sub(Point point) {
return new Point(x - point.x, y - point.y);
}
public Point dot(double v) {
return new Point(v * x, v * y);
}
public double dist(Point point) {
return sub(point).len();
}
public double len() {
return sqrt(x * x + y * y);
}
public String toString() {
return x + ":" + y;
}
}
class Main {
public static void main(String[] args) {
Point source = new Point(2, 3);
Point target = new Point(-4, 9);
// You can utilize the cycle or implement kind of timer to animate something
for (int t = 0; t <= 100; t++) {
System.out.println(source.moveTo(0.01 * t, target));
}
}
}
https://replit.com/join/sucvdhpqoa-redneckz
#AlexanderAlexandrov I've change the type of my variables to double accordingly, now in one of my classes I have a method givePoints, which uses Scanner for asking a user how many points he wants and what are the coordinates then it saves them into an array of points with first element being always(0,0).
Another method takes an array of points as parameter and sort them in order of their distances to point(0,0).
These methods work perfectly. The problem is with method hitThepoints.
Here I want to first create the array of points, sort them, and then command my robot to hit all the points. robot is an object of class Robot extends circle, with position of type Point, that at first is at point(0,0)
public void hitThePoints(){
Point[] poi=sortPoints (givePoints()); //Creates a sorted array of points
Point short=new Point(poi[1].getX(),poi[1].getY());
System.out.println(" the nearest point is :");
System.out.println("("+short.getX()+ ","+short.getY()+")");
for(int i=1; i<poi.length;i++){
Point source=robot.position;
Point target=new Point(poi[i].getX(), poi[i].getY());
while(source.getX()!=target.getX() &&
source.getY()!=target.getY()){
robot.bewegeUm((source.moveTo(0.01,target)).getX(),
(source.moveTo(0.01,target)).getY());
if(source.getX()!=target.getX() &&
source.getY()!=target.getY()){break;}
System.out.println(source.getX() +","+ source.getY());
}
}
}
I am making a pong type game in java and I am trying to make the ball bounce off of the walls but whenever the ball hits the ball it just stops, it does not reflect off of the wall and I can't seem to figure out why.
Ball class which handles the ball movement
public class Ball {
private double x;
private double y;
private double time;
private double xreflection=1.0;
private double yreflection=1.0;
private BallTrajectory traj=new BallTrajectory(20, 20);
public Ball(double x, double y) {
this.x=x;
this.y=y;
}
public void tick() {
time+=1.0/60.0;
if(x==0)
xreflection=1.0;
else if(x==Game.Width-15)
xreflection=-1.0;
if(y==0)
yreflection=1.0;
else if(y==Game.Height-15)
yreflection=-1.0;
x+=traj.xvel()*xreflection;
y-=traj.yvel(time)*yreflection;
}
public void render(Graphics g) {
g.setColor(Color.pink);
g.fillOval((int)x, (int)y, 15,15);
}
}
This class handles the trajectory of the ball as it moves in projectile type motion
public class BallTrajectory {
private double initvel;
private double theta;
public BallTrajectory(double initvel, double theta) {
this.initvel=initvel;
this.theta=theta;
}
public double xvel() {
double xvelo=initvel*Math.cos(Math.toRadians(theta));
return xvelo;
}
public double yvel(double time) {
double yvelo=initvel*Math.sin(Math.toRadians(theta))-(9.8*time);
return yvelo;
}
public double xpos(double time) {
double xpos=initvel*Math.cos(Math.toRadians(theta))*time;
return xpos;
}
public double ypos(double time) {
double ypos=initvel*Math.sin(Math.toRadians(theta))*time-.5*9.8*Math.pow(time, 2);
return ypos;
}
Without going through a whole bunch of testing, I would suggest that it is very unlikely that x will ever be exactly equal to Game.Width or 0. Instead, you should be testing that the value is "within bounds" instead, maybe something like...
public void tick() {
time += 1.0 / 60.0;
if (x <= 0) {
xreflection = 1.0;
} else if (x >= Game.Width - 15) {
xreflection = -1.0;
}
if (y <= 0) {
yreflection = 1.0;
} else if (y >= Game.Height - 15) {
yreflection = -1.0;
}
x += traj.xvel() * xreflection;
y -= traj.yvel(time) * yreflection;
}
You should also start taking the time to learn how to debug your code, it is something you will need to do a lot, from desk-checking your logic to using print statements and the debugger
I have an assignment explaining like this:
Write a definition of a class named Point that might be used to store and manipulate the location of a point on the plane. The point is stored as two coordinates: x and y. You will need to declare and implement the following methods:
Two constructors:
a. no-argument constructor that sets the point coordinates to (0,0), and
b. a constructor that takes x and y coordinate of the point and sets member
variables.
Method set that sets the private data after an object of this class is created.
A method to move the point by an amount along the vertical and horizontal directions specified by the first and second arguments: move(double dx, double dy)
The method to rotate the point by 90 degrees clockwise around the origin. Hint: when point is getting rotated 90 clockwise around the origin the following changes happen to its coordinates: xrotated = y; yrotated = -x .
two accessor methods to retrieve the coordinates of the point.
It should be 2 different call. these items on second one (not main class)
I will call this on main class. (I do that).
This is my code but I dont understand what I should do next.
private double x;
private double y;
public Point(double initialX, double initialY) {
x = initialX;
y = initialY;
}
public Point() {
x = 0;
y = 0;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public void move(double dx, double dy) {
x += dx;
y += dy;
}
You have almost everything, good job. For the rotate by 90 function, you're given a pretty good clue about what to do. Imagine you have a point (1,2), and you rotate it. you'll end up with (2,-1). if you rotate it again, you'll get (-1,-2). once more gives you (-2,1), and a fourth 90 degree rotation gives (1,2), which is what you started with. come up with a function that does this. It shouldn't be longer than 3 lines.
The setter functions (functions used to set, or change, the values) are simply functions you can use to set the values of the point. so, you'd have a function "setX(...) { ... }" and a function "setY(...) { ... }". These should be very straightforward.
Feel free to ask further questions if you're still confused.
private double x;
private double y;
public Point(double dx, double dy) {
x = dx;
y = dy;
}
public Point() {
x = 0;
y = 0;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public void SetX(double dx)
{
x = dx;
}
public void SetY(double dy)
{
y = dy;
}
public void move(double dx, double dy)
{
x = x + dx;
y = y + dy;
}
public double rotateX()
{
double temp = x;
x=y;
y=temp;
return x;
}
public double rotateY()
{
y=-y;
return y;
}
main page
public static void main(String[] args) {
// TODO Auto-generated method stub
Point p = new Point();
p.SetX(50);
p.SetY(17);
System.out.println("X and Y coordinates are : \n("+p.getX()+","+p.getY()+")");
System.out.println("after 90 degree clockwise rotate: ");
System.out.println(p.rotateX()+","+p.rotateY());
So I am trying to move a projectile in the direction that is indicated by the mouse position on the screen. I already have converted the mouse coordinates into in-game coordinates however I can't figure out how to correctly move the projectile into the proper direction. I am trying to use a slope to move the projectile but it doesn't seem to want to grab the correct slope so I end up with them flying in completely wrong directions. Here are some bits of code that I am using.
Any help on this would be greatly appreciated as I am a little over my head in this.
NOTE: The projectile does NOT follow the mouse. It should save the coordinates and then head in that direction noting that it can also go past the given coordinates at the same rate.
Entity Creation
int[] mousePos = MouseManager.getCalculatedMouseCoordinates();
float deltaX = mousePos[0] - GameManager.x;
float deltaY = mousePos[1] - GameManager.y;
float m = deltaY/deltaX;
System.out.println(m);
GameManager.currentWorld.addEntity(new EntityProjectile(GameManager.x, GameManager.y, 30, m, 50, "fireball"));
Projectile Class
package UnNamedRpg.Player.Entity;
public class EntityProjectile {
private double x, y;
private int entityID = -1;
private int speed;
private double headerX, headerY;
private int renderHeading;
private double range, currentRange = 0;
private String texture;
private double factor = -1;
public EntityProjectile(double startX, double startY, int speed, double headerX, double headerY, double range, String texture){
setX(startX);
setY(startY);
setSpeed(speed);
setHeaderX(headerX);
setHeaderY(headerY);
setTexture(texture);
setRange(range);
}
public void doTick(){
double vx = this.x - this.headerX;
double vy = this.y - this.headerY;
if(this.factor == -1){
double length = Math.sqrt((vx*vx) + (vy*vy));
double factor = this.speed / length;
this.factor = factor;
}
vx *= factor;
vy *= factor;
this.x = vx;
this.y = vy;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public int getRenderHeading() {
return renderHeading;
}
public void setRenderHeading(int renderHeading) {
this.renderHeading = renderHeading;
}
public int getEntityID() {
return entityID;
}
public void setEntityID(int entityID) {
this.entityID = entityID;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public String getTexture() {
return texture;
}
public void setTexture(String texture) {
this.texture = texture;
}
public double getRange() {
return range;
}
public void setRange(double range) {
this.range = range;
}
public double getCurrentRange() {
return currentRange;
}
public void setCurrentRange(double currentRange) {
this.currentRange = currentRange;
}
public double getHeaderX() {
return headerX;
}
public void setHeaderX(double headerX) {
this.headerX = headerX;
}
public double getHeaderY() {
return headerY;
}
public void setHeaderY(double headerY) {
this.headerY = headerY;
}
public double getFactor() {
return factor;
}
public void setFactor(double factor) {
this.factor = factor;
}
}
Update Position Method
--Now called in EntityProjectile class every tick instead of it happening in the world tick.
Moving towards a given point is relatively simple with some basic vector math. The vector you want to move along is calculated simply by coordinate subtraction:
vx = objectX - mouseX
vy = objectY - mouseY
But you probably want to move your object a little slower than bam there, so you need to scale the vector to a desired length (equals speed per game tick). The current length of the vector is obtained by the pythagorean sqrt(a * a + b * b). To scale the vector to a given length just multiply the components by the required factor:
double targetLength = 5.0; // chosen arbitrarily
double length = Math.sqrt(vx * vx + vy * vy);
double factor = targetLength / length;
vx *= factor;
vy *= factor;
There you have your speed components x,y to be used as delta per game tick. The 5.0 is the "speed" at which the object will move per tick.
EDIT: #Cyphereion About the length of the vector, thats geometrically speaking the base of a triangle, see https://en.wikipedia.org/wiki/Pythagorean_theorem (considered common knowlegde).
Once you have that, you just need to adjust the length of each component by figuring out a scaling factor that makes the base line come out as the desired "speed" length. The original values of the components (vx, vy) represent a vector (see: https://en.wikipedia.org/wiki/Euclidean_vector#Representations) encoding the direction to move to.
Scaling the vector's length adjusts the speed at which your object moves when you apply the vectors components as delta to its position (which is just vector addition). I swapped around the division length/targetLength initailly (now fixed), so the speed variable had a reversed meaning (larger = slower instead of larger = faster).
If you're having trouble with your sprite then use the setDirection() you have there to augment the trajectory. In these examples you have all good code but you're missing restting the direction when your mouse changes direction. That's all I can see. Good luck!
I created a simple Application which is meant to display, in 2D, dots which are hypothetically on a 3D plane (these points are of type Vector, written below). The class uses the XYZ Coordinates of the Camera and the XYZ Coordinates of the Vector, and uses that information to quickly translate the Vector XYZ Coordinates into XY Coordinates.
The only class needed in this question is the Vector class given below. All other classes used are omitted because they essentially fire mouse movements and redraw the frame.
--My concern is that, as the camera moves, the Vector points jump around as if the formula that I'm using is totally unreliable. Are these formulas (found under Perspective Projection) completely incorrect? The use of those formulas can be found within my set2D method. Am I doing something completely wrong, skipping steps, or perhaps have I translated the formula into code incorrectly?
Thanks!
import java.awt.Color;
import java.awt.Graphics;
public class Vector
{
private int cX, cY, cZ; //Camera Coordinates
private int aX, aY, aZ; //Object Coordinates
private double bX, bY; //3D to 2D Plane Coordinates
public Vector(int aX, int aY, int aZ, int cX, int cY, int cZ)
{
this.aX = aX;
this.aY = aY;
this.aZ = aZ;
this.cX = cX;
this.cY = cY;
this.cY = cZ;
set2D();
}
//SETS
public void setCameraX(int cX)
{
this.cX = cX;
set2D();
}
public void setCameraY(int cY)
{
this.cY = cY;
set2D();
}
public void setCameraZ(int cZ)
{
this.cZ = cZ;
set2D();
}
public void setCameraXYZ(int cX, int cY, int cZ)
{
setCameraX(cX);
setCameraY(cY);
setCameraZ(cZ);
}
public void setObjX(int x)
{
this.aX = x;
}
public void setObjY(int y)
{
this.aY = y;
}
public void setObjZ(int z)
{
this.aZ = z;
}
public void setObjXYZ(int x, int y, int z)
{
this.aX = x;
this.aY = y;
this.aZ = z;
}
public void set2D()
{
//---
//the viewer's position relative to the display surface which goes through point C representing the camera.
double eX = aX - cX;
double eY = aY - cY;
double eZ = aZ - cZ;
//----
double cosX = Math.cos(eX);
double cosY = Math.cos(eY);
double cosZ = Math.cos(eZ);
double sinX = Math.sin(eX);
double sinY = Math.sin(eY);
double sinZ = Math.sin(eZ);
//---
//The position of point A with respect to a coordinate system defined by the camera, with origin in C and rotated by Theta with respect to the initial coordinate system.
double dX = ((cosY*sinZ*eY) + (cosY*cosZ*eX)) - (sinY * eZ);
double dY = ((sinX*cosY*eZ) + (sinX*sinY*sinZ*eY) + (sinX*sinY*cosZ*eX)) + ((cosX*cosZ*eY) - (cosX*sinZ*eX));
double dZ = ((cosX*cosY*eZ) + (cosX*sinY*sinZ*eY) + (cosX*sinY*cosZ*eX)) - ((-sinX*cosZ*eY) - (-sinX*sinZ*eX));
//---
//---
//The 2D projection coordinates of the 3D object
bX = (int)(((eZ / dZ) * dX) - eX);
bY = (int)(((eZ / dZ) * dY) - eY);
//---
System.out.println(bX + " " + bY);
}
//GETS
public int getCameraX()
{
return cX;
}
public int getCameraY()
{
return cY;
}
public int getCameraZ()
{
return cZ;
}
public int getObjX()
{
return aX;
}
public int getObjY()
{
return aY;
}
public int getObjZ()
{
return aY;
}
public int get2DX()
{
return (int)bX;
}
public int get2DY()
{
return (int)bY;
}
//DRAW
public void draw(Graphics g)
{
g.setColor(Color.red);
g.fillOval((int)bX, (int)bY, 3, 3);
}
//TO STRING
public String toString()
{
return (aX + " " + aY + " " + aZ);
}
}
The following line of your code does not match with the formula you are using:
double dZ = ((cosX*cosY*eZ) + (cosX*sinY*sinZ*eY) + (cosX*sinY*cosZ*eX)) - ((-sinX*cosZ*eY) - (-sinX*sinZ*eX));
Notice the part - ((-sinX*cosZ*eY) - (-sinX*sinZ*eX))
This should be - ((sinX*cosZ*eY) - (sinX*sinZ*eX))
Since if you take sinX and multiply it, the -ve sign stays outside. If however you multiple -sinX then the sign outside the brackets should become +ve.