Drawing a line that is an element of an array in p5.js - p5.js

In my current p5.js project, I'm randomly plotting several lines on the canvas - so my background is in the setup function, but I wish to highlight the current one with a thicker stroke. In order to know which line was the last one drawn, I'm pushing them to a list to redraw just the last one later with a different stroke value. But I don't know how to display on the canvas such a line that is an element of an array. Somebody could help me?
What I have done so far:
//just inicializing the x-coordinates of the limit point of my line
let ax = 0;
let bx = 0;
//variables for the current line and the array of lines
let linha;
let linhas = [];
function setup() {
createCanvas(400, 400);
background(0);
}
function draw() {
//randomly choosing the x-coordinates of the limit point of my line
ax = random(0,400);
bx = random(0, 400);
stroke(255, 50)
//plotting the current line
linha = line(ax, 0, bx, 400);
//putting it on the array
linhas.push(line);
//what I wish to be doing is something like
/*
strokeWeight(5);
'print' linhas(linhas.length - 1) //where by print I mean display on the screen the last of the lines and only it, i.e. in the n+1 iteration, I don't want to have the n-line with that thicker stroke.
*/
}

Something like below will help. I've added comments on the relevant lines.
//just saving the indices for better readibility and to make it less bug-prone.
const x = 0,
start = 0,
y = 1,
end = 1;
const myLines = [];
function setup() {
createCanvas(400, 400);
//move the entire codeblock below to draw() if you randomize it on every render.
//add your random lines as such
myLines.push([[10, 20],[30, 40]]);
myLines.push([[20, 20],[20, 60]]);
myLines.push([[30, 20],[10, 300]]);
myLines.push([[40, 20],[100, 120]]);
myLines.push([[50, 20],[40, 80]]);
background(220);
//drawing the lines from the array
for (let i = 0; i < myLines.length; i++) {
line(
myLines[i][start][x],
myLines[i][start][y],
myLines[i][end][x],
myLines[i][end][y]
);
}
//getting the last element in the array to draw a thicker line
strokeWeight(5);
line(
myLines[myLines.length - 1][start][x],
myLines[myLines.length - 1][start][y],
myLines[myLines.length - 1][end][x],
myLines[myLines.length - 1][end][y]
);
}

Related

How do I use the X and Y values from an object from touches in P5js?

