How to constrain randomness - javascript

I'm drawing a random shape with vertices onto a canvas.
Sometimes the shape is very narrow and small.
Is there a way to constrain the randomness so this wont happen.
As I am very new to p5 any tips would be appreciated.
Thanks for your time and help
let noOfShapes = 3;
function setup(){
createCanvas(1240, 1754);
noLoop();
background(0,230)
colorMode(RGB)
rectMode(CENTER);
strokeWeight(3);
}
function draw(){
//fill(56, 37, 34);
for(let x = 0; x < noOfShapes; x++) {
beginShape();
stroke(255);
fill(25, 255, 255,100);
//noFill();
for(let y = 2; y < 6; y++) {
vertex(random(10,width), random(10,width))
// vertex(random(10,width), random(10,width))
// vertex(random(10,width), random(10,width))
// vertex(random(10,width), random(10,width))
}
endShape(CLOSE);
}
stroke(255);
for(let x=20; x<= width; x = x+20){
blendMode(DODGE);
//fill(200,200,200)
stroke(255);
beginShape();
vertex(x, 0)
vertex(x, height+20)
endShape();
}
}

Create a list of random numbers for the x and y coordinates:
rx = []; ry = [];
for (let y = 0; y < 4; y++) {
rx.push(random(10, width-20));
ry.push(random(10, height-20));
}
Compute the difference between the minimum (min) and maximum (max) for each list:
drx = max(rx) - min(rx);
dry = max(ry) - min(ry);
Define a threshold an repeat the process as long any of the differences is below the threshold:
let threshold = 200;
do {
// [...]
}
while (drx < threshold || dry < threshold)
The algorithm can be further improved, by taking into account the distance between the points along 45° diagonals. Use the Dot product to calculate the distances:
rd1.push(rx[y]*0.707 + ry[y]*0.707);
rd2.push(rx[y]*0.707 - ry[y]*0.707);
Use the random coordinates to generate the shape:
let threshold = 400;
let rx, ry, drx, dry, rd1, rd2, drd1, drd2;
do {
rx = []; ry = []; rd1 = []; rd2 = [];
for (let y = 0; y < 4; y++) {
rx.push(random(10, width-20));
ry.push(random(10, height-20));
rd1.push(rx[y]*0.707 + ry[y]*0.707);
rd2.push(rx[y]*0.707 - ry[y]*0.707);
}
drx = max(rx) - min(rx);
dry = max(ry) - min(ry);
drd1 = max(rd1) - min(rd1);
drd2 = max(rd2) - min(rd2);
}
while (drx < threshold || dry < threshold || drd1 < threshold || drd2 < threshold)
beginShape();
stroke(255);
fill(25, 255, 255,100);
//noFill();
for (let y = 0; y < rx.length; y++) {
vertex(rx[y], ry[y]);
}
endShape(CLOSE);
let noOfShapes = 1;
function setup(){
createCanvas(1240, 1754);
noLoop();
background(0,230)
colorMode(RGB)
rectMode(CENTER);
strokeWeight(3);
}
function draw(){
for(let x = 0; x < noOfShapes; x++) {
let threshold = 400;
let rx, ry, drx, dry, rd1, rd2, drd1, drd2;
do {
rx = []; ry = []; rd1 = []; rd2 = [];
for (let y = 0; y < 4; y++) {
rx.push(random(10, width-20));
ry.push(random(10, height-20));
rd1.push(rx[y]*0.707 + ry[y]*0.707);
rd2.push(rx[y]*0.707 - ry[y]*0.707);
}
drx = max(rx) - min(rx);
dry = max(ry) - min(ry);
drd1 = max(rd1) - min(rd1);
drd2 = max(rd2) - min(rd2);
}
while (drx < threshold || dry < threshold || drd1 < threshold || drd2 < threshold)
beginShape();
stroke(255);
fill(25, 255, 255,100);
//noFill();
for (let y = 0; y < rx.length; y++) {
vertex(rx[y], ry[y]);
}
endShape(CLOSE);
}
stroke(255);
for(let x=20; x<= width; x = x+20){
blendMode(DODGE);
//fill(200,200,200)
stroke(255);
beginShape();
vertex(x, 0)
vertex(x, height+20)
endShape();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>

Related

How to make a grid of ellipses with subdivisions

I have created a circle with subdivisions (function CircleSubDivs) in p5.js and now want to generate a grid filled with those. Ideally the ellipse would also be disproportionate if the width and height of a tile is not the same, or if the amount of tiles were to be controlled by the mouse position the ellipse would move flexibly.
This was my inspiration
This is my code so far:
// let colors = [
// "#F48668 ",
// "#5D2E8C",
// "#F7F7F7"
// ];
function CircleSubDivs(x, y, size) {
let amount = 13;
let r = 360 / amount;
for (let j = 0; j < 10; j++) {
for (let i = 0; i < amount; i++) {
fill(random(255));
let s = map(j, 0, 8, width, 100);
arc(width / 2, height / 2, s, s, radians(r * i), radians(r * (i + 1)));
}
}
}
function setup() {
createCanvas(500, 500);
frameRate(1);
}
function draw() {
background("#0F0F0F");
noStroke();
let tilesX = 3;
let tilesY = 2;
let tileW = width / tilesX;
let tileH = height / tilesY;
for (let x = 0; x < tilesX; x++) {
for (let y = 0; y < tilesY; y++) {
CircleSubDivs(x * tileW, y * tileH, tileW, tileH);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
As you can see I have created a grid and tried to store my function for the ellipse with divisions in there, but it just shows me one single ellipse when I run it. I would really appreciate some help :)
Your parameters to your function are unused, so the function does the same thing every time.
You might try something like:
function drawSubdividedCircle(x, y, size, segments=13, layers=10) {
const r = 360 / segments;
for (let i = 0; i < segments; i++) {
for (let j = 0; j < layers; j++) {
fill(random(255));
const s = map(j, 0, layers, size, 0);
arc(
x + size / 2,
y + size / 2,
s,
s,
radians(r * i),
radians(r * (i + 1))
);
}
}
}
function setup() {
createCanvas(500, 500);
frameRate(1);
}
function draw() {
background("#0F0F0F");
noStroke();
const tilesX = 3;
const tilesY = 2;
const tileSize = width / tilesX;
for (let x = 0; x < tilesX; x++) {
for (let y = 0; y < tilesY; y++) {
drawSubdividedCircle(x * tileSize, y * tileSize, tileSize);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>

How to make a grid of moiré circles in p5.js?

I'm attempting to make a grid where every tile is filled with a single "moire-style" ellipse (a circle with circles inside).
function setup() {
createCanvas(500, 500);
ellipseMode(CENTER);
}
function draw() {
background(255);
noFill();
strokeWeight(3);
stroke(0);
let tilesX = 3;
let tilesY = tilesX;
let tileW = width / tilesX;
let tileH = height / tilesY;
for (let x = 0; x < tilesX; x++) {
for (let y = 0; y < tilesY; y++) {
moire(tilesX, tilesY, tileW);
}
}
function moire(x, y, size) {
for (var i = 1; i <= tileW; i = i + 8) {
ellipse(width / 2, height / 2, 2 * i, 2 * i);
translate(tilesX, tilesY);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
This is what I have in my p5.js sketch but the moire elements don't align to the tiles.
The following demo will create a grid of moire circles:
let _numRows = 3;
let _numCols = 3;
let _colGap = 30;
let _rowGap = 30;
function moire(x, y, size) {
for (var i = 1; i <= size; i = i + 8) {
ellipse(x, y, 2 * i, 2 * i);
translate(3, 3);
}
}
function setup() {
createCanvas(500, 500);
ellipseMode(CENTER);
}
function draw() {
background(255);
noFill();
strokeWeight(3);
stroke(0);
let _xOffset = width/5;
let _yOffset = height/5;
for (let j = 0; j < _numCols; j++) {
for (let k = 0; k < _numRows; k++) {
push();
moire(_xOffset + j * (100 + _colGap), _yOffset + k * (100 + _rowGap), 50);
pop();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>

Javascript Error on p5.js (Unexpected end of input)

I have a problem in p5.js. I was creating this for a school project, and everything works (I think). However, when I run it, it shows me "Unexpected end of input." And the error says "Unrecoverable syntax error (100% scanned). I'm not sure what's wrong.
I included the code below in case if there's something wrong with my code. Thanks for your time!
/* GLOBAL VARIABLES */
let meteorX = []; // Store X position of the meteor
let meteorY = [0, 0 ,0 ,0 ,0]; // Store Y position of the meteor
let meteorDiameter = []; // Store diameter of the meteor
let catcherWidth = 40; // Store diameter of the catcher
let catcherHeight = 60
let distance; //distance between catcher and meteor
let speed = []; //Speed of meteor
let score = 0; //number of meteor caught
//Declare a variables to store the image files
let bgImage;
let meteorImage;
let catcherImage;
// Only runs once
function setup() {
createCanvas(400, 400);
//Load the images into the sketch and store in variables
bgImage = loadImage('bgImage.jpg');
meteorImage = loadImage('meteor.png');
catcherImage = loadImage('rocketship.png');
}
//populate meteorX values
for(let i = 0; i < 5; i++){
meteorX[i] = random(0, width);
}
//populate initial diameter
for(let i = 0; i < 5; i++){
meteorDiameter[i] = random(10,40)
}
//populate initial speed
for(let i = 0; i < 5; i++){
speed[i] = random(0.5,4)
}
// Runs over and over in a loop
function draw() {
// Draws the image starting from the top left corner
imageMode(CORNER);
background(bgImage);
noStroke();
//Draw meteors to screen
for(let i = 0; i < 5; i++){
ellipse(meteorX[i], meteorY[i], meteorDiameter[i],meteorDiameter[i])
}
for(let i = 0; i <5; i++){
meteorY[i] = meteorY[i] + speed[i]
}
// Draw the catcher to follow the mouse
image(catcherImage, mouseX, mouseY, catcherWidth, catcherHeight);
for(let i = 0; i < 5; i++){
distance[i] = dist(meteorX[i], meteorY[i], mouseX, mouseY);
//whenever a meteor intersects with catcher
for(let i = 0; i < 5; i++){
if(distance[i] < 15){
meteorY[i] = 0
meteorX[i] = random(0,width)
meteorDiameter = random(10,40)
score = score + 1
}
}
//when meteor touches bottom of screen
for(let i = 0; i < 5; i++){
if(distance[i] > height){
meteorY[i] = 0;
meteorX[i] = random(0, width);
meteorDiameter[i] = random(10,40)
}
}
// Test to see if cat has intersected with screen bottom
if(meteorY > height) {
meteorY = 0;
meteorX = random(width);
speed = random(1,4);
meteorDiameter = random(10,30);
}
// put score on bottom
fill(0, 254, 202);
textAlign(RIGHT);
textSize(15);
text('Score: ' + score, 80, 385);
if(score == 10){
meteorY = width + 10;
meteorX = height + 10;
speed = 0;
//win message
textAlign(CENTER);
textSize(20);
text('You Win!', width/2, height/2);
textSize(14);
text('Click the mouse anywhere to restart.', width/2, height/2 + 30);
// Restart the game if player clicks the mouse.
if(mouseIsPressed){
restart();
}
}
}
function restart(){
meteorY = 0
meteorX = 100
speed = 0.5
score = 0
}```
Just close the draw function with }, you opened but not closed.
function draw() {
// Draws the image starting from the top left corner
imageMode(CORNER);
background(bgImage);
noStroke();
//Draw meteors to screen
for(let i = 0; i < 5; i++){
ellipse(meteorX[i], meteorY[i], meteorDiameter[i],meteorDiameter[i])
}
for(let i = 0; i <5; i++){
meteorY[i] = meteorY[i] + speed[i]
}
// Draw the catcher to follow the mouse
image(catcherImage, mouseX, mouseY, catcherWidth, catcherHeight);
for(let i = 0; i < 5; i++){
distance[i] = dist(meteorX[i], meteorY[i], mouseX, mouseY);
//whenever a meteor intersects with catcher
for(let i = 0; i < 5; i++){
if(distance[i] < 15){
meteorY[i] = 0
meteorX[i] = random(0,width)
meteorDiameter = random(10,40)
score = score + 1
}
}
//when meteor touches bottom of screen
for(let i = 0; i < 5; i++){
if(distance[i] > height){
meteorY[i] = 0;
meteorX[i] = random(0, width);
meteorDiameter[i] = random(10,40)
}
}
// Test to see if cat has intersected with screen bottom
if(meteorY > height) {
meteorY = 0;
meteorX = random(width);
speed = random(1,4);
meteorDiameter = random(10,30);
}
// put score on bottom
fill(0, 254, 202);
textAlign(RIGHT);
textSize(15);
text('Score: ' + score, 80, 385);
if(score == 10){
meteorY = width + 10;
meteorX = height + 10;
speed = 0;
//win message
textAlign(CENTER);
textSize(20);
text('You Win!', width/2, height/2);
textSize(14);
text('Click the mouse anywhere to restart.', width/2, height/2 + 30);
// Restart the game if player clicks the mouse.
if(mouseIsPressed){
restart();
}
}
}
} <--- This one is missing

Avoid crossing of geometries

I would like to work with this code:
let vertices = [];
function setup() {
createCanvas(windowWidth, windowHeight);
let numberOfVertices = random(3, 11); //pick the number of points
for (let i = 0; i < numberOfVertices; i++) {
vertices.push(createVector(random(width), random(height))); //add a point to the list of points
}
}
function draw() {
background(220);
fill(255, 0, 0);
noStroke();
beginShape();
for (let i = 0; i < vertices.length; i++) {
vertex(vertices[i].x, vertices[i].y);//place each vertex
}
endShape();
}
* {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.3.1/lib/p5.js"></script>
Unfortunately, the geometries sometimes cross. How is it possible to avoid that?
Would be very thankful for help!
Calculate the center of the bounding box of the points and sort the points by the angle of the vector from the center to the point:
let ax = vertices.map(v => v.x);
let ay = vertices.map(v => v.y);
let cx = (Math.min(...ax) + Math.max(...ax)) / 2;
let cy = (Math.min(...ay) + Math.max(...ay)) / 2;
vertices.sort((a, b) => {
let v1 = p5.Vector.sub(a, createVector(cx, cy));
let v2 = p5.Vector.sub(b, createVector(cx, cy));
return Math.atan2(v1.y, v1.x) - Math.atan2(v2.y, v2.x);
});
In the following example, the lines that form the center point to the vertices are drawn to visualize the algorithm:
let vertices = [];
let cx, cy
function setup() {
createCanvas(windowWidth, windowHeight);
let numberOfVertices = random(3, 11); //pick the number of points
for (let i = 0; i < numberOfVertices; i++) {
vertices.push(createVector(random(width), random(height))); //add a point to the list of points
}
let ax = vertices.map(v => v.x);
let ay = vertices.map(v => v.y);
cx = (Math.min(...ax) + Math.max(...ax)) / 2;
cy = (Math.min(...ay) + Math.max(...ay)) / 2;
vertices.sort((a, b) => {
let v1 = p5.Vector.sub(a, createVector(cx, cy));
let v2 = p5.Vector.sub(b, createVector(cx, cy));
return Math.atan2(v1.y, v1.x) - Math.atan2(v2.y, v2.x);
});
}
function draw() {
background(220);
fill(255, 0, 0);
noStroke();
beginShape();
for (let i = 0; i < vertices.length; i++) {
vertex(vertices[i].x, vertices[i].y);//place each vertex
}
endShape();
stroke(255, 255, 255);
strokeWeight(3)
for (let i = 0; i < vertices.length; i++) {
line(cx, cy, vertices[i].x, vertices[i].y);
}
}
<script src="https://cdn.jsdelivr.net/npm/p5#1.3.1/lib/p5.js"></script>
Demo

draggable backgroun

I want to achieve something like an infinite drag like the one in Konva js Can anyone help me with this. I try varius things but non of them were ok. Im new in p5js and javascript. Please for any hints. Only this element prevents me from completing the entire project.
var grid;
var current_img;
var BgCat1 = [];
var layerOne;
let show_grid = false;
There may be a more elegant solution, but here I draw an extra cell on each side of the grid to handle the wraparound, so a 12x12 grid with 10x10 visible. See it run here: https://editor.p5js.org/rednoyz/full/uJCADfZXv
let dim = 10, sz;
let xoff = 0, yoff = 0;
function setup() {
createCanvas(400, 400);
sz = width/ dim;
}
function mouseDragged() {
xoff += mouseX - pmouseX;
yoff += mouseY - pmouseY;
}
function draw() {
background(255);
for (let i = 0; i < dim+2; i++) {
for (let j = 0; j < dim+2; j++) {
let x = ((xoff + j * sz) % (width+sz)) - sz;
if (x < -sz) x += width+sz;
let y = ((yoff + i * sz) % (height+sz)) - sz;
if (y < -sz) y += height+sz;
rect(x, y, sz, sz);
text(i * 10 + j, x + sz/2, y + sz/2);
}
}
}

Categories

Resources