Processing connecting ellipses with one line - java

I am a beginner in Processing and have a question for a task I am trying to solve.
I have an array of two different ellipses, one red on the top of my screen and one of blue ellipses at the bottom. Now I am trying to draw lines from every blue ellipse to every red ellipse by just using one line.
I would appreciate any help.
Thank you in advance.
Here is my current code of the ellipses.
float x=50;
float yDown=height-50;
float yTop=height-550;
float radius=50;
KreisRot[] kreisRot = new KreisRot[width];
KreisBlau[] kreisBlau = new KreisBlau[width];
void setup() {
size(600, 600);
for (int r=0; r < kreisRot.length; r++) {
kreisRot[r] = new KreisRot();
}
for (int b=0; b < kreisRot.length; b++) {
kreisBlau[b] = new KreisBlau();
}
}
void draw() {
for (int r=0; r < kreisRot.length; r++) {
kreisRot[r].showRed();
}
for (int b=0; b < kreisRot.length; b++) {
kreisBlau[b].showBlue();
}
}
class KreisBlau {
float x=50;
float yDown=height-50;
float radius=50;
void showBlue() {
for (int b=0; b < kreisBlau.length; b++) {
fill(0, 0, 255);
ellipse(50+(b)*100, yDown, radius, radius);
}
}
}
class KreisRot {
float x=50;
float yTop=height-550;
float radius=50;
void showRed() {
for (int r=0; r < kreisRot.length; r++) {
fill(255, 0, 0);
ellipse(50+(r)*100, yTop, radius, radius);
}
}
}

I recommend to create a single class Kreis, which has a constructor, which can initialize the position and the color of the object. Further the class should have methods, to ask the object for ist x and y position (X(), y()):
class Kreis {
float _x, _y;
int _r, _g, _b;
float radius=50;
Kreis(float x, float y, int r, int g, int b ) {
this._x = x;
this._y = y;
this._r = r;
this._g = g;
this._b = b;
}
float X() { return _x; }
float Y() { return _y; }
void show() {
fill(_r, _g, _b);
noStroke();
ellipse(_x, _y, radius, radius);
}
}
Setup the objects like this:
Kreis[] kreisRot = new Kreis[6];
Kreis[] kreisBlau = new Kreis[6];
void setup() {
size(600, 600);
for (int r=0; r < kreisRot.length; r++) {
kreisRot[r] = new Kreis(50+r*100, 50, 255, 0, 0);
}
for (int b=0; b < kreisRot.length; b++) {
kreisBlau[b] = new Kreis(50+b*100, height-50, 0, 0, 255);
}
}
To draw a line from each of the blue ellipses to each of the red ellipses, you need 2 nested loops. Get the position of the ellipses in the loop and draw a line between them:
void draw() {
for (int r=0; r < kreisRot.length; r++) {
kreisRot[r].show();
}
for (int b=0; b < kreisBlau.length; b++) {
kreisBlau[b].show();
}
for (int r=0; r < kreisRot.length; r++) {
for (int b=0; b < kreisBlau.length; b++) {
stroke(0, 196, 0);
strokeWeight(3);
line(kreisRot[r].X(), kreisRot[r].Y(), kreisBlau[b].X(), kreisBlau[b].Y());
}
}
}
Preview:

Related

How to display coordinates as Strings with Graphics2D in Java?

I have a Voronoi diagram being displayed thanks to the Graphics2D class. I would like to know how to display a String in one of black dots located within the patterns. I've tried things such as labels, etc., and can't manage to output a String anywhere in the diagram.
Here's how the code looks:
public Voronoi() {
super("Voronoi Diagram");
setBounds(0, 0, size, size);
setDefaultCloseOperation(EXIT_ON_CLOSE);
int n = 0;
Random rand = new Random();
I = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
px = new int[cells];
py = new int[cells];
color = new int[cells];
for (int i = 0; i < cells; i++) {
px[i] = rand.nextInt(size);
py[i] = rand.nextInt(size);
color[i] = rand.nextInt(16777215);
}
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
n = 0;
for (byte i = 0; i < cells; i++) {
if (distance(px[i], x, py[i], y) < distance(px[n], x, py[n], y)) {
n = i;
}
}
I.setRGB(x, y, color[n]);
}
}
Graphics2D g = I.createGraphics();
g.setColor(Color.BLACK);
for (int i = 0; i < cells; i++) {
g.fill(new Ellipse2D .Double(px[i] - 2.5, py[i] - 2.5, 5, 5));
}
try {
ImageIO.write(I, "png", new File("voronoi.png"));
} catch (IOException e) {
}
}
public void paint(Graphics g) {
g.drawImage(I, 0, 0, this);
}
static double distance(int x1, int x2, int y1, int y2) {
double d;
// d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); // Euclidian
d = Math.abs(x1 - x2) + Math.abs(y1 - y2); // Manhattan
// d = Math.pow(Math.pow(Math.abs(x1 - x2), p) + Math.pow(Math.abs(y1 - y2), p), (1 / p)); // Minkovski
return d;
}
public static void main(String[] args) {
new Voronoi().setVisible(true);
}
}

Processing - Rough pixel sorting algorithm stops after a part of the image

I wrote a code for processing and had formerly sorted pixels with selection sort. I have to hand it in and the teacher said it is taking to long like this, so I decided to divide the pixels brightness into parts of 50 and just sort it very roughly. The image that comes out isn't completely sorted though and I really don't know where it went wrong.
I doesn't have to be sorted perfectly - it's really just about having a cool-looking image as a result.
I hope some can help me and it is understandable what I mean!
Thanks in advance
PImage img;
PImage two;
PImage sorted;
int j = 0;
int x = j;
int y = x;
int u = y;
int h = u;
int d = 1;
void setup() {
size(736,1051);
img = loadImage("guy.png");
two = loadImage("guy2.png");
background(two);
}
void draw() {
loadPixels();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int loc = x + y*width;
float r = red(img.pixels[loc]);
float g = green(img.pixels[loc]);
float b = blue(img.pixels[loc]);
float av = ((r+g+b)/3.0);
pixels[loc] = color(g,b,r, 17); //I know r, g, b are switched here
}
}
updatePixels();
save("guy_coloured.png");
}
void keyPressed(){
sorted = loadImage("guy_coloured.png");
sorted.loadPixels();
image(sorted, 0, 0);
System.out.print("doing it");
for (int i = 0; i < sorted.pixels.length; i++){
color colours = sorted.pixels[i];
float b = brightness(colours);
if(b<50){
sorted.pixels[j] = sorted.pixels[i];
j++;}
}
for (int f = 0; f < img.pixels.length; f++){
color colours = sorted.pixels[f];
float b = brightness(colours);
if(b<100 && b>50){
sorted.pixels[x] = sorted.pixels[f];
x++;}
}
for (int k = 0; k < img.pixels.length; k++){
color colours = sorted.pixels[k];
float b = brightness(colours);
if(b<150 && b>100){
sorted.pixels[y] = sorted.pixels[k];
y++;}
}
for (int t = 0; t < img.pixels.length; t++){
color colours = sorted.pixels[t];
float b = brightness(colours);
if(b<200 && b>150){
sorted.pixels[u] = sorted.pixels[t];
u++;}
}
for (int o = 0; o < img.pixels.length; o++){
color colours = sorted.pixels[o];
float b = brightness(colours);
if(b>200){
sorted.pixels[h] = sorted.pixels[o];
h++;}
}
System.out.print("done");
sorted.updatePixels();
image(sorted, 0, 0);
save("guy_sorted.png");
noLoop();
}
I want the whole image to be sorted, but it gives me back the normal image with about 1/4 sorted from the top.
This is the current result:
https://imgur.com/kHffIpm
Full code including irrelevant parts: https://docs.google.com/document/d/1YC97YMq9fKcbCAn3_RvLIm1bNo72FrNnHT3obc9pp7U/edit?usp=sharing
You do not sort the pixels. What you actually do is to arrange the dark pixel at the begin of the image and overwrite the pixels which are there. If you want to sort the pixels, then you've to swap them.
Write a function which can swap 2 pixel:
void Swap(PImage toSort, int i1, int i2) {
color c = toSort.pixels[i1];
toSort.pixels[i1] = toSort.pixels[i2];
toSort.pixels[i2] = c;
}
Once some pixels have been sorted, and are arranged at the begin of the image, this area doesn't need to be investigated further.
Write a function which sorts pixels dependent on a brightness range [b_min, b_max] and start at a certain index start:
int Sort(PImage toSort, int start, float b_min, float b_max) {
for (int i = start; i < toSort.pixels.length; i++) {
float b = brightness(toSort.pixels[i]);
if (b >= b_min && b < b_max) {
Swap(toSort, i, start);
start ++;
}
}
return start;
}
Sort the image by ascending brightness. e.g:
PImage img, two, sorted;
void setup() {
size(736,1051);
img = loadImage("guy.png");
two = loadImage("guy2.png");
background(two);
}
void draw() {
loadPixels();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int loc = x + y*width;
float r = red(img.pixels[loc]), g = green(img.pixels[loc]), b = blue(img.pixels[loc]);
pixels[loc] = color(g,b,r, 17); //I know r, g, b are switched here
}
}
updatePixels();
save("guy_coloured.png");
}
void Swap(PImage toSort, int i1, int i2) {
color c = toSort.pixels[i1];
toSort.pixels[i1] = toSort.pixels[i2];
toSort.pixels[i2] = c;
}
int Sort(PImage toSort, int start, float b_min, float b_max) {
for (int i = start; i < toSort.pixels.length; i++) {
float b = brightness(toSort.pixels[i]);
if (b >= b_min && b < b_max) {
Swap(toSort, i, start);
start ++;
}
}
return start;
}
void keyPressed(){
sorted = loadImage("guy_coloured.png");
sorted.loadPixels();
image(sorted, 0, 0);
System.out.print("doing it");
int j = 0;
j = Sort(sorted, j, 0.0, 50.0);
j = Sort(sorted, j, 0.50, 100.0);
j = Sort(sorted, j, 0.100, 150.0);
j = Sort(sorted, j, 0.150, 200.0);
j = Sort(sorted, j, 0.200, 256.0);
System.out.print("done");
sorted.updatePixels();
image(sorted, 0, 0);
save("guy_sorted.png");
noLoop();
}

How to fill 2D array with randm colors in java?

I've been trying to generate a grid of randomly colored boxes for a brick-breaker game. However given this code, the colors keep changing. I'd like them to be randomly set and stay that way.
for(int i = 0; i < map.length; i++) {
for(int j = 0; j < map [0].length; j++) {
if(map[i][j] > 0) { //make brick if greater than 0, else don't
int color = (int) (Math.random() * 256);
g.setColor(new Color(color, color, color));
g.fillRect(j * brickWidth + 80, i * brickHeight + 50, brickWidth, brickHeight);
g.setStroke(new BasicStroke(3));
g.setColor(Color.black);
g.drawRect(j * brickWidth + 80, i * brickHeight + 50, brickWidth, brickHeight);
}
}
}
Each time your component need to be resized or moved, repaint() method is being called to update it's state. So if you are generating colors in paintComponent like in following example:
public class MyComponent extends JComponent {
#Override
protected void paintComponent(Graphics g) {
// generate colors and draw grid
}
}
then colors will change on resize event or other event that lead to repaint call, since repaint invokes paintComponent method. If you want to display the same colors, just move generate-colors code out of this method:
public class MyComponent extends JComponent {
private final Color[][] gridColors = randomGridColors(5, 5);
private Color[][] randomGridColors(int rows, int columns) {
Color[][] gridColors = new Color[rows][columns];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
gridColors [i][j] = randomColor();
}
}
}
private Color randomColor() {
int rgbValue = (int) (Math.random() * 256);
return new Color(rgbValue, rgbValue, rgbValue);
}
#Override
protected void paintComponent(Graphics g) {
// draw grid
}
}
You currently create the random color every time you draw your bricks, which can be many times per second.
Create some brick class and generate the color for each brick only once.
Something like this:
public class TryThis {
private static final Logger LOG = Logger.getLogger(TryThis.class.getName());
public static void main(String[] args) {
SwingComponent panel = new SwingComponent();
JFrame frame = new JFrame("try me");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setVisible(true);
}
static class SwingComponent extends JPanel {
int W = 10;
int H = 10;
int recwidth = 20;
int recheight = 10;
Brick[][] bricks = new Brick[H][W];
public SwingComponent() {
super();
for (int y = 0; y < H; y++) {
for (int x = 0; x < W; x++) {
bricks[y][x] = new Brick(createRandomColor(), new Rectangle(x * recwidth, y * recheight, recwidth,
recheight));
}
}
}
#Override
public void paint(Graphics g) {
for (int y = 0; y < H; y++) {
for (int x = 0; x < W; x++) {
bricks[y][x].draw(g);
}
}
}
Color createRandomColor() {
return new Color((int) (Math.random() * 256), (int) (Math.random() * 256), (int) (Math.random() * 256));
}
}
static class Brick {
Color col;
Rectangle rec;
public Brick(Color col, Rectangle rec) {
this.col = col;
this.rec = rec;
}
public void draw(Graphics g) {
g.setColor(col);
g.fillRect(rec.x, rec.y, rec.width, rec.height);
}
}
}

Getting a specific row in a spritesheet libgdx java

I am trying to access a specific row in my sprite sheet and I am thoroughly confused as to how to do this. I tried modifying a tutorial I found to accomplish this but when I run the code the length of my animation array is of size 0 when there are five rows in my spritesheet and 12 columns. My class should always fill my animation array with one row of information. Here is my Animator class
public Animator(Texture spriteSheet, int cols){
this.walkSheet = spriteSheet;
this.cols = cols;
this.rows = 1;
}
public void create() {
TextureRegion[][] tmp = TextureRegion.split(walkSheet, walkSheet.getWidth()/cols, walkSheet.getHeight()/rows); // #10
walkFrames = new TextureRegion[cols];
anim = new Animation[rows];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
walkFrames[j] = tmp[i][j];
}
anim[i] = new Animation(0.025f, walkFrames);
}
stateTime = 0f; // #13
}
public void render(int index, SpriteBatch spriteBatch, int x, int y, int width, int height) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
stateTime += Gdx.graphics.getDeltaTime();
currentFrame = anim[index].getKeyFrame(stateTime, true);
spriteBatch.draw(currentFrame, x, y, width, height);
}
Any help with this will be extremely appreciated as I have spent so much time trying to figure this out.
I haven't tried this code yet, but I think this could work for what you want.
public Animator(Texture spriteSheet, int cols, int rows){
this.walkSheet = spriteSheet;
this.cols = cols;
this.rows = rows;
}
public void create() {
TextureRegion[][] tmp = TextureRegion.split(walkSheet, walkSheet.getWidth()/cols, walkSheet.getHeight()/rows); // #10
anim = new Animation[rows];
for (int i = 0; i < rows; i++) {
walkFrames = new TextureRegion[cols];
for (int j = 0; j < cols; j++) {
walkFrames[j] = tmp[i][j];
}
anim[i] = new Animation(0.025f, walkFrames);
}
stateTime = 0f; // #13
}
public void render(int index, SpriteBatch spriteBatch, int x, int y, int width, int height) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
stateTime += Gdx.graphics.getDeltaTime();
currentFrame = anim[index].getKeyFrame(stateTime, true);
spriteBatch.draw(currentFrame, x, y, width, height);
}

Painting balloons on Graphics2D

I want to make bubble shooter game and I have problem with generate bubbles at start. When trying to compile program, I have error: Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException.
public class MyPanel extends JPanel {
Init init;
public MyPanel(){
super();
init = new Init();
}
public void paint(Graphics g){
Dimension size = getSize();
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.GRAY);
g2d.fillRect(0, 0, size.width, size.height - 70);
for(int j = 0; j < 10; j++)
for(int i = 0; i < 20; i++){
init.fields[i][j].b.paint(g); //here compiler shows error
}
}
}
public class Field {
private int x;
private int y;
private int r = 30;
public Baloon b;
public Field(int x, int y){
this.x = x*r;
this.y = y*r;
}
public void addBaloon(int n){
b = new Baloon(this.x, this.y, r, n);
}
}
public class Init {
Parser pr = new Parser();
private int r = pr.getRadius();
private int x = pr.getXDimension();
private int y = pr.getYDimension();
private int ni = pr.getColorRange();
Field[][] fields = new Field[x][y];
private int startX = 20;
private int startY = 10;
public Init(){
for(int yi = 1; yi<y; yi++){
for (int xi = 1; xi<x; xi++){
fields[xi][yi] = new Field(xi*r, yi*r);
}
}
for(int yi = 1; yi < startY; yi ++){
for(int xi = 1 ; xi < startX; xi++){
Random rand = new Random();
int n = rand.nextInt(ni);
fields[xi][yi].addBaloon(n);
}
}
}
}
You are initializing array from index 1:
for(int yi = 1; yi<y; yi++){
for (int xi = 1; xi<x; xi++){
fields[xi][yi] = new Field(xi*r, yi*r);
}
}
While accessing it from 0 like:
for(int j = 0; j < 10; j++)
for(int i = 0; i < 20; i++){
init.fields[i][j].b.paint(g); //here compiler shows error
}
Array index starts from 0 and goes upto n-1. So you need to initialize like:
for(int yi = 0; yi<y; yi++){
for (int xi = 0; xi<x; xi++){
fields[xi][yi] = new Field(xi*r, yi*r);
}
}

Categories