This is my first week playing with P5js and Processing so be gentle.
I've got the following P5js code where I'm looking at touch values. By pressing multi-points on a touch screen brings up more circles anchored to a central position.
What I'd like to know is how do I call the x value for object 1 that's printed in the console? or y value for object 0? how would i state them in the code?
What I'd like to do is use these values to change the dimensions of a shape in the middle of the screen, like something in object 0 driving the height of the shape or object 1 on the the x or y values driving strokeWeight or colour . However I'm in my first week and completely lost to how to use these values in the code.
function setup() {
createCanvas(windowWidth, windowHeight);
background(200);
}
function draw() {
background(255);
fill(255, 0, 0);
strokeWeight(0)
for (var i = 0; i < touches.length; i++) {
fill(255);
strokeWeight(3)
ellipse(touches[i].x, touches[i].y, 50, 50);
line(touches[i].x, touches[i].y, windowWidth / 2, windowHeight / 2);
fill(255);
ellipse(windowWidth / 2, windowHeight / 2, 10, 10);
print(touches);
}
}
// do this prevent default touch interaction
function mousePressed() {
return false;
}
document.addEventListener('gesturestart', function(e) {
e.preventDefault();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
or Sketch file is here
any help would be muchly muchly appreciated, i'm a newb trying to find my way
There is only one mistake in it which I found till now, the color of the background and the fill colors are the same! you may change them to actually see the shapes, lines etc.

how to interpolate between two consecutive points with a smooth curve in p5.js

I intend to have an ellipse move smoothly between the stop points while keep rotating. It'll rotate for 1sec at point (20,50), transition to (40,70) on a smooth curve (bezier or random polynomial) and rotate till 3sec and move on to (160,190)
The current issue is that it jumps between stop points rather than move smoothly.
var angle=0;
var x=[20,40,160] // x coordinates for stop points
var y=[50,70,190] // y coordinates for stop points
var t=[1000,2000,4000] // time for stop points
var i=0;
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
frameRate(30);
translate(x[i],y[i]);
rotate(angle);
if (millis() >= t[i] & millis() < t[i+1]){
i+=1
}
fill(0);
ellipse(0,0, 20, 80);
angle++
}
There are a lot of different ways to do this, and which approach you take depends on exactly how you want your code to behave.
Similar to the answer to your last question, you need to show the movement between the points.
Right now you're moving directly from one point to another. You need to show the intermediate steps.
Here are a few things to look into:
The frameCount variable holds the current frame number. This is useful for exact timing of behaviors that you want to trigger on specific frames.
The millis() function returns the number of milliseconds the sketch has been running. This is useful for duration-based logic, where you want to do something after a certain number of seconds.
The lerp() function allows you to calculate values that change over time.
You could also use delta values, where you move the X and Y values by some amount each frame.
Here's an example of that last approach:
var circleX = 20;
var circleY = 20;
var mode = 'move right';
function setup() {
createCanvas(400, 400);
}
function draw() {
background(200);
ellipse(circleX, circleY, 20, 20);
if (mode == 'move right') {
circleX++;
if (dist(circleX, circleY, 380, 20) < 1) {
mode = 'move down';
}
} else if (mode == 'move down') {
circleY++;
if (dist(circleX, circleY, 380, 380) < 1) {
mode = 'move left';
}
} else if (mode == 'move left') {
circleX--;
if (dist(circleX, circleY, 20, 380) < 1) {
mode = 'move up';
}
} else if (mode == 'move up') {
circleY--;
if (dist(circleX, circleY, 20, 20) < 1) {
mode = 'move right';
}
}
}
But please note that this code is just an example, and there's a ton of room for improvement here. The important thing is that you need to move the scene a little bit each frame, instead of going directly from one point to another.

Wrong color when using loadPixels to copy image

I am trying to duplicate the ellipse such that its center point of the copy is the inverse of the original position in both axes using the pixels[] array to copy pixel data to new locations. However, the copy does not have the same color (rather than black, it is pink) as the original; the colors are not copying as I intended. Why is this?
This is the code:
function setup() {
createCanvas(600, 600);
smooth(8);
rectMode(CENTER);
fill(250);
stroke(32);
strokeWeight(10);
}
function draw() {
draw_();
}
function draw_() {
background(250);
ellipse(100, 100, 100, 100)
loadPixels();
for(var i=0; i<pixels.length/2; i++)
pixels[pixels.length-i-1] = pixels[i];
updatePixels();
}
This is the result:
According to the reference, the pixels array contains information in red, green, blue, and alpha components depending on index, like this:
pixels[0] = red(myColor);
pixels[1] = green(myColor);
pixels[2] = blue(myColor);
pixels[3] = alpha(myColor);
pixels[4] = red(myColor);
pixels[5] = green(myColor);
pixels[6] = blue(myColor);
pixels[7] = alpha(myColor);
//...
So if you simply reverse the array, you aren't going to just reverse the image. You're also going to mess up the colors: you'll swap red and alpha, and green and blue.
You might be better off using the get() function, which takes an x and y argument and returns a full color. Again, more info can be found in the reference.
Thanks a lot for Kevin's help, it's worked.
for(var i=0; i<pixels.length/2; i+=4) {
pixels[pixels.length-i-4] = pixels[i];
pixels[pixels.length-i-3] = pixels[i+1];
pixels[pixels.length-i-2] = pixels[i+2];
pixels[pixels.length-i-1] = pixels[i+3];
}

Using radians and iterating over array of hex colour values

I have a number of hex values stored in an array. I am using the array index to increase the angle in radian and display a series of ellipses in a circle display a series of ellipses. Difficult to explain but I have a pen. The issue is that when I use a for loop I'm not sure how to use the index to colour the ellipses.
const colors = ['#b1ede8','#db9a78','#eed4ad','#a989b2']
function setup(){
createCanvas(windowWidth,windowHeight)
}
function draw(){
background(255,100,100)
translate(width/2,height/2)
noStroke();
prizes(colors,200)
}
function windowResized(){
resizeCanvas(windowWidth,windowHeight)
}
function prizes(data,radius){
for(i = 0 ; i < TWO_PI ; i+=TWO_PI/data.length)
{
let x = radius * cos(i);
let y = radius * sin(i);
i is now a floating value in radians and the fill code does not work.
fill(colors[i])
ellipse(x,y,20)
}
}
Thanks in advance
const colors = ['#b1ede8','#db9a78','#eed4ad','#a989b2']
function setup(){
createCanvas(windowWidth,windowHeight)
}
function draw(){
background(255,100,100)
translate(width/2,height/2)
noStroke();
prizes(colors,200)
}
function windowResized(){
resizeCanvas(windowWidth,windowHeight)
}
function prizes(data,radius){
var j = 0;
for(i = 0 ; i < TWO_PI ; i+=TWO_PI/data.length)
{
let x = radius * cos(i);
let y = radius * sin(i);
fill(data[j])
ellipse(x,y,20)
j++;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.16/p5.js"></script>
I think i found the problem. You used i to get the color value. But You don't increment i by 1. So you will get invalide numbers. I made a new variable j to index the color. Is this the result You are looking for?

How do I get a random number to stay fixed with slick?

I'm a beginner in Java as well as with the slick tools. I want to make a game that has different coloured cubes randomly placed within a certain area of the window.
I use two for-loops and call for a random number in render. I get the cubes placed exactly as I want, but the problems is that they flicker in all colours. I guess it has to do with how I call for a random number and that it gets updated with FPS?!
Please help me!!
public void render(GameContainer gc, StateBasedGame sdg, Graphics g) throws SlickException {
//set background
Image background = (new Image("res/background.png")).getScaledCopy(800, 500);
g.drawImage(background, 0, 0);
//set gamescape
blue = (new Image("res/blue.png")).getScaledCopy(20,20);
green = (new Image("res/green.png")).getScaledCopy(20,20);
red = (new Image("res/red.png")).getScaledCopy(20,20);
int xvalue = 300;
int yvalue = 400;
for (int a = 1; a < 20; a++) {
for (int i = 1; i < 10; i++) {
r = rand.nextInt(3);
if(r==0){g.drawImage(blue,xvalue,yvalue);}
else if(r==1){g.drawImage(red, xvalue, yvalue);}
else{g.drawImage(green, xvalue, yvalue);}
xvalue = xvalue+20;
}
yvalue = yvalue - 20;
xvalue = xvalue -180;
}
}
Your problem is that you generate a new random number each time you redraw the scene.
To resolve this, you may have to create an array in which you store the generated color of each cube. And each time you redraw your images, you just read each color value in the array.

Resources