Skip to content

Instantly share code, notes, and snippets.

@dribnet
Forked from uwcc/.block
Last active September 9, 2019 02:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dribnet/8f611cc0956fa74c32655c26504d5081 to your computer and use it in GitHub Desktop.
Save dribnet/8f611cc0956fa74c32655c26504d5081 to your computer and use it in GitHub Desktop.
MDDN342 Assignment 2: Randomised Collections
license: mit

PS2 MDDN 342 2019

In-class example of:

  • how to add the "focus" parameter to focusedRandom (in arrangement.js)
  • how one random variable (in this case earSize in arrangement.js) can depend on another random variable (faceColor)
  • how to add more sliders to the editor (editor.html and editor.js)
/*
* This program draws your arrangement of faces on the canvas.
*/
const canvasWidth = 960;
const canvasHeight = 500;
let curRandomSeed = 0;
let lastSwapTime = 0;
const millisPerSwap = 5000;
function setup () {
// create the drawing canvas, save the canvas element
let main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
curRandomSeed = int(focusedRandom(0, 1000));
// rotation in degrees
angleMode(DEGREES);
}
function changeRandomSeed() {
curRandomSeed = curRandomSeed + 1;
lastSwapTime = millis();
}
// global variables for colors
const bg_color1 = [225, 206, 187];
function mouseClicked() {
changeRandomSeed();
}
function draw () {
if(millis() > lastSwapTime + millisPerSwap) {
changeRandomSeed();
}
// reset the random number generator each time draw is called
resetFocusedRandom(curRandomSeed);
// clear screen
background(50);
noStroke();
let faceWidth;
let earSize, earDist;
let faceColor;
let gridWidth = 10;
let gridHeight = 6;
// draw a 5x3 grid of faces
let w = canvasWidth / gridWidth;
let h = canvasHeight / gridHeight;
for(let i=0; i<gridHeight; i++) {
for(let j=0; j<gridWidth; j++) {
let y = h/2 + h*i;
let x = w/2 + w*j;
// center face
push();
translate(x, y);
scale(w/25, h/25);
let faceColorSpinner = int(focusedRandom(1, 9));
if(faceColorSpinner >= 2 && faceColorSpinner <= 3) {
faceColor = 1;
}
else if(faceColorSpinner >= 4 && faceColorSpinner <= 6) {
faceColor = 2;
}
else if(faceColorSpinner == 7) {
faceColor = 3;
}
else {
faceColor = 4;
}
if(faceColor == 1) {
earSize = focusedRandom(5, 20, 1);
}
else {
earSize = focusedRandom(0, 8, 2);
}
earDist = focusedRandom(0, 10, 4);
drawMickeyMouse(earSize, earDist, faceColor);
pop();
}
}
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
}
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.3/seedrandom.min.js"></script>
<script src="https://d3js.org/d3-random.v1.min.js"></script>
<script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="face_code.js"></script>
<script language="javascript" type="text/javascript" src="editor.js"></script>
<style>
body { padding: 0; margin: 0; }
.inner { position: absolute; }
#controls {
font: 300 12px "Helvetica Neue";
padding: 5;
margin: 5;
background: #f0f0f0;
opacity: 0.0;
-webkit-transition: opacity 0.2s ease;
-moz-transition: opacity 0.2s ease;
-o-transition: opacity 0.2s ease;
-ms-transition: opacity 0.2s ease;
}
#controls:hover { opacity: 0.9; }
</style>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
<a href="index.html">arrangement</a>
(<a href="arrangement.js">arrangement code</a>,
<a href="face_code.js">face code</a>)<br>
<a href="editor.html">editor</a>
(<a href="editor.js">editor code</a>,
<a href="face_code.js">face code</a>)<br>
<a href="sketch.html">sketch</a>
</div>
<div class="inner" id="controls" height="500px">
<table>
<tr>
<td>Ear Size</td>
<td id="slider1Container"></td>
</tr>
<tr>
<td>Ear Spacing</td>
<td id="slider2Container"></td>
</tr>
<tr>
<td>Colour</td>
<td id="slider3Container"></td>
</tr>
<tr>
<td>-----</td>
<td id="slider4Container"></td>
</tr>
<tr>
<td>------</td>
<td id="slider5Container"></td>
</tr>
<tr>
<td>Setting 6</td>
<td id="slider6Container"></td>
</tr>
<tr>
<td>Setting 7</td>
<td id="slider7Container"></td>
</tr>
<tr>
<td>Setting 8</td>
<td id="slider8Container"></td>
</tr>
<tr>
<td>Setting 9</td>
<td id="slider9Container"></td>
</tr>
<tr>
<td>Setting 10</td>
<td id="slider10Container"></td>
</tr>
<tr>
<td>Show Target</td>
<td id="checkbox1Container"></td>
</tr>
<tr>
<td>Face</td>
<td id="selector1Container"></td>
</tr>
</table>
</div>
</div>
</table>
</body>
/*
* This editor shows the possible faces that can be created
*/
const canvasWidth = 960;
const canvasHeight = 500;
let slider1, slider2, slider3, slider4, slider5;
let slider6, slider7, slider8, slider9, slider10;
let faceSelector;
let faceGuideCheckbox;
function setup () {
// create the drawing canvas, save the canvas element
let main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
// create sliders
slider1 = createSlider(0, 100, 50);
slider2 = createSlider(0, 100, 50);
slider3 = createSlider(0, 100, 50);
slider4 = createSlider(0, 100, 50);
slider5 = createSlider(0, 100, 50);
slider6 = createSlider(0, 100, 50);
slider7 = createSlider(0, 100, 50);
slider8 = createSlider(0, 100, 50);
slider9 = createSlider(0, 100, 50);
slider10 = createSlider(0, 100, 50);
slider1.parent('slider1Container');
slider2.parent('slider2Container');
slider3.parent('slider3Container');
slider4.parent('slider4Container');
slider5.parent('slider5Container');
slider6.parent('slider6Container');
slider7.parent('slider7Container');
slider8.parent('slider8Container');
slider9.parent('slider9Container');
slider10.parent('slider10Container');
faceGuideCheckbox = createCheckbox('', false);
faceGuideCheckbox.parent('checkbox1Container');
faceSelector = createSelect();
faceSelector.option('1');
faceSelector.option('2');
faceSelector.option('3');
faceSelector.value('1');
faceSelector.parent('selector1Container');
}
const bg_color = [225, 206, 187];
function draw () {
strokeWeight(0.2);
let mode = faceSelector.value();
background(bg_color);
let s1 = slider1.value();
let s2 = slider2.value();
let s3 = slider3.value();
let s4 = slider4.value();
let s5 = slider5.value();
let s6 = slider6.value();
let s7 = slider7.value();
let s8 = slider8.value();
let s9 = slider9.value();
let s10 = slider10.value();
let show_face_guide = faceGuideCheckbox.checked();
// use same size / y_pos for all faces
let face_size = canvasWidth / 5;
let face_scale = face_size / 10;
let face_y = height / 2;
let face_x = width / 2;
push();
translate(face_x, face_y);
scale(face_scale);
push();
if (mode == '1') {
// draw 1st face
let earSize = map(s1, 0, 100, 0, 10);
let earDist = map(s2, 0, 100, 0, 10);
// let faceColor = int(map(s3, 0, 100, 1, 4));
let faceColor = int(map(s3, 0, 100, 1, 5));
drawMickeyMouse(earSize, earDist, faceColor);
}
pop();
if(show_face_guide) {
strokeWeight(0.1);
rectMode(CORNER);
noFill()
stroke(0, 0, 255);
// ellipse(0, 0, 20, 20);
rect(-10, -10, 20, 20);
line( 0, -11, 0, -10);
line( 0, 10, 0, 11);
line(-11, 0,-10, 0);
line( 11, 0, 10, 0);
}
pop();
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
}
/*
* This file should contain code that draws your faces.
*
* Each function takes parameters and draws a face that is within
* the bounding box (-10, -10) to (10, 10).
*
* These functions are used by your final arrangement of faces as well as the face editor.
*/
/*
* earSize can vary from 0 to 10
* earDist is the distance between ears and varies from 0 to 10
* faceColor is 1,2,3,4 for yellow,blue,red, or violet respectively
*/
function drawMickeyMouse(earSize, earDist, faceColor) {
const yellow = color(255, 255, 0);
const blue = color(0, 0, 200);
const red = color(200, 0, 0);
const violet = color(150, 0, 150);
const error_green = color(0, 255, 0);
noStroke();
if(faceColor == 1) {
fill(yellow);
}
else if (faceColor==2) {
fill(blue);
}
else if (faceColor==3) {
fill(red);
}
else if (faceColor == 4) {
fill(violet);
}
else {
fill(error_green);
}
// head
ellipse(0, 2, 10);
let earRadius = map(earSize, 0, 10, 4, 7);
let earXPos = map(earDist, 0, 10, 3, 7);
ellipse(-earXPos, -5, earRadius);
ellipse( earXPos, -5, earRadius);
}
var canvasWidth = 960;
var canvasHeight = 500;
var sliders = [];
var faceSelector;
var curRandomSeed;
function setup () {
// create the drawing canvas, save the canvas element
var main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
curRandomSeed = int(focusedRandom(0, 100));
// create sliders
for(i=1; i<=4; i++) {
var slider = createSlider(0, 100, 50);
var parentStr = 'slider' + i + 'Container';
slider.parent(parentStr);
sliders.push(slider);
}
sliders[0].value(0);
sliders[1].value(100);
sliders[2].value(0);
sliders[3].value(50);
randButton = createButton('randomize');
randButton.mousePressed(changeRandomSeed);
randButton.parent('selector1Container');
// rotation in degrees
angleMode(DEGREES);
}
function changeRandomSeed() {
curRandomSeed = curRandomSeed + 1;
}
// global variables for colors
var bg_color = [200, 200, 200];
var fg_color = [255, 255, 255];
var stroke_color = [0, 0, 0];
var num_samples = 2000;
var num_bins = 20;
function draw () {
resetFocusedRandom(curRandomSeed);
var min = sliders[0].value();
var max = sliders[1].value();
var focus = Math.floor(map(sliders[2].value(), 0, 100, 0, 10))
var mean = sliders[3].value();
if(mean < min) {
mean = min;
sliders[3].value(mean);
}
if(mean > max) {
mean = max;
sliders[3].value(mean);
}
var samples = []
var bins = Array(num_bins)
for(var i=0; i<num_bins; i++) {
bins[i] = 0;
}
var s, b;
for(var i=0; i<num_samples; i++) {
s = focusedRandom(min, max, focus, mean);
b = Math.floor(s*4 / num_bins);
bins[b] = bins[b] + 1;
}
background(bg_color);
fill(fg_color);
for(var i=0; i<num_bins; i++) {
x = i * width / num_bins;
y = bins[i];
rect(x, height-y, width/num_bins, y);
}
fill(0);
var info = "min " + min + " max " + max + " focus " + focus + " mean " + mean;
textSize(36);
text(info, 300, 100);
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
}
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.3/seedrandom.min.js"></script>
<script src="https://d3js.org/d3-random.v1.min.js"></script>
<script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="z_focused_random.js"></script>
<script language="javascript" type="text/javascript" src="face_code.js"></script>
<script language="javascript" type="text/javascript" src="arrangement.js"></script>
<style>
body { padding: 0; margin: 0; }
.inner { position: absolute; }
#controls {
font: 300 12px "Helvetica Neue";
padding: 5;
margin: 5;
background: #f0f0f0;
opacity: 0.0;
-webkit-transition: opacity 0.2s ease;
-moz-transition: opacity 0.2s ease;
-o-transition: opacity 0.2s ease;
-ms-transition: opacity 0.2s ease;
}
#controls:hover { opacity: 0.9; }
</style>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
<a href="index.html">arrangement</a>
(<a href="arrangement.js">arrangement code</a>,
<a href="face_code.js">face code</a>)<br>
<a href="editor.html">editor</a>
(<a href="editor.js">editor code</a>,
<a href="face_code.js">face code</a>)<br>
<a href="sketch.html">sketch</a>
</div>
<div class="inner" id="controls" height="500px">
<table>
<tr>
<td></td>
<td id="slider1Container"></td>
</tr>
<tr>
<td></td>
<td id="slider2Container"></td>
</tr>
<tr>
<td></td>
<td id="slider3Container"></td>
</tr>
<tr>
<td></td>
<td id="slider4Container"></td>
</tr>
<tr>
<td></td>
<td id="slider5Container"></td>
</tr>
<tr>
<td></td>
<td id="selector1Container"></td>
</tr>
</table>
</div>
</div>
</table>
</body>
{
"commits": [
{
"sha": "f7f76e38bd1c02c783d2a0e1ed815b555abf2560",
"name": "refined_distribution"
},
{
"sha": "abd752c765c87016a261b58ec508aa2c4677dae9",
"name": "FocusedRandom API"
},
{
"sha": "062bd19b1898d7f0018e6482257d90f3aeaec2e1",
"name": "weighted_selection"
},
{
"sha": "802c94f04fe74a5f701555a695be15e2570457ef",
"name": "two_face_types"
},
{
"sha": "6c45fb54eb95913f76ab652c20b79f88d3d3f590",
"name": "simple_collection"
}
]
}
<head>
<style> body {padding: 0; margin: 0;} </style>
</head>
<body style="background-color:white">
<img src="sketch.jpg" width="960" height="480"/>
<p>
<a href="index.html">arrangement</a>
(<a href="arrangement.js">arrangement code</a>,
<a href="face_code.js">face code</a>)<br>
<a href="editor.html">editor</a>
(<a href="editor.js">editor code</a>,
<a href="face_code.js">face code</a>)<br>
<a href="sketch.html">sketch</a>
</body>
function resetFocusedRandom() {
return Math.seedrandom(arguments);
}
function focusedRandom(min, max, focus, mean) {
// console.log("hello")
if(max === undefined) {
max = min;
min = 0;
}
if(focus === undefined) {
focus = 1.0;
}
if(mean === undefined) {
mean = (min + max) / 2.0;
}
if(focus == 0) {
return d3.randomUniform(min, max)();
}
else if(focus < 0) {
focus = -1 / focus;
}
let sigma = (max - min) / (2 * focus);
let val = d3.randomNormal(mean, sigma)();
if (val >= min && val < max) {
return val;
}
return d3.randomUniform(min, max)();
}
// note: this file is poorly named - it can generally be ignored.
// helper functions below for supporting blocks/purview
function saveBlocksImages(doZoom) {
if(doZoom == null) {
doZoom = false;
}
// generate 960x500 preview.jpg of entire canvas
// TODO: should this be recycled?
var offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = 960;
offscreenCanvas.height = 500;
var context = offscreenCanvas.getContext('2d');
// background is flat white
context.fillStyle="#FFFFFF";
context.fillRect(0, 0, 960, 500);
context.drawImage(this.canvas, 0, 0, 960, 500);
// save to browser
var downloadMime = 'image/octet-stream';
var imageData = offscreenCanvas.toDataURL('image/jpeg');
imageData = imageData.replace('image/jpeg', downloadMime);
p5.prototype.downloadFile(imageData, 'preview.jpg', 'jpg');
// generate 230x120 thumbnail.png centered on mouse
offscreenCanvas.width = 230;
offscreenCanvas.height = 120;
// background is flat white
context = offscreenCanvas.getContext('2d');
context.fillStyle="#FFFFFF";
context.fillRect(0, 0, 230, 120);
if(doZoom) {
// pixelDensity does the right thing on retina displays
var pd = this._pixelDensity;
var sx = pd * mouseX - pd * 230/2;
var sy = pd * mouseY - pd * 120/2;
var sw = pd * 230;
var sh = pd * 120;
// bounds checking - just displace if necessary
if (sx < 0) {
sx = 0;
}
if (sx > this.canvas.width - sw) {
sx = this.canvas.width - sw;
}
if (sy < 0) {
sy = 0;
}
if (sy > this.canvas.height - sh) {
sy = this.canvas.height - sh;
}
// save to browser
context.drawImage(this.canvas, sx, sy, sw, sh, 0, 0, 230, 120);
}
else {
// now scaledown
var full_width = this.canvas.width;
var full_height = this.canvas.height;
context.drawImage(this.canvas, 0, 0, full_width, full_height, 0, 0, 230, 120);
}
imageData = offscreenCanvas.toDataURL('image/png');
imageData = imageData.replace('image/png', downloadMime);
// call this function after 1 second
setTimeout(function(){
p5.prototype.downloadFile(imageData, 'thumbnail.png', 'png');
}, 1000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment