so I'm trying to reproduce this graphics program here for my java class.
This is what I've come up with so far:
import processing.core.PApplet;
public class Assignment09b extends PApplet {
// Create arrays to stort the x & y values of the mouse
int [] xArray = new int [100];
int [] yArray = new int [100];
public void setup(){
//Runs at 60Fps
size(500, 500);
}
public void draw(){
//Changes the background each frame
background(0);
//Stores the x&y values of the mouse in the arrays
for (int i = 0; i < xArray.length; i++){
xArray[i] = this.mouseX;
yArray[i] = this.mouseY;
}
//SHOULD print out the snake using series of ellipses
for (int i = 0; i < xArray.length; i++){
//Generates a random color each time
fill(random(255), random(255), random(255));
ellipse(xArray[i], yArray[i], 25, 25);
}
}
}
I have a few ideas as to what the problem might be:
Because I'm in a loop, its just spawning one ellipse really quickly but I don't know how to have it spawn them simultaneously
It might be an issue with the frame rate speed maybe?
I'm an incompetent programmer :/
Please guys can you please give me some advice as to what I may be doing wrong or not at all. Thank you!
The problem is you're setting all the values at the same time here:
//Stores the x&y values of the mouse in the arrays
for (int i = 0; i < xArray.length; i++){
xArray[i] = this.mouseX;
yArray[i] = this.mouseY;
}
You only want to update 1 element in the array and have the others shift by one: the 'oldest' value goes out, the new value comes in. You can manually use a reverse for loop (from the end of the array to the front excepting the 1st element) or use arrayCopy:
private void updateArrays(int x,int y){
arrayCopy(xArray, 0, xArray, 1, xArray.length-1);//shift all elements backwards by 1
arrayCopy(yArray, 0, yArray, 1, yArray.length-1);//so x at index 99 goes 98, 98 to 97, etc. excepting index 0
xArray[0] = x;//finally add the newest value
yArray[0] = y;//at the start of the array (so in the next loop it gets shifted over by 1) like the above values
}
which makes the full listing:
import processing.core.PApplet;
public class Assignment09b extends PApplet {
// Create arrays to stort the x & y values of the mouse
int [] xArray = new int [100];
int [] yArray = new int [100];
public void setup(){
//Runs at 60Fps
size(500, 500);
}
public void draw(){
//Changes the background each frame
background(0);
updateArrays(mouseX,mouseY);
//SHOULD print out the snake using series of ellipses
for (int i = 0; i < xArray.length; i++){
//Generates a random color each time
fill(random(255), random(255), random(255));
ellipse(xArray[i], yArray[i], 25, 25);
}
}
private void updateArrays(int x,int y){
arrayCopy(xArray, 0, xArray, 1, xArray.length-1);//shift all elements backwards by 1
arrayCopy(yArray, 0, yArray, 1, yArray.length-1);//so x at index 99 goes 98, 98 to 97, etc. excepting index 0
xArray[0] = x;//finally add the newest value
yArray[0] = y;//at the start of the array (so in the next loop it gets shifted over by 1) like the above values
}
}
Since this is an exercise I recommend playing with for loops and arrays more.
It's something you'll end up using quite a lot and worth practicing/getting the hang of.
Goodluck!
var xArray = new Array(100);
var yArray = new Array(100);
function setup(){
createCanvas(500, 500);
}
function draw(){
//Changes the background each frame
background(0);
updateArrays(mouseX,mouseY);
//SHOULD print out the snake using series of ellipses
for (var i = 0; i < xArray.length; i++){
//Generates a random color each time
fill(random(255), random(255), random(255));
ellipse(xArray[i], yArray[i], 25, 25);
}
}
function updateArrays(x,y){
arrayCopy(xArray, 0, xArray, 1, xArray.length-1);//shift all elements backwards by 1
arrayCopy(yArray, 0, yArray, 1, yArray.length-1);//so x at index 99 goes 98, 98 to 97, etc. excepting index 0
xArray[0] = x;//finally add the newest value
yArray[0] = y;//at the start of the array (so in the next loop it gets shifted over by 1) like the above values
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>
Related
I'm trying to make a drawing panel that draws little circles with numbers in it, going from 0 to 9. However, the for loop, for one reason or another, keeps skipping 0. I've tried setting i to -1, but that doesn't change anything. Conversely when I set the condition to i < 11, it draws all numbers from 1 to 10.
Here's the code so far:
`
// Draws boxed ovals using a while loop.
import java.awt.*;
public class DrawLoop
{
public static void main(String[] args)
{
DrawingPanel panel = new DrawingPanel(502, 252);
panel.setBackground(Color.CYAN);
Graphics g = panel.getGraphics();
String iValue = "";
int sizeX = 50; // size of boxes
int sizeY = 25;
int i;
for (i = 0; i < 10; i++) { // start at i = 0
int cornerX = i*50; // calculate upper left corner
int cornerY = i*25;
g.setColor(Color.WHITE);
g.fillOval(cornerX + 5, cornerY + 5, sizeX-10, sizeY-10);
g.setColor(Color.BLACK);
g.drawRect(cornerX, cornerY, sizeX, sizeY);
iValue = "" + i;
g.drawString(iValue, cornerX - 29, cornerY - 8);
}
}
}
`
Tried to make a drawing panel that drew numbers from 0-9, loop skips 0 and only does 1-9.
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
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 relatively new to programming, and i'm trying to create a program that creates a purple ball where i click that moves to the right until it is off the screen, where i can have unlimited balls on the screen at once. I've made a program that does this, but i can only have one on the screen at once, if i click a second time, the first ball disappears and is replaced with a new one. Oh, and when i click a second time, the ball doesn't start where the cursor is, it starts from where the last ball was on the X-Axis.
Help please!
Here's the code:
int moveX, moveY;
void setup() {
background(255);
moveY = 200;
moveX = 0;
size(500,400);
}
void mouseClicked() {
moveY = mouseY;
moveX++;
}
void draw() {
if (moveX >= 1){
background(255);
fill(255, 0, 255);
ellipse(moveX, moveY, 40, 40);
moveX++;
}
}
As donfuxx suggests, giving each ball it's own coordinates.
One way to do this is using an array to store multiple values(coordinates).
To do this you need to get familiar with for loops and arrays.
They may look scary at first, but once you get the hang of them they're quite easy.
Wherever you can think of a situation where repetition is needed, you can use a for loop to make your life easier.
For loop have the following syntax:
for keyword (3 elements: a start point,an end point(condition) and an increment,(separated by the ; character)
Let's say you want to move from a(0) to b(10) one step at a time:
for(int currentPos = 0 ; currentPos < 10; currentPos++){
println("step: " + currentPos);
}
If you can walk, you can also skip :)
for(int currentPos = 0 ; currentPos < 10; currentPos+=2){
println("step: " + currentPos);
}
even backwards if you want:
for(int currentPos = 10 ; currentPos > 0; currentPos--){
println("step: " + currentPos);
}
This is very useful when traversing all sort of data(coordinates of a ball in a scene, etc.)
How do you organize your data ? You place it in a list or array.
An array contains elements of the same type and has a set length.
The syntax to declare an array is like so:
ObjectType[] nameOfArray;
and you can initialize an empty array:
int[] fiveNumbers = new int[5];//new keyword then the data type and length in sq.brackets
or you can initialize the array with values:
String[] words = {"ini","mini","miny","moe"};
You access elements in an array using square brackets and the index of the object in the list you want to access. Arrays have a length property so you can easily count objects.
background(255);
String[] words = {"ini","mini","miny","moe"};
for(int i = 0 ; i < words.length; i++){
fill(map(i,0,words.length, 0,255));
text(words[i],10,10*(i+1));
}
Now back to your original question.
Here is your code using for loops and arrays:
int ballSize = 40;
int maxBalls = 100;//maximum number of balls on screen
int screenBalls = 0;//number of balls to update
int[] ballsX = new int[maxBalls];//initialize an empty list/array of x coordinates
int[] ballsY = new int[maxBalls];//...and y coordinates
void setup() {
size(500, 400);
fill(255, 0, 255);
}
void mouseClicked() {
if (screenBalls < maxBalls) {//if still have room in our arrays for new ball coordinates
ballsX[screenBalls] = mouseX;//add the current mouse coordinates(x,y)
ballsY[screenBalls] = mouseY;//to the coordinate arrays at the current ball index
screenBalls++;//increment the ball index
}
}
void draw() {
println(screenBalls);
background(255);
for (int i = 0 ; i < screenBalls; i++) {//start counting from 0 to how many balls are on screen
ballsX[i]++;//increment the x of each ball
if(ballsX[i]-ballSize/2 > width) ballsX[i] = -ballSize/2;//if a ball goes off screen on the right, place it back on screen on the left
ellipse(ballsX[i], ballsY[i], ballSize, ballSize);//display each ball
}
}
There are multiple ways to tackle this. Arrays have fixed size. If you don't want to be constrained by that you can use an ArrayList (sort of a variable size array). Later you might want to look into how you can make an object that can update and draw itself. Have fun!
The code below will produce randomly generated circles of different colors. I need to be able to specify the color of the circle by it's size so that the loop will produce the same pattern of circles in different locations. This needs to be done with a 2d array. I know this is probably not that difficult, but I can't seem to grasp the concept.
Here are the directions and my code.
Thanks!
Set up a 2-D, int colors[][], array with 6 rows, one for each circle, and 3 columns, one for each element (Red, Green, Blue) of the colors to be used. In the above display the color values were randomly generated in the range 0 to 255 at the beginning of the program. Then for each diameter[i], color[i][0], color[i][1] and color[i][2] were used for the RGB levels.
import java.io.*;
import java.util.*;
import java.awt.*;
public class Lab10 {
/**
* #param args
*/
public static void main(String[] args) {
Scanner console=new Scanner (System.in);
Random r = new Random();
int [] color= new int [3];
color[0]=r.nextInt(256);
color[1]=r.nextInt(256);
color[2]=r.nextInt(256);
System.out.println("Please enter 6 integer values. The values should be in descending order and in the range 100 to 1.");
int[] diameters=new int[6];
int colors[][] = new int [6][3];
for(int i=0; i<6; i++){
diameters[i]=console.nextInt();//values entered
}
for (int i=0; i<diameters.length; i++) {
for (int j = 0; j < color.length; j++) {
colors[i][j]=colors[i][j];
}
}
int panelX = 400, panelY = 400;
DrawingPanel panel = new DrawingPanel(panelX, panelY);
panel.setBackground(Color.WHITE);
Graphics g = panel.getGraphics();
for (int i=0; i<10; i++){
int centerX=r.nextInt(350);
int centerY=r.nextInt(350);
for(int value:diameters){
g.setColor(new Color(r.nextInt(256),r.nextInt(256), r.nextInt(256)));
g.fillOval(centerX - value , centerY - value, 2 * value, 2 * value);
}
}
}
}
Hint
To break the concept for you.
int color[6][3] is your array.
To randomly generate the color values
create an object of class Random
Random random = new Random();
Do a loop on rows of color
for(int i=0;i<6;i++)
{
for(int j=0;j<3;j++)
color[i][j]= random.nextInt(255);
}
Now draw the circle like for diameter[i] ,
refer to color[i][0],color[i][1],color[i][2] for its rgb values
So if I got this right, you want to draw circles randomly, and you want the color to be dependent on diameter.
Here is my solution to that problem: pastebin
Also, i tried to show how it can be done both with and without java 8, so don't be confused about it.
Here is how it should look like: