Drawing a simple circle - java

I'm trying to draw a circle with the help of Java but I'm stuck
This is what I've done so far,
public class Circle {
public static void DrawMeACircle(int posX, int posY, int radius) {
int a = 10;
int b = 10;
int x = posX - a; //x = position of x away from the center
int y = posY - b;
int xSquared = (x - a)*(x - a);
int ySquared = (y - b)*(y - b);
for (int i = 0;i <=20; i++) {
for (int j = 1;j <=20; j++) {
if (Math.abs(xSquared) + (ySquared) >= radius*radius && Math.abs(xSquared) + (ySquared) <= radius*radius) {
System.out.println("#");
} else {
System.out.println(" ");
}
}
}
}
public static void main(String[] args){
DrawMeACircle(5,5,5);
}
}
As you can see, this doesn't work out properly. Does anyone know how this can be solved?
I'm thankful for any help possible, Michael.

First of all, your inner if condition does not depend from i and j, so is a constant. That means the same symbol is printed every time, a space symbol.
Next, you're using System.out.println(" "); every time, adding a newline to each symbol. So, result looks like a column of spaces.
Last, but not least: drawing area is limited by 20x20 "pixels" and unable to fit large circles.
You can fix all these points together with something like
public class Circle {
public static void DrawMeACircle(int posX, int posY, int radius) {
for (int i = 0;i <= posX + radius; i++) {
for (int j = 1;j <=posY + radius; j++) {
int xSquared = (i - posX)*(i - posX);
int ySquared = (j - posY)*(j - posY);
if (Math.abs(xSquared + ySquared - radius * radius) < radius) {
System.out.print("#");
} else {
System.out.print(" ");
}
}
System.out.println();
}
}
public static void main(String[] args){
DrawMeACircle(5,15,5);
}
}
which gives us somewhat similar to the circle.

Related

Grid Not Returning a Value in Processing 3

I'm trying to make a minesweeper clone using Processing's java. I have managed to create a grid and each tile has a randomized value assigned to it, but for some reason, only the top left tile can be clicked, the rest of the tiles do not return a value. If anyone knows whats wrong with my code or what I could try that would be great, thanks
Here's my Java code:
int realWidth = 500;
int realHeight = 500;
int tilemount = 0;
boolean mousePress = false;
//calls class
Tile[] tile = new Tile[100];
float tileSize = realWidth/10;
//sets size of window
void settings() {
size(realWidth, realHeight);
}
//Draws 100 tiles on the grid and assignemts each with a value from -1 - 9
void setup() {
int x = 0;
int y = 0;
for (int i = 0; i < tile.length; i++) {
tile[i] = new Tile(x, y, int(random(-1,9)), tilemount);
x += tileSize;
if (x > realWidth-tileSize) {
x = 0;
y += tileSize;
}
tilemount ++;
}
print("done");
}
//updates each tile in the list
void draw() {
background(50);
for (int i = 0; i < tile.length; i++) {
tile[i].display();
tile[i].tileClicked();
}
//checks if tiles are clicked
clickCheck();
}
//sets up tile class
class Tile {
int x;
int y;
int value;
int tilemount;
Tile(int x, int y, int value, int tilemount) {
this.x = x;
this.y = y;
this.value = value;
this.tilemount = tilemount;
}
//positions the tile based off of display values
void display() {
rect(x, y, tileSize, tileSize);
}
//the problem:
/*if tile is clicked, it should run through all 100 tiles in the list,
detect if the mouse is inside the x value assinged to each tile, and produce the
value of the tile the mouse is currently inside */
void tileClicked() {
if (mousePressed && mousePress == false) {
mousePress = true;
for (int i = 0; i < tile.length; i++) {
//println(tile[i].x, tile[i].y);
//println(tile[2].x, tile[2].y, mouseX, mouseY);
if (mouseX > tile[i].x && mouseX < tileSize && mouseY > tile[i].y && mouseY < tileSize) {
println(i, tile[i].value);
break;
}
}
}
}
}
//Checks if mouse is clicked
void clickCheck() {
if (!mousePressed) {
mousePress = false;
}
}
There is a bit of confusion over classes/objects and global variables in your code.
I say that for a few reasons:
boolean mousePress = false; is a global variable, accessible throughout the sketch, however you are accessing it and changing it from each Tile instance, resetting it's value: you probably meant to use a mousePress property for Tile. This way, each Tile has it's mousePress without interfering with one another.
in tileClicked() you're itereratting through all the tiles, from Tile which means unecessarily doing the loop for each time: each tile can check it's own coordinates and position to know if it's being clicked or not (no need for the loop)
speaking of checking bounds, checking if mouseX < tileSize and mouseY < tileSize will only check for the top left tile: you probably meant mouseX < x + tileSize and mouseY < y + tileSize
Here's a version of your sketch with the above notes applied
(and optional debug text rendering to double check the printed value against the tile):
int realWidth = 500;
int realHeight = 500;
int tilemount = 0;
//calls class
Tile[] tile = new Tile[100];
float tileSize = realWidth/10;
//sets size of window
void settings() {
size(realWidth, realHeight);
}
//Draws 100 tiles on the grid and assignemts each with a value from -1 - 9
void setup() {
int x = 0;
int y = 0;
for (int i = 0; i < tile.length; i++) {
tile[i] = new Tile(x, y, int(random(-1,9)), tilemount);
x += tileSize;
if (x > realWidth-tileSize) {
x = 0;
y += tileSize;
}
tilemount ++;
}
println("done");
}
//updates each tile in the list
void draw() {
background(50);
for (int i = 0; i < tile.length; i++) {
tile[i].display();
tile[i].tileClicked();
//checks if tiles are clicked
tile[i].clickCheck();
}
}
//sets up tile class
class Tile {
int x;
int y;
int value;
int tilemount;
boolean mousePress = false;
Tile(int x, int y, int value, int tilemount) {
this.x = x;
this.y = y;
this.value = value;
this.tilemount = tilemount;
}
//positions the tile based off of display values
void display() {
fill(255);
rect(x, y, tileSize, tileSize);
fill(0);
text(value,x + tileSize * 0.5, y + tileSize * 0.5);
}
//the problem:
/*if tile is clicked, it should run through all 100 tiles in the list,
detect if the mouse is inside the x value assinged to each tile, and produce the
value of the tile the mouse is currently inside */
void tileClicked() {
if (mousePressed && mousePress == false) {
mousePress = true;
//println(tile[2].x, tile[2].y, mouseX, mouseY);
if (mouseX > x && mouseX < x + tileSize && mouseY > y && mouseY < y + tileSize) {
println(value);
}
}
}
//Checks if mouse is clicked
void clickCheck() {
if (!mousePressed) {
mousePress = false;
}
}
}
I understand the intent of the mousePress variable, but I'd like to mousePressed() function which you can use to avoid de-bouncing/resetting this value and simplify code a bit.
Here's a version of the above sketch using mousePressed() (and renaming variables a touch to be in line with Java naming conventions):
int realWidth = 500;
int realHeight = 500;
int tileCount = 0;
//calls class
Tile[] tiles = new Tile[100];
float tileSize = realWidth/10;
//sets size of window
void settings() {
size(realWidth, realHeight);
}
//Draws 100 tiles on the grid and assignemts each with a value from -1 - 9
void setup() {
int x = 0;
int y = 0;
for (int i = 0; i < tiles.length; i++) {
tiles[i] = new Tile(x, y, int(random(-1,9)), tileCount);
x += tileSize;
if (x > realWidth-tileSize) {
x = 0;
y += tileSize;
}
tileCount ++;
}
println("done");
}
//updates each tile in the list
void draw() {
background(50);
for (int i = 0; i < tiles.length; i++) {
tiles[i].display();
}
}
void mousePressed(){
for (int i = 0; i < tiles.length; i++) {
tiles[i].click();
}
}
//sets up tile class
class Tile {
int x;
int y;
int value;
int index;
Tile(int x, int y, int value, int tileCount) {
this.x = x;
this.y = y;
this.value = value;
this.index = tileCount;
}
//positions the tile based off of display values
void display() {
fill(255);
rect(x, y, tileSize, tileSize);
// optional: display the tile value for debugging purposes
fill(0);
text(value, x + tileSize * 0.5, y + tileSize * 0.5);
}
//the problem:
/*if tile is clicked, it should detect if the mouse is inside the
value assinged to each tile, and produce the
value of the tile the mouse is currently inside */
void click() {
if (mouseX > x && mouseX < x + tileSize && mouseY > y && mouseY < y + tileSize) {
println("index", index, "value", value);
}
}
}
Good start though: keep going!
The rest of the code is good, congrats on using a 1D array for a 2D grid layout (and the logic for resetting the x position on each row). Have fun learning !
I think you did a good job naming functions and classes and what not. From this point, I would recommend breaking your code down so that you can make sure that at least 3 tiles function fully before allowing the tilelength to be something like 100 (for 100 tiles).
so from what I can see:
+ You have 3 apostrophes at the end of your code that need to be removed.
+ you use tile.length but never defined a length variable in your class, so when your for loop runs it has no number to use to determine it's number of cycles.
+ Please double check your logic in the tileClicked function with the help of a truth/logic table: https://en.wikipedia.org/wiki/Truth_table . I didn't look too deeply into this but this looks like an area where one misunderstanding could throw ;
Try adding this.length = 3; in your tile class and then re-run your code to see if more tiles pop up.
And it might be good to use some system.out.println calls to print conditional values out so that you can see the intermeediate results and compare them to what you expect to happen. Just some basic debugging.
Good luck.

