How to make a grid with one bigger tile - javascript

I'm working on this program for a grid that generates geometric shapes and I want the function drawSubdividedCircle to always appear only once at a random position on the grid and take up the with and height of two rows/columns. I think the main problem is stacking because when i run it now the objects overlap. This is basically my goal:
And this is the code:
let colors = [
"#F7F7F7",
"#141414",
"#f07f45",
"#bcaad6",
"#60388e",
"#00afc6",
"#aae3ea"
];
let tilesX = 5;
let tilesY = 5;
let tileW;
let tileH;
let tileSize;
function drawSubdividedCircle (x, y, size, segments, layers) {
segments = random (1,13);
layers = random (1,13);
const r = 360 / segments;
for (let i = 0; i < segments; i++)
{
for (let j = 0; j < layers; j++)
{
fill(random(colors));
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, SVG);
tileW = width / tilesX;
tileH = height / tilesY;
tileSize = (tileW, tileH);
}
function draw() {
noStroke();
frameRate(2);
for (let x = 0; x < tilesX; x++)
{
for (let y = 0; y < tilesY; y++)
{
let r = random(1);
if (r < 0.5)
{
ellipse((x - 0.5) * tileSize, (y - 0.5) * tileSize, tileSize, tileSize);
fill(random(colors));
}
else
{
rect(x * tileSize, y * tileSize, tileSize, tileSize);
fill(random(colors));
}{ drawSubdividedCircle(x * tileSize, y * tileSize, tileSize*2);
fill(random(colors));
}
}
}
//save("sketch1.6.5.svg");
//print("saved svg");
//noLoop();
}

Added an array to keep track of the state of each individual tile. Could be optimized for sure, but this works just fine.
https://editor.p5js.org/Kroepniek/sketches/MsFlcY3kl
let colors = [
"#F7F7F7",
"#141414",
"#f07f45",
"#bcaad6",
"#60388e",
"#00afc6",
"#aae3ea"
];
let tilesX = 5;
let tilesY = 5;
let tileW;
let tileH;
let tileSize;
let tileIsFree;
let subdividedCirclesCount = 0;
const subdividedCirclesLimit = 1;
function reinitTileStateArray()
{
tileIsFree = [];
for (let x = 0; x < tilesX; x++)
{
for (let y = 0; y < tilesY; y++)
{
tileIsFree[y * tilesX + x] = true;
}
}
subdividedCirclesCount = 0;
}
function drawSubdividedCircle (x, y, size, segments, layers) {
subdividedCirclesCount++;
segments = random (1,13);
layers = random (1,13);
const r = 360 / segments;
for (let j = 0; j < layers; j++)
{
for (let i = 0; i < segments; i++)
{
fill(random(colors));
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(2);
tileW = width / tilesX;
tileH = height / tilesY;
tileSize = (tileW, tileH);
}
function draw() {
background(0);
noStroke();
reinitTileStateArray();
let randomChance = 0.5;
for (let y = 0; y < tilesY; y++)
{
for (let x = 0; x < tilesX; x++)
{
let r = random();
if (tileIsFree[y * tilesX + x])
{
fill(random(colors));
rect(x * tileSize, y * tileSize, tileSize, tileSize);
if (r < randomChance)
{
fill(random(colors));
ellipse((x + 0.5) * tileSize, (y + 0.5) * tileSize, tileSize, tileSize);
}
else if (subdividedCirclesCount < subdividedCirclesLimit && tileIsFree[y * tilesX + x + 1])
{
drawSubdividedCircle(x * tileSize, y * tileSize, tileSize * 2);
tileIsFree[y * tilesX + x] = false;
tileIsFree[y * tilesX + x + 1] = false;
tileIsFree[(y + 1) * tilesX + x] = false;
tileIsFree[(y + 1) * tilesX + x + 1] = false;
randomChance = 0.75;
}
}
}
}
//save("sketch1.6.5.svg");
//print("saved svg");
//noLoop();
}

Related

How to change the rows or columns of a grid without messing up the content

I want to be able to implement more rows or columns to the grid depending on the format. (For example if i want to use the sketch on a horizontal 16x9 screen, there would have to be more rows than columns) Right now it only works if the format/canvas is square.
As soon as I change the number of tiles or the size of the canvas, the elements jump around.
Here is my sketch:
let colors = [
"#F7F7F7",
"#141414",
"#FB2576",
"#F48668",
"#67339E",
"#00A6A6",
"#78FFD6"
];
function drawSubdividedCircle(x, y, size, segments, layers) {
segments = random (1,13);
layers = random (1,13);
const r = 360 / segments;
for (let i = 0; i < segments; i++) {
for (let j = 0; j < layers; j++) {
fill(random(colors));
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(2);
}
function draw() {
noStroke();
let tilesX = 5;
let tilesY = 5;
let tileW = width / tilesX;
let tileH = height / tilesY;
const tileSize = width / tilesX;
for (let x = 0; x < tilesX; x++) {
for (let y = 0; y < tilesY; y++) {
rect(x*tileW, y*tileH, tileW, tileH);
fill(random(colors));
push();
for (let x = 0; x < tilesX; x++) {
for (let y = 0; y < tilesY; y++) {
let r = random(1);
if (r < 0.5) {
ellipseMode(CORNER);
ellipse(x*tileW, y*tileH, tileW, tileH);
fill(random(colors));
} else {
ellipseMode(CENTER);
drawSubdividedCircle(x * tileSize, y * tileSize, tileSize);
fill(random(colors));
pop();
}
}
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
I changed your code a little.. Removed two redundant for-loops, it is much faster now.
When you want to make your program responsive, you have to make a choice. Do you want the circles to scale when you change the resolution or maybe do you want the amount of rows/columns to change when the resolution changes? There are several possibilities, I made it now to keep the amount of tiles, and use the smaller value of the 'tileW' and 'tileH' to remain the circle shape.
let colors = [
"#F7F7F7",
"#141414",
"#FB2576",
"#F48668",
"#67339E",
"#00A6A6",
"#78FFD6"
];
var tilesX = 5;
var tilesY = 5;
var tileW;
var tileH;
var tileSize;
function drawSubdividedCircle(x, y, size, segments, layers)
{
segments = random (1,13);
layers = random (1,13);
const r = 360 / segments;
for (let i = 0; i < segments; i++)
{
for (let j = 0; j < layers; j++)
{
fill(random(colors));
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(550, 500);
ellipseMode(CENTER);
//frameRate(2);
tileW = width / tilesX;
tileH = height / tilesY;
tileSize = min(tileW, tileH);
}
function draw()
{
background(0);
noStroke();
for (let x = 0; x < tilesX; x++)
{
for (let y = 0; y < tilesY; y++)
{
rect(x * tileSize, y * tileSize, tileSize, tileSize);
fill(random(colors));
let r = random(1);
if (r < 0.5)
{
ellipse((x - 0.5) * tileSize, (y - 0.5) * tileSize, tileSize, tileSize);
fill(random(colors));
}
else
{
drawSubdividedCircle(x * tileSize, y * tileSize, tileSize);
fill(random(colors));
}
}
}
}

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>

p5js, How to make the color follow with the array?

I want the color follow with the array, not to change the color every frame,
Like the second code color show on the array, but it is colorMode.
I don't know how making the colorMode to be the picked color, or Picked color follow with array motion.
How can I do?
https://editor.p5js.org/fruit66677788/sketches/8wiulg7m7
https://editor.p5js.org/fruit66677788/sketches/vnH3tYpJO
In order for each curve to have a consistent color from frame to frame you need to either deterministically select the same color based on the value of x, or you need to reset the random seed so that the random sequence of colors are selected in the same order each frame.
Option 1:
stroke(colors[round(x - offset) % colors.length]);
var colors = ["#ed3441", "#ffb03b", "#36acf5", "#ffd630", "#084e86", "#fcfeff"];
function setup() {
createCanvas(500, 500);
}
function draw() {
background(200);
let offset = -width / 10;
noFill();
let xStep = (height + offset * 2) / 75;
for (let x = offset; x <= height - offset; x += xStep) {
let num = int(1 + 1.25 * noise(x / 150, frameCount / 100));
let arr = [PI / 8];
for (let i = 0; i < num; i++) {
let n = sq(sq(noise(x / 10, frameCount / 200))) * (width - offset * 75);
n = max(n, 1);
arr.push(n);
}
drawingContext.setLineDash(arr);
drawingContext.lineDashOffset = x - frameCount / 10;
strokeWeight(xStep / 0.8);
strokeCap(ROUND);
stroke(colors[round(x - offset) % colors.length]);
beginShape();
for (let y = offset; y < width - offset; y += 5) {
let nx =
x + tan(y / 330 + x / 300) * 150 * cos(frameCount / 20) * sin(x / 300);
vertex(y, nx);
}
endShape();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
Option 2:
In setup()
seed = random(0, 9999999);
In draw() prior to the for loop:
randomSeed(seed);
var colors = ["#ed3441", "#ffb03b", "#36acf5", "#ffd630", "#084e86", "#fcfeff"];
let seed;
function setup() {
createCanvas(500, 500);
seed = random(0, 9999999);
}
function draw() {
randomSeed(seed);
background(200);
let offset = -width / 10;
noFill();
let xStep = (height + offset * 2) / 75;
for (let x = offset; x <= height - offset; x += xStep) {
let num = int(1 + 1.25 * noise(x / 150, frameCount / 100));
let arr = [PI / 8];
for (let i = 0; i < num; i++) {
let n = sq(sq(noise(x / 10, frameCount / 200))) * (width - offset * 75);
n = max(n, 1);
arr.push(n);
}
drawingContext.setLineDash(arr);
drawingContext.lineDashOffset = x - frameCount / 10;
strokeWeight(xStep / 0.8);
strokeCap(ROUND);
stroke(random(colors));
beginShape();
for (let y = offset; y < width - offset; y += 5) {
let nx =
x + tan(y / 330 + x / 300) * 150 * cos(frameCount / 20) * sin(x / 300);
vertex(y, nx);
}
endShape();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

Making a Mesh Plane in WebGL with Triangles

I'm trying to create a triangulated plane in WebGL and I have the following code. However, when I render this in the browser, it just gives me a vertical line parallel to the y-axis.
var quads = 200;
for (var y = 0; y <= quads; ++y) {
var v = y / quads * 40;
for (var x = 0; x <= quads; ++x) {
var u = x / quads * 40;
recipient.vertices.push( vec3(u, v, 1))
recipient.normals.push( vec3(0, 0, 1))
}
}
var rowSize = (quads + 1);
for (var y = 0; y < quads; ++y) {
var rowOffset0 = (y + 0) * rowSize;
var rowOffset1 = (y + 1) * rowSize;
for (var x = 0; x < quads; ++x) {
recipient.indices.push(rowOffset0, rowOffset0 + 1, rowOffset1);
recipient.indices.push(rowOffset1, rowOffset0 + 1, rowOffset1 + 1);
}
}
Also as a followup question, I was hoping to get some tips on how to make a curved surface with this plane, something similar to a hill.
There was a bug in the original answer. It should be this
var quads = 200;
for (var y = 0; y <= quads; ++y) {
var v = y / quads;
for (var x = 0; x <= quads; ++x) {
var u = x / quads;
recipient.vertices.push( vec3(u, v, 1))
recipient.normals.push( vec3(0, 0, 1))
}
}
var rowSize = (quads + 1);
for (var y = 0; y < quads; ++y) {
var rowOffset0 = (y + 0) * rowSize;
var rowOffset1 = (y + 1) * rowSize;
for (var x = 0; x < quads; ++x) {
var offset0 = rowOffset0 + x;
var offset1 = rowOffset1 + x;
recipient.indices.push(offset0, offset0 + 1, offset1);
recipient.indices.push(offset1, offset0 + 1, offset1 + 1);
}
}
Fixed in original answer as well.
function Vec3Array() {
this.array = [];
this.push = function(v3) {
this.array.push.apply(this.array, v3);
}
}
function vec3(x, y, z) {
return [x, y, z];
}
var recipient = {
vertices: new Vec3Array(),
normals: new Vec3Array(),
indices: [],
};
var quads = 200;
for (var y = 0; y <= quads; ++y) {
var v = y / quads;
for (var x = 0; x <= quads; ++x) {
var u = x / quads;
recipient.vertices.push( vec3(u, v, 1))
recipient.normals.push( vec3(0, 0, 1))
}
}
var rowSize = (quads + 1);
for (var y = 0; y < quads; ++y) {
var rowOffset0 = (y + 0) * rowSize;
var rowOffset1 = (y + 1) * rowSize;
for (var x = 0; x < quads; ++x) {
var offset0 = rowOffset0 + x;
var offset1 = rowOffset1 + x;
recipient.indices.push(offset0, offset0 + 1, offset1);
recipient.indices.push(offset1, offset0 + 1, offset1 + 1);
}
}
var gl = twgl.getWebGLContext(document.getElementById("c"));
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
var arrays = {
position: recipient.vertices.array,
indices: recipient.indices,
};
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
var scale = 2 + (Math.sin(time) * 0.5 + 0.5) * 16;
var uniforms = {
matrix: [
scale, 0, 0, 0,
0, scale, 0, 0,
0, 0, 1, 0,
-1, -1, 0, 1,
],
};
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.setUniforms(programInfo, uniforms);
twgl.drawBufferInfo(gl, gl.LINE_STRIP, bufferInfo);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
html, body {
width: 100%;
height: 100%;
margin: 0;
}
canvas {
width: 100%;
height: 100%;
}
<script src="https://twgljs.org/dist/twgl.min.js"></script>
<script id="vs" type="notjs">
attribute vec4 position;
uniform mat4 matrix;
void main() {
gl_Position = matrix * position;
}
</script>
<script id="fs" type="notjs">
precision mediump float;
void main() {
gl_FragColor = vec4(1,0,0,1);
}
</script>
<canvas id="c"></canvas>

Categories

Resources