Draw line function - java

I want to create a drawLine function, however I am not able to use any graphics classes (I can set pixels though). I tried this method https://en.wikipedia.org/wiki/Bresenham's_line_algorithm#Method, but this only works when the line is going from top left to bottom right and not for example going from top right to bottom left. Does anyone have a way that does this? The current code I have:
public void drawLine(int startX, int startY, int endX, int endY) {
double deltaX = endX - startX;
double deltaY = endY - startY;
double error = -1;
double deltaError = Math.abs(deltaY / deltaX);
int y = startY;
for (int x = startX; x < endX - 1; x++) {
error += deltaError;
if (error >= 0) {
y++;
error--;
}
drawPixel(x, y);
}
}
Any help is appreciated.
I solved it. The end result is this.
public void drawLine(int startX, int startY, int endX, int endY) {
if (startX > endX && startY > endY) {
int startXCopy = startX;
startX = endX;
endX = startXCopy;
int startYCopy = startY;
startY = endY;
endY = startYCopy;
}
double deltaX = endX - startX;
double deltaY = endY - startY;
double error = -1;
double deltaError = Math.abs(deltaY / deltaX);
if (deltaX == 0) {
for (int y = startY; y < endY; y++)
drawPixel(startX, y);
}
if (deltaY == 0) {
for (int x = startX; x < endX; x++)
drawPixel(x, startY);
}
if (deltaX >= deltaY) {
int y = startY;
int yDirection = endY > startY ? 1 : -1;
for (int x = startX; x < endX - 1; x++) {
error += deltaError;
if (error >= 0) {
y += yDirection;
error--;
}
drawPixel(x, y);
}
} else if (deltaY > deltaX) {
int x = startX;
int xDirection = endX > startX ? 1 : -1;
for (int y = startY; y < endY - 1; y++) {
error += deltaError;
if (error >= 0) {
x += xDirection;
error--;
}
drawPixel(x, y);
}
}
}

To draw a line is a simple Math problem and can be achieved on different ways.
What you need is the basic linear euqation y = f(x) = mx + b
where m is your slope, defined as m=(y2−y1)/(x2−x1), bis your startY value and the x is expressed by x = x_i - startX where x_i is your current point on your line. Then you can compute all y-values for each x_i value on the line between your start point and your end point. The quantity of points depends on a resolution factor.
double slope = (double)(endY - startY) / (endX - startX);
//adjustable resolution factor
double resolution = 1;
double x = startX;
while (x <= endX) {
double y = slope * (x - startX) + startY;
drawPixel(x, y);
x += resolution;
}

Related

Java in Processing: Make a circle go clockwise around the window endlessly

My current code shows a circle that goes around the window once in a clockwise rotation, and then moves off the screen in the upper right corner when it's making its way around a second time. How can I edit my code, so the circle continues to go around the screen endlessly and never moves off the edge?
// cirlce radius
final int radius = 25;
// circle x position
int xPos = 15;
int yPos = 15;
int xDir = 4;
int yDir = 0;
void setup()
{
size(500, 500);
background(177, 237, 247);
}
void draw()
{
background(177, 237, 247);
ellipse(xPos, yPos, radius, radius);
xPos = xPos + xDir;
yPos = yPos + yDir;
if (xPos > width - 15) {
yDir = 4;
xDir = 0;
} if (yPos > height - 15) {
xDir = -4;
yDir = 0;
} if (xPos < width - 485) {
xDir = 0;
yDir = -4;
} if (yPos < height - 485) {
yDir = 0;
xDir = 4;
}
}
The 3rd and 4th argument of ellipse are the length of the axis, instead of the length of the semi axis. Therefore you need to multiple the radius by 2.
When the ellipse reaches an edge, you need to limit the position of the ellipse by the edge:
// cirlce radius
final int radius = 25;
// circle x position
int xPos = radius;
int yPos = radius;
int xDir = 4;
int yDir = 0;
void setup() {
size(500, 500);
background(177, 237, 247);
}
void draw()
{
background(177, 237, 247);
ellipse(xPos, yPos, radius*2, radius*2);
xPos = xPos + xDir;
yPos = yPos + yDir;
if (xPos > width - radius) {
xPos = width - radius;
yDir = 4;
xDir = 0;
}
if (yPos > height - radius) {
yPos = height - radius;
xDir = -4;
yDir = 0;
}
if (xPos < radius) {
xPos = radius;
xDir = 0;
yDir = -4;
}
if (yPos < radius) {
yPos = radius;
yDir = 0;
xDir = 4;
}
}

Aiming in LibGDX using the mouse

I am making a game in libGDX and I am having trouble setting up the Bullet class. I am unable to get the projectiles to go to the mouse location.
I have tried to use Math.atan() to find the angle that I need to fire at but I couldn't get that to work. right now I am just using the distance to find velocity on the x and y-axis.
private static final int SPEED = 500;
private static Texture texture;
String path = "C:\\Users\\minicodcraft\\Downloads\\game\\core\\assets\\";
private float x, y; // starting position
private float xVelocity, yVelocity;
private float yPos; // the y position of the mouse input
private float xPos; // the x position of the mouse input
public Bullet(float x, float y, float yPos, float xPos) {
this.x = x;
this.y = y;
this.xPos = xPos;
this.yPos = yPos;
this.xVelocity = 0f;
this.yVelocity = 0f;
calcDirection();
if (texture == null) {
texture = new Texture(path + "Bullet.png");
}
}
private void calcDirection() {
float xDistanceFromTarget = Math.abs(xPos - x);
float yDistanceFromTarget = Math.abs(yPos - y);
float totalDistanceFromTarget = xDistanceFromTarget + yDistanceFromTarget;
xVelocity = xDistanceFromTarget / totalDistanceFromTarget;
yVelocity = yDistanceFromTarget / totalDistanceFromTarget;
if (xPos < x) {
xVelocity *= -1;
}
if (yPos < y) {
yVelocity *= -1;
}
}
public void update(float deltaTime) {
if (x > 0 && y > 0) {
x += xVelocity * SPEED * deltaTime;
y += yVelocity * SPEED * deltaTime;
} else if (x < 0 && y > 0) {
x -= xVelocity * SPEED * deltaTime;
y += yVelocity * SPEED * deltaTime;
} else if (x > 0 && y < 0) {
x += xVelocity * SPEED * deltaTime;
y -= yVelocity * SPEED * deltaTime;
} else if (x < 0 && y < 0) {
x -= xVelocity * SPEED * deltaTime;
y -= yVelocity * SPEED * deltaTime;
}
}
public void render(SpriteBatch batch) {
batch.draw(texture, x, y);
}
The following code gives a velocity towards the mouse position from the player's position:
float diffX = mouse.x - player.x;
float diffY = mouse.y - player.y;
float angle = (float) Math.atan2(diffY, diffX);
float velX = (float) (Math.cos(angle));
float velY = (float) (Math.sin(angle));
Vector2 velocity = new Vector2(velX, -velY);
velocity.nor();
velocity.scl(magnitudeSpeed);
velocity.scl(deltaTime);
Then velocity.x is the x component of the velocity. Respective for y. No need to multiply by speed and deltaTime again, already done above.

Having trouble drawing a square grid for an android game

