I am trying to fill some particular circle areas on a square grid in Proceesing. However, I am facing some weird filling after I run my code. I used the "atan2" function to get the angle of points in the grid and apply some if conditions to limit the area. But it doesn't work. Actually, it works some way but not exactly what I want.This is the result I run the code-> enter image description here, but it should be like -> enter image description here Can someone help me to solve this, please?
(Additionally, I seized this page to detect which points are in the area I specified enter link description here.
Cell [][] cells;
int res = 10;
PVector circleCenter ;
float rad=290;
void setup() {
size(1200, 800);
cells = new Cell[width/res ][height/res];
for (int i=0; i<cells.length; i++) {
for (int j = 0; j<cells[0].length; j++) {
cells[i][j] = new Cell();
}
}
}
void draw() {
background(255);
circleCenter = new PVector(mouseX, mouseY);
display();
pushStyle();
ellipse(circleCenter.x, circleCenter.y, 20, 20);
popStyle();
//println(frameRate);
}
void display() {
for (int i=0; i<cells.length; i++) {
for (int j = 0; j<cells[0].length; j++) {
if (sq(i*res-width/2) + sq(j*res-height/2) <=sq(rad/2)) {
float angleInRad = atan2(j*res-height/2, i*res-width/2);
///
if (angleInRad<radians(-10) && angleInRad>radians(-60)) {
fill(0, 255, 0); // degrees(atan2(j*res-circleCenter.y, i*res-circleCenter.x))
}
} else {
noFill();
}
rect(i*res, j*res, res, res);
}}
class Cell {
boolean blackness=false;
Cell() {
}
}
You have not specified input data for your task. I assume we have center coordinates cx, cx, radius r, starting and ending angle sa, ea of the sector (in code -10, -60).
There is an approach to check whether vector direction lies in sector, it's robust to potential troubles with periodicity, negative values etc. At first normalize range ends, then find middle angle and half-angle
half = (ea - sa) / 2
mid = (ea + sa) / 2
coshalf = Cos(half)
Now compare that difference of angle and middle one is lower then half-angle
if Cos(angle - mid) >= coshalf then
angle lies in range sa..ea
Related
I am working on a school project in Processing (Java Mode). We have a picture of how the game should look like.
So the task is to create a grid out of squares. Random squares should light up in red. If a red square is clicked, it should change colors to green and stay green.
What my code looks like at the moment:
Square[][] grid;
int cols = 20;
int rows = 20;
void setup() {
size(400, 400);
grid = new Square[cols][rows];
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
grid[i][j] = new Square(i*20, j*20, 20, 20);
}
}
}
void draw() {
background(0);
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
grid[i][j].display();
if (grid[i][j].x<mouseX && mouseX < grid[i][j].x + grid[i][j].w && grid[i][j].y<mouseY && mouseY < grid[i][j].y + grid[i][j].h && mousePressed) {
color col = color(0,204,0);
grid[i][j].update(col);
}
}
}
}
Class for squares:
class Square {
float x, y;
float w, h;
color c;
Square(float tempX, float tempY, float tempW, float tempH) {
x = tempX;
y = tempY;
w = tempW;
h = tempH;
c = color(0);
}
void display() {
stroke(0);
fill(c);
rect(x, y, w, h);
}
void update(color c) {
this.c = c;
}
}
So at the moment, every square you click turns green. I am not sure how to write the code, so that random squares change color to red and shuffle every 5 seconds.
Do you have any tips on how to proceed with the code or which thinking steps to take to be able to solve this task?
First, take your task:
So the task is to create a grid out of squares. Random squares should light up in red. If a red square is clicked, it should change colors to green and stay green.
and break it down:
create a grid out of squares: nicely done already !
Random squares should light up in red
If a red square is clicked
change colors to green and stay green
How do you use random numbers in Processing ?
The simplest method is using the random() method: you can pass two values and you'll get back a random number between those values.
Let's say you want to flip a coin so there's a (roughly) 50-50 change you get heads or tails. You could so something like:
if(random(0, 100) > 50){
println("head");
}else{
println("tails");
}
Could even be random(0.0, 1.0) > 0.5 for example, the idea is the same.
You could think of throwing a dice or a number of dices, etc.
Remember these are pseudo-random and in your own time can explore other pseudo random related methods such as randomGauss() and noise().
random() may be good enough for now, part 2 done :)
You're almost done with part 3:
if (grid[i][j].x<mouseX && mouseX < grid[i][j].x + grid[i][j].w && grid[i][j].y<mouseY && mouseY < grid[i][j].y + grid[i][j].h && mousePressed) {
but you need to also check if the clicked square is red.
Would nice to have some red squares to begin with. Let's assume color(204, 0, 0) is your red, you could simply add an additional check:
if(grid[i][j].c == color(204, 0, 0)){
println("red block clicked");
grid[i][j].c = color(0, 204, 0);
}
Which roughly turns your sketch into:
Square[][] grid;
int cols = 20;
int rows = 20;
final color RED = color(204, 0, 0);
final color GREEN = color(0, 204, 0);
void setup() {
size(400, 400);
grid = new Square[cols][rows];
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
grid[i][j] = new Square(i*20, j*20, 20, 20);
// roughly 50 - 50 % change a grid square will be red
if (random(0, 100) > 50) {
grid[i][j].update(RED);
}
}
}
}
void draw() {
background(0);
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
grid[i][j].display();
if (grid[i][j].x<mouseX && mouseX < grid[i][j].x + grid[i][j].w && grid[i][j].y<mouseY && mouseY < grid[i][j].y + grid[i][j].h && mousePressed) {
// if the square is red
if (grid[i][j].c == RED) {
// change colour to GREEN
grid[i][j].update(GREEN);
}
}
}
}
}
class Square {
float x, y;
float w, h;
color c;
Square(float tempX, float tempY, float tempW, float tempH) {
x = tempX;
y = tempY;
w = tempW;
h = tempH;
c = color(0);
}
void display() {
stroke(0);
fill(c);
rect(x, y, w, h);
}
void update(color c) {
this.c = c;
}
}
In terms of shuffling colours every 5 seconds I recommend:
for every 5 seconds you could use millis()
above there is an example of shuffling done in setup() though you might want to encapsulate a nested loop like that with the random condition in a void shuffle() function for example which you could easily call every 5 seconds.
note that this approach will reset green blocks to red, you might want an else in that condition to reset blocks to black (otherwise, with time, most will turn red), etc.
Have fun!
P.S. I tend to separate state data from representation. For example I would add a variable to keep track of each square state (e.g. OFF, INTERACTIVE, ACTIVATED), update a basic finite state machine, then render colours accordingly. What you have above is a tight coupling between the colour of a Square and it's state. For the homework you've got that's ok, but in the future, for more complex projects you might want to consider data flows through your program and how you represent it.
My problem is wherever i click a node appears and for the second click another node appears with connected edge...so i want that When i click at any location, the node should be generated at the closest grid intersection point. I tried using loops.
and i'm trying to do that without "class"
int n_partition=10;
int length = 101;
PVector[] position = new PVector[length];
int BallNum;
void setup() {
size(600, 360);
background(255);
}
void draw() {
fill(255);
grid();
fill(0);
}
void mousePressed(){
stroke(0);
BallNum++;
position[BallNum]= new PVector(mouseX, mouseY);
circle(position[BallNum].x, position[BallNum].y, 10);
if (BallNum > 1) {
line(position[BallNum].x,position[BallNum].y,position[BallNum-
1].x,position[BallNum-1].y);
line(position[1].x,position[1].y,position[BallNum].x,position[BallNum] .y);
}
for (int i = 0; i < position[BallNum].length; ++ i) {
position[BallNum] = position[BallNum].get(i);
position[BallNum] = position[BallNum].get((i+1) % position[BallNum].length);
line(position[BallNum].x, position[BallNum].y,
position[BallNum].x, position[BallNum].y);
}
}
I EXPECT THE NODE SHOULD GO TO THE CLOSEST INTERSECTION.
You've to calculate the nearest position of the mouse to a point on the grid. For that you've to know the width (tile_width) and the height (tile_height) of cell.
The index of the cell can be calculated by the dividing the mouse position to the size of a tile and round() the result to an integral value (e.g. round(mouseX / (float)tile_width)).
Don't draw anything in int the mousePressed callback. The only thing you've to do there is to add a pint to the list:
void mousePressed(){
int tile_width = width / n_partition; // adapt this for your needs
int tile_height = height / n_partition;
int x = round(mouseX / (float)tile_width) * tile_width;
int y = round(mouseY / (float)tile_height) * tile_height;
position[BallNum]= new PVector(x, y);
BallNum++;
}
All the drawing has to be done in draw(). Draw the lines and points in separate loops:
void draw() {
background(255);
grid();
// draw the lines in a loop
strokeWeight(3);
stroke(0, 0, 255);
for (int i = 0; i < BallNum; ++ i) {
int i2 = (i+1) % BallNum;
line(position[i].x, position[i].y, position[i2].x, position[i2].y);
}
// draw balls in a loop
strokeWeight(1);
stroke(0, 0, 0);
fill (255, 0, 0);
for (int i = 0; i < BallNum; ++i) {
circle(position[i].x, position[i].y, 10);
}
}
Note, the scene is consecutively redrawn in every frame. Before the scene is drawn, the entire window has to be "cleared" by background().
See the result:
I'm trying to create a script that drawls a curve through 'n' vertexes equally spaced around the center of an ellipse.
The reason I'm not just drawling an ellipse around the center ellipse is because I eventually want to connect a micro-controller to Processing where the data points acquired from the 'n' amount of sensors will vary the height ('y') of each vertex, creating constantly changing, irregular curves around the center ellipse such as this possible curve:
Essentially, this is supposed to be a data visualizer, but I cannot figure out why this is not working or how to achieve this effect after going through examples and the documentation on https://processing.org/reference/.
Here is my code:
color WHITE = color(255);
color BLACK = color(0);
void setup() {
size(500, 500);
}
void draw() {
background(WHITE);
translate(width/2, height/2); // move origin to center of window
// center ellipse
noStroke();
fill(color(255, 0, 0));
ellipse(0, 0, 10, 10); // center point, red
fill(BLACK);
int n = 10;
int y = 100;
float angle = TWO_PI / n;
beginShape();
for (int i = 0; i < n; i++) {
rotate(angle);
curveVertex(0, y);
}
endShape();
}
The matrix operations like rotate do not transform the single vertices in a shape. The current matrix is applied to the entire shape when it is draw (at endShape). You've to calculate all the vertex coordinates:
Create a ArrayList of PVector, fill it with points and draw it in a loop:
color WHITE = color(255);
color BLACK = color(0);
ArrayList<PVector> points = new ArrayList<PVector>();
void setup() {
size(500, 500);
int n = 10;
int radius = 100;
for (int i = 0; i <= n; i++) {
float angle = TWO_PI * (float)i/n;
points.add(new PVector(cos(angle)*radius, sin(angle)*radius));
}
}
void draw() {
background(WHITE);
translate(width/2, height/2);
noFill();
stroke(255, 0, 0);
beginShape();
PVector last = points.get(points.size()-1);
curveVertex(last.x, last.y);
for (int i = 0; i < points.size(); i++) {
PVector p = points.get(i);
curveVertex(p.x, p.y);
}
PVector first = points.get(0);
curveVertex(first.x, first.y);
endShape();
}
Back again with another problem that has stumped me completely and cannot for the life of me fix.
So I had previously posted a question about my Java game I am making for a class that with the help of #MadProgrammer was fixed...mostly. Now there is a new problem that needs a post all to it's own
Previous Post:
Rows and columns with multidimensional array java
Problem:
In the code below I have it set up to loop through the variables x and y to make rows and columns on a jPanel. Each time it loops through it should randomly mark the "x,y" location with one of the "terrains" so that later it can "paint" that location with the appropriate colored 20x20 square.
The code runs great except for one thing, it looks like it skips the very first "if statement" that marks the "terran[0]" which is "floor". When the code is ran it "paints" the other three "terrains" and not a single "floor" "terrain".
I have looked for a solution on these posts but no success:
Java if statement is skipped
If statement being skipped during execution
Java - for loops being skipped
Java if-statement being skipped
Here is a working piece of code that results in the problem at hand:
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class gamePanel extends JPanel
{
public gamePanel()
{
setBounds(115,93,480,480);
}
private Random generator = new Random();
int floor = 0; //initializes the variable floor to zero for later use
int dirt = 1;
int stone = 2;
int water = 3;
int width = 24;
int height = 24;
int x, y; // my x & y variables for coordinates
int[][] coords = new int[width][height]; //my array that I want to store the coordinates for later use in painting
int[] terrain = {floor, dirt, stone, water}; //my terrain that will determine the color of the paint
public void mapGen() //what should mark/generate the JPanel
{
for(x = 0; x < width; x++)
{
for(y = 0; y < height; y++)
{
int z = generator.nextInt(20);// part of the randomization
if(z <= 10)
{
coords[x][y] = terrain[0]; //should mark the coordinates as floor
}
if(z == 11)
{
coords[x][y] = terrain[3];//should mark the coordinates as water
}
if(z >= 12 && z <= 16)
{
coords[x][y] = terrain[2];//should mark the coordinates as stone
}
if(z >= 17 && z <= 19)
{
coords[x][y] = terrain[1];//should mark the coordinates as dirt
}
coords[0][0] = terrain[0]; // sets coordinate 0,0 to floor //need to have these always be floor
coords[23][23] = terrain[0]; // sets coordinate 24,24 to floor //^^^^^^^^^^
}
}
}
#Override
public void paintComponent(Graphics g)//what will paint each 20x20 square on the grid what it is assigned
{
super.paintComponent(g);
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
mapGen();
if(coords[x][y] == terrain[floor])//should paint the floor color at marked coordinates
{
g.setColor(Color.white);
g.fillRect((x*20), (y*20), 20, 20);
}
if(coords[x][y] == terrain[dirt]);//should paint the dirt color at marked coordinates
{
g.setColor(new Color(135,102,31));
g.fillRect((x*20), (y*20), 20, 20);
}
if(coords[x][y] == terrain[stone])//should paint the stone color at marked coordinates
{
g.setColor(new Color(196,196,196));
g.fillRect((x*20),(y*20),20,20);
}
if(coords[x][y] == terrain[water])//should paint the water color at marked coordinates
{
g.setColor(new Color(85,199,237));
g.fillRect((x*20),(y*20),20,20);
}
}
}
}//end paintComponent
public static void main(String[] args)
{
gamePanel panel = new gamePanel();
JFrame frame = new JFrame();
frame.setSize(500,550);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.setVisible(true);
}//end main
}// end gamePanel
Please keep in mind that I am a novice programmer and I am still learning. So anything that is not considered "basic" code please explain in detail.
I've built this L-System in Processing using toxiclib and I want to connect each point which is specified to each intersection in the branching of the tree. I've written a separate sketch in which I'm trying to create a triangle mesh by connecting the three closest points, I've been able to connect three points but I want it to be able to go through all the Vertices in an arraylist and then connect three closest points until I have a mesh out of all the vertices in the array. I also need to be able to convert this whole sketch into a function where by I can feed it into my L-System and then it will return the whole system with all the points connected in order to create a mesh. Essentially this is so I can then texture and maybe possibly apply Shaders to it if possible. I think that I might be attempting a harder way of approaching this for I believe toxiclibs or HEMESH libraries could do all of this for me, but I've been unable to figure it out. Any help would be much appreciated.
Here's the code for the sketch I wrote to try and connect all the points into a mesh.
import peasy.*;
float min = 1000;
ArrayList <PVector> loc = new ArrayList <PVector> ();
ArrayList <PVector> locSort = new ArrayList <PVector> ();
float [] minDists;
int [] minIdxs;
PeasyCam cam;
void setup() {
size(600, 600, OPENGL);
cam = new PeasyCam(this, 100);
for (int i=0; i<50; i++) {
loc.add(new PVector(random(-50, 50), random(-50, 50), random(-50, 50)));
}
minDists = new float[3];
minIdxs = new int[3];
for (int i = 0; i < 3; i ++)minDists[i] = 1000;
for (int i=0; i<loc.size(); i++) {
for (int j=0; j<loc.size (); j++) {
PVector vi= loc.get(i);
// loc.remove(i);
PVector vj= loc.get(j);
// loc.remove(j);
float c = vi.dist(vj);
for (int k = 0; k < 3; k++) {
if (c < minDists[k] && c > 0) {
if (k == 0) {
minDists[2] = minDists[1];
minDists[1] = minDists[0];
} else if (k == 1) {
minDists[2] = minDists[1];
}
println(k, c);
minDists[k] = c;
minIdxs[k] = j;
break;
}
}
}
}
}
void draw() {
background(255);
for (PVector v : loc) {
pushMatrix();
translate(v.x, v.y, v.z);
fill(0);
noStroke();
sphere(1);
popMatrix();
}
for (int i = 0; i < 3; i ++) {
PVector p1 = loc.get(minIdxs[i]);
PVector p2 = loc.get(minIdxs[(i+1)%3]);
stroke(255, 0, 0);
line(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
}
}
Also the L-System was created by following this tutorial: https://www.youtube.com/watch?v=qF8LGLVrwfo