Recursive Division Maze Java

I'm having problems with completing the algorithm based on this link.
After building a wall I choose the upper or left part of the maze and it seems to create itself only to the point where it needs to break the recursion and enter another divide method call. I'm not sure if I understand the values needed to be passed to the last call of the divide method correctly.
public void divide(int x, int y, int width, int hight) {
if (width< 2 || hight< 2) ;
else {
boolean horizontal = chooseOrientation(width,hight);
if (horizontal) {
int randomNumber = r.nextInt(hight - 1);
wallY = randomNumber + y;
for (int i = x; i < width; i++) {
fields[wallY][i].setHorizontalWall();
}
fields[wallY][r.nextInt(width- 1)].deleteHorizontalWall();
hight = wallY - y + 1;
divide(x, y, width, hight);
}
else {
int randomNumber = r.nextInt(width- 1);
WallX = randomNumber + x;
for (int i = y; i < hight; i++) {
fields[i][WallX].setVerticalWall();
}
fields[r.nextInt(hight - 1) + y][WallX].deleteVerticalWall();
width = WallX - x + 1;
}
if(horizontal){
hight = y + hight + WallY-1;
y = WallY + 1;
}
else {
width = WallX - 1 + width + x;
x = WallX + 1;
}
divide(x, y, width, hight);
}
}
In the "recursive-division" algorithm you start with a full 2-dimensional grid graph and you then start removing edges (= building "walls") alternating in horizontal and vertical "stripes". In every "stripe" only a single edge ("door") is left.
A graph-based version of this algorithm can be found here:
https://github.com/armin-reichert/mazes
https://github.com/armin-reichert/mazes/blob/master/mazes-algorithms/src/main/java/de/amr/maze/alg/others/RecursiveDivision.java

Assistance with creating grid/ball (objects?) in Java

I'm trying to create a Roomba program with a ball that bounces around the screen that cleans the tiles that it passes over. The program should start with all grey tiles and when the ball passes over them then the tiles turn white. Currently I have the ball that bounces around everywhere and a grid method which creates a 5x5 grid.
I have encountered two problems:
I cannot make the grid and the ball appear in the same simulation while running the program, it's either one or the other.
I'm having trouble with finding a way to analyze if the ball has passed over certain squares in the grid, perhaps I need to create an object for the grid/ball?
My code:
import edu.princeton.cs.introcs.StdDraw;
public class Roomba {
private static int windowWidth = 200;
private static int windowHeight = 200;
private static double x = 100;
private static double y = 100;
private static double vx = 2;
private static double vy = 4;
private static int radius = 5;
private static boolean inGame = true;
public static void updateLocations() {
x += vx;
y += vy;
}
public static void drawGrid() {
StdDraw.setScale(0, 5);
int[][] grid = new int[5][5];
for (int x = 0; x < grid.length; x++) {
for (int y = 0; y < grid.length; y++) {
grid[x][y] = 255;
}
}
for (int x = 0; x < grid.length; x++) {
for (int y = 0; y < grid.length; y++) {
StdDraw.square(x, y, 1);
}
}
}
public static void updateVelocities() {
if (y + radius >= windowHeight) {
vy = -vy;
} else if (y - radius <= 0) {
vy = -vy;
}
if (x >= 194 || x <= 6) {
vx = -vx;
}
}
public static void setBackground() {
StdDraw.clear(StdDraw.GRAY);
// drawGrid();
}
public static void drawBall() {
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.filledCircle(x, y, radius);
// StdDraw.setPenColor(StdDraw.RED);
// StdDraw.filledSquare(x + 3, y + 3, 1);
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.text(100, 70, "x is: " + x + " y is: " + y);
}
public static void draw() {
setBackground();
drawBall();
}
public static void main(String[] args) {
StdDraw.setCanvasSize(800, 800);
StdDraw.setXscale(0, windowWidth);
StdDraw.setYscale(0, windowHeight);
while (true) {
if (inGame) {
draw();
updateVelocities();
updateLocations();
} else {
StdDraw.text(100, 100, "Game Over");
}
// change to if all tiles have been cleaned
// if (x + radius > windowWidth || x - radius < 0) {
// inGame = false;
// }
StdDraw.show(20);
}
}
}
Maybe the background is being drawn over the ball or vice verse? Try to draw the ball first then the background? Make sure the ball is actually being rendered at the correct size and not as the entire screen. I'm not to familiar with 2D graphics but maybe there is some z fighting?

Java 2D Polygon - Polygon Collision Detection

Recently I have been using the Polygon class to create asteroids as well as bullets and a spaceship. I am currently trying to create the collision detection for the program however it appears that the collision detection only works around 1/5 of the time (no pattern appears as to why it works).
Here's the code..
Creating the Polygon:
void renderPoly() {
int j;
int s = sides;
double r, angle;
int x, y;
for (j = 0; j < s; j++) {
angle = 2 * Math.PI / s * j;
r = MIN_ROCK_SIZE + (int) (Math.random() * (MAX_ROCK_SIZE - MIN_ROCK_SIZE));
x = (int) (r * Math.cos(angle));
y = (int) (r * -Math.sin(angle));
cOM[0] += x;
cOM[1] += y;
pointData[j][0] = x;
pointData[j][1] = y;
}
cOM[0] /= asteroidShape.npoints;
cOM[1] /= asteroidShape.npoints;
for (int i = 0; i < asteroidShape.npoints; i++) {
pointData[i][0] += cOM[0];
pointData[i][1] += cOM[1];
}
}
rotating and moving the polygon:
void move() {
int x, y, i;
//change rotation
theta += rotVel;
//change x
asteroidData[0] += deltaX;
//change y
asteroidData[1] += deltaY;
for (i = 0; i < asteroidShape.npoints; i++) {
x = (int) (pointData[i][0] * Math.cos(theta) - pointData[i][1] * Math.sin(theta) );
y = (int) (pointData[i][0] * Math.sin(theta) + pointData[i][1] * Math.cos(theta) );
asteroidShape.xpoints[i] = x + asteroidData[0];
asteroidShape.ypoints[i] = y + asteroidData[1];
asteroidShape.invalidate();
}
}
check if touching bullet:
boolean hitBullet(Bullet b) {
this.asteroidShape.invalidate();
for (int i = 0; i < b.bulletShape.npoints; i++)
if (this.asteroidShape.contains(b.bulletShape.xpoints[i], b.bulletShape.ypoints[i]) )
return true;
for (int j = 0; j < this.asteroidShape.npoints; j++)
if (b.bulletShape.contains(this.asteroidShape.xpoints[j], this.asteroidShape.ypoints[j]) )
return true;
return false;
}
(the ship method is the same except the constructor requires a ship object)
as well as the loop that calls it in the 'game' class:
for (int i = 0; i < aArray.length-1; i++) {
if (aArray[i] != null) {
for (int j = 0; j < bArray.length-1; j++) {
if (bArray[j] != null) {
if (aArray[i].hitBullet(bArray[j])) {
aArray[i] = null;
bArray[j] = null;
i = aArray.length-1;
j = bArray.length-1;
}
}
else {
i = aArray.length-1;
j = bArray.length-1;
}
}
}
else {
i = aArray.length-1;
}
}
I have been looking around at alternative solutions such as the Separating Axis Theorem however I do have convex polygons at times and since this method (.contains()) already exists I would like to use it.
Any help would be appreciated, thanks!
The easy way to solve this that I've found is to convert Shapes (in your case Polygon(2D?)) into Areas. You can use Area.intersect(Area) to see if two Areas have collided

Finding white rectangle in an image