I would like for this to display as a 7 x 7 square grid in the centre of the screen, however as you can see with my current code the vertical lines are in the correct positions but the horizontal ones are not. I am sure this is a simple fix and any help would be appreciated -
public class GameGrid extends View {
Paint black = new Paint();
public GameGrid(Context context) {
super(context);
black.setColor(Color.BLACK);
black.setStrokeWidth(8);
}
#Override
public void onDraw(Canvas canvas) {
float startX;
float stopX;
float startY;
float stopY;
int width = canvas.getWidth();
int height = canvas.getHeight();
int gridSize = 7;
int gridSpacing = width / gridSize;
//Vertical Grid-lines
for (int i = 0; i < gridSize; i++) {
startX = width / 2 - height / 2;
stopX = width / 2 + height / 2;
startY = i*gridSpacing;
stopY = i*gridSpacing;
canvas.drawLine(startX, startY, stopX, stopY, black);
}
//Horizontal Grid-lines
for (int i = 0; i < gridSize; i++) {
startX = i*gridSpacing;
stopX = i*gridSpacing;
startY = height / 2 - width / 2;
stopY = height / 2 + width / 2;
canvas.drawLine(startX, startY, stopX, stopY, black);
}
}
Picture of what grid currently looks like
You are missing the offset (on both axis). Why you don't pre-calculate xOffset and yOffset and the start to paint based on the point (xOffset, yOffset)?
something like this:
#Override
public void onDraw(Canvas canvas) {
float startX;
float stopX;
float startY;
float stopY;
int width = canvas.getWidth();
int height = canvas.getHeight();
int gridSize = 7;
int gridSpacing = Math.min(width, height) / gridSize;
int boardSize = gridSize * gridSpacing;
int xOffset = (width - boardSize)/2;
int yOffset = (height - boardSize)/2;
//Vertical Grid-lines
for (int i = 0; i < gridSize; i++) {
startX = xOffset + i*gridSpacing;
startY = yOffset;
stopX = startX;
stopY = startY + boardSize;
canvas.drawLine(startX, startY, stopX, stopY, black);
}
//Horizontal Grid-lines
for (int i = 0; i < gridSize; i++) {
startX = xOffset;
startY = yOffset + i*gridSpacing;
stopX = startX + boardSize;
stopY = startY;
canvas.drawLine(startX, startY, stopX, stopY, black);
}
}
If you want to make sure that will be always centered (e.g. in landscape ) you should set:
int gridSpacing = Math.min(width, height) / gridSize;
I'd GUESS the problem is that the canvas isn't square? Height is greater than width.
Thus in the vertical Gridlines
startX = width / 2 - height / 2;
gives a negative number and puts the starting point to the left off-screen. It looks fine, but the length is wrong.
For the horizontal Gridlines
startY = height / 2 - width / 2;
is a positive number and you start partway down the screen. Similarly, the endY value overshoots by some amount (note the horizontal gridlines are longer than the vertical gridlines as well as being offset downward)
Perhaps try
//Horizontal Y vals
startY = 0;
stopY = height;

processing FrameBuffer Error

I am trying to make a processing program, but if I use P2D, P3D, or OPENGL mode I get an error:
com.sun.jdi.VMDisconnectedException
at com.sun.tools.jdi.TargetVM.waitForReply(TargetVM.java:285)
at com.sun.tools.jdi.VirtualMachineImpl.waitForTargetReply(VirtualMachineImpl.java:1015)
at com.sun.tools.jdi.PacketStream.waitForReply(PacketStream.java:51)
at com.sun.tools.jdi.JDWP$ObjectReference$InvokeMethod.waitForReply(JDWP.java:4589)
at com.sun.tools.jdi.ObjectReferenceImpl.invokeMethod(ObjectReferenceImpl.java:374)
at processing.mode.java.runner.Runner.findException(Runner.java:701)
at processing.mode.java.runner.Runner.reportException(Runner.java:652)
at processing.mode.java.runner.Runner.exception(Runner.java:595)
at processing.mode.java.runner.EventThread.exceptionEvent(EventThread.java:367)
at processing.mode.java.runner.EventThread.handleEvent(EventThread.java:255)
at processing.mode.java.runner.EventThread.run(EventThread.java:89)
the error message itself varies between P2D and P3D, but they both get a no framebuffer objects available error. I am using processing 2.0b7, please help and let me know if you need more info.
Note: I don't know if this is a separate issue or not, but I am also getting GLSL shader errors to.
Now, here is my code:
Cell[][] Cells = new Cell[50][50];
byte Direction = 1;
byte Times = 1;
int oldwidth = 500;
int oldheight = 500;
void setup() {
size(oldwidth, oldheight, OPENGL);
background(255);
colorMode(HSB,250);
for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) {
Cells[x][y] = new Cell(x * 5, y * 5, 255, x * (width / 50), y * (height / 50), width / 50, height / 50);
}
}
}
void draw() {
for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) {
if (width == oldwidth) Cells[x][y].Width = width / 50;
if (height == oldheight) Cells[x][y].Height = height / 50;
if (Direction == 1){
Cells[x][y].Hue += 5;
if (Cells[x][y].Hue > 250) Cells[x][y].Hue -= 250;
}
if (Direction == 2){
Cells[x][y].Saturation -= 5;
if (Cells[x][y].Saturation < 0) Cells[x][y].Saturation += 500;
}
if (Direction == 3){
Cells[x][y].Hue -= 5;
if (Cells[x][y].Hue < 0) Cells[x][y].Hue += 250;
}
if (Direction == 4){
Cells[x][y].Saturation += 5;
if (Cells[x][y].Saturation > 500) Cells[x][y].Saturation -= 500;
}
Cells[x][y].Draw();
}
}
if (Times == 50){
Times = 1;
if (Direction == 4) Direction = 1; else Direction += 1;
} else Times += 1;
delay(10);
}
class Cell {
int X;
int Y;
int Width;
int Height;
float Hue;
float Saturation;
float Brightness;
Cell(color parC, int parX, int parY, int parWidth, int parHeight) {
Hue = hue(parC);
Saturation = saturation(parC);
Brightness = brightness(parC);
X = parX;
Y = parY;
Width = parWidth;
Height = parHeight;
}
Cell(float parHue, float parSaturation, float parBrightness, int parX, int parY, int parWidth, int parHeight) {
Hue = parHue;
Saturation = parSaturation;
Brightness = parBrightness;
X = parX;
Y = parY;
Width = parWidth;
Height = parHeight;
}
void Draw() {
if (Saturation > 250) if (Saturation > 500) stroke(color(Hue,0,Brightness)); else stroke(color(Hue,Saturation - (Saturation - 250) * 2,Brightness)); else stroke(color(Hue,Saturation,Brightness));
if (Saturation > 250) if (Saturation > 500) fill(color(Hue,0,Brightness)); else fill(color(Hue,Saturation - (Saturation - 250) * 2,Brightness)); else fill(color(Hue,Saturation,Brightness));
rect(X, Y, Width, Height);
}
}
I just realized that it is just that my graphics card does not support OPENGL 2.0

Changing speed of ball dropping... In processing

Here is a program that has a ball drop and bounce from wherever the mouse is clicked. Would anyone know how to change the rate that the ball drops to the force of gravity?
Im trying to figure out the proper solution to this... but i am having a little trouble. All help and or input would be much appreciated.
float x;
float y;
float yspeed = 0;
float xspeed = 0;
float balldiameter = 10;
float ballradius = balldiameter/2;
void setup() {
size (400,400);
background (255);
fill (0);
ellipseMode(CENTER);
smooth();
noStroke();
x = width/2;
y = height/2;
}
void draw() {
mouseChecks();
boundaryChecks();
ballFunctions();
keyFunctions();
}
void mouseChecks() {
if (mousePressed == true) {
x = mouseX;
y = mouseY;
yspeed = mouseY - pmouseY;
xspeed = mouseX - pmouseX;
}
}
void boundaryChecks() {
if (y >= height - ballradius) {
y = height - ballradius;
yspeed = -yspeed/1.15;
}
if (y <= ballradius) {
y = ballradius;
yspeed = -yspeed/1.35;
}
if (x >= width -ballradius) {
x = width -ballradius;
xspeed = -xspeed/1.10;
}
if (x <= ballradius) {
x = ballradius;
xspeed = -xspeed/1.10;
}
}
void ballFunctions() {
if (balldiameter < 2) {
balldiameter = 2;
}
if (balldiameter > 400) {
balldiameter = 400;
}
ballradius = balldiameter/2;
background(255); //should this be in here?
ellipse (x,y,balldiameter,balldiameter);
yspeed = yspeed += 0.2;
xspeed = xspeed/1.005;
y = y + yspeed;
x = x + xspeed;
}
void keyFunctions() {
if (keyPressed) {
if(keyCode == UP) {
balldiameter +=1;
}
if (keyCode == DOWN) {
balldiameter -=1;
}
}
}
The acceleration of gravity on earth is 9.81 m/s^2. So, if your ball's velocity is 0 at the point the mouse is clicked, the final velocity will be the acceleration integrated in relation to time. This would be (9.81 * t) / 2. Where t is in seconds. The resulting units would be m/sec. You would have to convert meters to some screen space unit for drawing.

Categories