I have a super simple script that creates a circle with alternating "slice" colors
let slices = 12;
function setup() {
createCanvas(400, 400);
noStroke();
}
function draw() {
background(220);
translate(width/2, height/2);
let inc = TWO_PI/slices;
let c = 0
for (let i = 0; i < TWO_PI+inc; i+=inc) {
if (c % 2 == 0) {
fill('white')
} else {
fill('black')
}
arc(0, 0, width/2, width/2, i, i+inc);
c++
}
}
How can I do this same thing but with a square (or a triangle, hexagon, etc.)? That is, I want the alternating slice colors but encapsulated in a square rather than a circle. I am not sure how to do this since I used arc() to create the slices. Is there some way I can create a mask or something? Or is there an easier solution to my problem?
You can take your pattern and apply it to an arbitrary shape using the mask() function on p5.Image. Alternately you could find the intersections between each ray that makes up each pie slice with the perimeter of your shape and use the intersection points and the definition of your shape to construct an pie slice that would fit inside the specified shape, but this would be much more complicated.
Here's an example. Click to change shapes.
let slices = 12;
let pattern;
let masked;
let density;
const MaskTypes = ['circle', 'square', 'triangle', 'text'];
let ix = 0;
function setup() {
createCanvas(400, 400);
density = pixelDensity();
let g = createGraphics(width, height);
g.noStroke();
g.translate(width / 2, height / 2);
const inc = TWO_PI / slices;
// fill the screen
const d = sqrt(width * width + height * height);
let c = 0;
for (let i = 0; i < TWO_PI + inc; i += inc) {
if (c % 2 == 0) {
g.fill('white');
} else {
g.fill('black');
}
g.arc(0, 0, d, d, i, i + inc);
c++;
}
pattern = createImage(width * density, height * density);
pattern.copy(g, 0, 0, width, height, 0, 0, width * density, height * density);
updateMask();
}
function mouseClicked() {
ix = (ix + 1) % MaskTypes.length;
updateMask();
}
function updateMask() {
let m = makeMask(MaskTypes[ix]);
masked = createImage(width * density, height * density);
masked.copy(pattern, 0, 0, width * density, height * density, 0, 0, width * density, height * density);
masked.mask(m);
}
function makeMask(type) {
let g = createGraphics(width, height);
g.noStroke();
g.fill(0);
g.translate(width / 2, height / 2);
switch (type) {
case 'circle':
g.circle(0, 0, width / 2);
break;
case 'square':
g.rect(-width / 4, -height / 4, width / 2, height / 2);
break;
case 'triangle':
g.triangle(-width / 4, height / 4, 0, -height / 4, width / 4, height / 4);
break;
case 'text':
g.textAlign(CENTER, CENTER);
g.textSize(96);
g.text("Hello!", 0, 0);
break;
}
let mask = createImage(width * density, height * density);
mask.copy(g, 0, 0, width, height, 0, 0, width * density, height * density);
return mask;
}
function draw() {
background(220);
image(masked, 0, 0, width, height)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>