I'm trying to find a white rectangle in an image. The rectangle size is fixed. This is what I've come up as of yet:
BufferedImage bImage = bufferedImage;
int height = bufferedImage.getHeight(); //~1100px
int width = bufferedImage.getWidth(); //~1600px
int neededWidth = width / 2;
int neededHeight = 150;
int x = 0;
int y = 0;
boolean breaker = false;
boolean found = false;
int rgb = 0xFF00FF00;
int fx, fy;
fx = fy = 0;
JavaLogger.log.info("width, height: " + w + ", " + h);
while ((x != (width / 2) || y != (height - neededHeight)) && found == false) {
for (int i = y; i - y < neededHeight + 1; i++) {
for (int j = x; j - x < neededWidth + 1; j++) { //Vareetu buut, ka +1 vajadziigs
//JavaLogger.log.info("x,y: " + j + ", " + i);
long pixel = bImage.getRGB(j, i);
if (pixel != colorWhite && pixel != -1) {
//bImage.setRGB(j, i, rgb);
//JavaLogger.log.info("x,y: " + (j+x) + ", " + (i+y));
breaker = true;
break;
} else {
//bImage.setRGB(j, i, 0xFFFFFF00);
}
//printPixelARGB(pixel);
if ((i - y == neededHeight-10) && j - x == neededWidth-10) {
JavaLogger.log.info("width, height: " + x + ", " + y + "," + j + ", " + i);
fx = j;
fy = i;
found = true;
breaker = true;
break;
}
}
if (breaker) {
breaker = false;
break;
}
}
if (x < (width / 2)) {
x++;
} else {
if (y < (height - neededHeight)) {
y++;
x = 0;
} else {
break;
}
}
//JavaLogger.log.info("width, height: " + x + ", " + y);
}
if (found == true) {
for (int i = y; i < fy; i++) {
for (int j = x; j < fx; j++) {
bImage.setRGB(j, i, 0xFF00FF3F);
}
}
}
JavaLogger.log.info("width, height: " + w + ", " + h);
This works ok, if the rectangle I need is close to the begining of (0;0), but as it get further away, the performance degrades quite severely. I'm wondering, if there's something that can be done?
For example, this search took nearly 8s, which is quite a lot.
I'm thinking, that this can deffinitely be done more effectively. Maybe some blob finding? Read about it, but I've no idea how to apply it.
Also, I'm new to both Java and Image processing, so any help is appreciated.
This is very rough, but successfully finds all the white pixels in the image, more checking can be done to ensure it is the size you want and everything is there but the basics are there.
PS: I have not tested with your image. r and this.rc is picture size and p and this.px is the inner rectangle size
public static void main(String[] args) {
JFrame frame = new JFrame();
final int r = 100;
final int p = 10;
NewJPanel pan = new NewJPanel(r, p, new A() {
#Override
public void doImage(BufferedImage i) {
int o = 0;
for (int j = 0; j < i.getWidth() - p; j++) {
for (int k = 0; k < i.getHeight() - p; k++) {
PixelGrabber pix2 = new PixelGrabber(
i, j, k, p, p, false);
try {
pix2.grabPixels();
} catch (InterruptedException ex) {}
int pixelColor = pix2.getColorModel()
.getRGB(pix2.getPixels());
Color c = new Color(pixelColor);
if (c.equals(Color.WHITE)) {
System.out.println("Found at : x:" + j + ",y:" + k);
}
}
}
}
});
frame.getContentPane().add(pan);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private interface A {
void doImage(BufferedImage i);
}
private static class NewJPanel extends JPanel {
private static final long serialVersionUID = -5348356640373105209L;
private BufferedImage image = null;
private int px;
private int rc;
private A a;
public NewJPanel(int r, int p, A a) {
this.px = p;
this.rc = r;
this.a = a;
}
public BufferedImage getImage() {
return image;
}
#Override public void paint(Graphics g) {
super.paint(g);
image = new BufferedImage(this.rc, this.rc,
BufferedImage.TYPE_INT_ARGB);
java.awt.Graphics2D g2 = image.createGraphics();
g2.setColor(Color.BLACK);
g2.fillRect(0, 0, this.rc, this.rc);
g2.setColor(Color.WHITE);
g2.fillRect(
new Random().nextInt(this.rc - this.px),
new Random().nextInt(this.rc - this.px),
this.px, this.px);
g.drawImage(image, this.rc, this.rc, this);
this.a.doImage(this.image);
}
}
I'm no expert but I don't think the code is the problem - you need to change your algorithm. I would start by recursively searching for a single white pixel on the 2d plane, something like:
findWhitePixel(square){
look at pixel in the middle of 'square' - if it's white return it, otherwise:
findWhitePixel(top-right-quarter of 'square')
findWhitePixel(top-left-quarter of 'square')
findWhitePixel(bottom-right-quarter of 'square')
findWhitePixel(bottom-left-quarter of 'square')
}
after you find a white pixel try travesing up, down, left and right from it to find the borders on you shape. if it's a given that there can only be rectangles - your done. if there might be other shapes (triangles, circles, etc.) you'll need some verification here.
What you are asking can be solved by the operation known as "erosion". The erosion replaces every pixel by the darkest of all pixels in the rectangle of the requested size at that location (top-left corner). Here, darkest means that non-white supersedes white.
The output of erosion is an image with W-1 columns and H-1 rows less. Any white pixel in it corresponds to a solution.
In the lucky case of a rectangle shape, erosion is a separable operation. This means that you can erode first using an horizontal segment shape, then a vertical segment shape on the output of the first erosion. For a W x H restangle size, this replaces W * H operations by W + H, a significant saving.
In the also lucky case of a binary image (non-white or white), erosion by a segment can be done extremely efficiently: in every row independently, find all contiguous runs of white pixels, and turn the W-1 rightmost ones to non-white. Do the same to all columns, shortening the white runs by H-1 pixels.
Example: find all 3x2 rectangles:
####....####
##.....#..##
#..######...
.....###....
After 3x1 erosion:
####..####
##...#####
#########.
...#####..
After 1x2 erosion:
####.#####
##########
#########.
This algorithms takes constant time per pixel (regardless the rectangle size). Properly implemented, should take a handful of milliseconds.

Categories