The idea for my assignment is a stylised face with watercolour-esque shading on one side. The watercolour-esque effect is created through cascading shaded areas to create something similar to a gradient. An outline is added to these to imitate how watercolour can dry and create a fringe effect.
Five of the sliders are in control of: the thickness of the top eyelid the colour of the eyes style of the lip how bright the face is hue of the entire face
In the training, the parameters were picked based on these: The hue of the face is determined by the shade of the hair. Bluer hue - darker hair colour Reder hue - lighter hair colour Masculine faces have thinner eye outlines and feminine faces have filled in lips. The eye lightness corresponded to the lightness of the eyes in the images. The shade depended on the skin tone of the images.
Image links: -https://unsplash.com/photos/6tHTXiSRUi8 -https://unsplash.com/photos/hOF1bWoet_Q -https://unsplash.com/photos/2qvxIr_DXGo -https://unsplash.com/photos/zCG05KP0Jiw -https://unsplash.com/photos/q0Uc8fFdrUo
<head>
<script language="javascript" type="text/javascript" src="p5.js"></script>
<script language="javascript" type="text/javascript" src="seedrandom.min.js"></script>
<script language="javascript" type="text/javascript" src="d3-random.v1.min.js"></script>
<script language="javascript" type="text/javascript" src="z_clmtrackr.js"></script>
<script language="javascript" type="text/javascript" src="z_model_pca_20_svm.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="z_face_system.js"></script>
<script language="javascript" type="text/javascript" src="z_kdTree.js"></script>
<script language="javascript" type="text/javascript" src="z_face-api.js"></script>
<script language="javascript" type="text/javascript" src="z_training_images.js"></script>
<script language="javascript" type="text/javascript" src="z_testing_images.js"></script>
<!-- 2020 -->
<script language="javascript" type="text/javascript" src="chen_face.js"></script>
<script language="javascript" type="text/javascript" src="cooper_face.js"></script>
<script language="javascript" type="text/javascript" src="hill_face.js"></script>
<script language="javascript" type="text/javascript" src="ho_face.js"></script>
<script language="javascript" type="text/javascript" src="howard_face.js"></script>
<script language="javascript" type="text/javascript" src="hu_face.js"></script>
<script language="javascript" type="text/javascript" src="idris_face.js"></script>
<script language="javascript" type="text/javascript" src="lee_face.js"></script>
<script language="javascript" type="text/javascript" src="luo_face.js"></script>
<script language="javascript" type="text/javascript" src="mckendry_face.js"></script>
<script language="javascript" type="text/javascript" src="mcsweeney_face.js"></script>
<script language="javascript" type="text/javascript" src="ng_face.js"></script>
<script language="javascript" type="text/javascript" src="nuesca_face.js"></script>
<script language="javascript" type="text/javascript" src="park_face.js"></script>
<script language="javascript" type="text/javascript" src="ruan_face.js"></script>
<script language="javascript" type="text/javascript" src="to_face.js"></script>
<script language="javascript" type="text/javascript" src="truong_face.js"></script>
<script language="javascript" type="text/javascript" src="tuala_face.js"></script>
<script language="javascript" type="text/javascript" src="wang_face.js"></script>
<script language="javascript" type="text/javascript" src="yee_face.js"></script>
<script language="javascript" type="text/javascript" src="zhang_face.js"></script>
<script language="javascript" type="text/javascript" src="zhao_face.js"></script>
<!-- 2019 -->
<script language="javascript" type="text/javascript" src="jaegers_face.js"></script>
<script language="javascript" type="text/javascript" src="kelly19_face.js"></script>
<script language="javascript" type="text/javascript" src="trewavas_face.js"></script>
<!-- 2018 -->
<script language="javascript" type="text/javascript" src="felizardo_face.js"></script>
<script language="javascript" type="text/javascript" src="jordan_face.js"></script>
<script language="javascript" type="text/javascript" src="joy_face.js"></script>
<script language="javascript" type="text/javascript" src="salazar_face.js"></script>
<!-- 2017 -->
<script language="javascript" type="text/javascript" src="campbell_face.js"></script>
<script language="javascript" type="text/javascript" src="dockerty_face.js"></script>
<script language="javascript" type="text/javascript" src="kelly_face.js"></script>
<script language="javascript" type="text/javascript" src="petris_face.js"></script>
<script language="javascript" type="text/javascript" src="prezo_runner.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:#323232">
<div class="outer">
<div class="inner" id="controls" height="500">
<table>
<tr>
<td>Lash Thickness</td>
<td id="slider1Container"></td>
</tr>
<tr>
<td>Eye Shade</td>
<td id="slider2Container"></td>
</tr>
<tr>
<td>Lip Style</td>
<td id="slider3Container"></td>
</tr>
<tr>
<td>Face Shade</td>
<td id="slider4Container"></td>
</tr>
<tr>
<td>Face Hue</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>setting 11</td>
<td id="slider11Container"></td>
</tr>
<tr>
<td>setting 12</td>
<td id="slider12Container"></td>
</tr>
<tr>
</tr>
<tr>
<td>show target</td>
<td id="sliderTintContainer"></td>
</tr>
<tr>
<td>Draw function</td>
<td id="selector1Container"></td>
</tr>
<tr>
<td>Face Draw</td>
<td id="checkbox1Container"></td>
</tr>
<tr>
<td>Face Targets</td>
<td id="checkbox2Container"></td>
</tr>
<tr>
<td>Face Points</td>
<td id="checkbox3Container"></td>
</tr>
<tr>
<td></td>
<td id="button1Container"></td>
</tr>
<tr>
<td></td>
<td id="button2Container"></td>
</tr>
<tr>
<td></td>
<td id="button3Container"></td>
</tr>
<tr>
<td></td>
<td id="button4Container"></td>
</tr>
</table>
</div>
<div>
<div id="canvasContainer"></div>
</div>
</div>
<pre>
<p id="output">
</p>
</pre>
</body>
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// these control the colors used
ch3_bodyPrimary = [204, 204, 204];
ch3_bodySecondary = [128, 128, 128];
ch3_detailPrimary = [0, 0, 0];
ch3_detailSecondary = [0, 0, 255];
function CampbellFace() {
// draw strokes with rounded joints
// strokeJoin(ROUND);
// set colour mode to HSB
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
colorMode(HSB);
strokeJoin(ROUND);
// variables of facial structure
var nose_pos = average_point(positions.nose_bridge);
var eye1_pos = average_point(positions.left_eye);
var eye2_pos = average_point(positions.right_eye);
var upperLip = average_point(positions.top_lip);
var bottomLip = average_point(positions.bottom_lip);
var face_pos = average_point(positions.chin);
var half_height = positions.chin[7][1] - nose_pos[1];
var face_width = positions.chin[positions.chin.length-1][0] - positions.chin[0][0];
var x = nose_pos[0];
var y = nose_pos[1];
var w = 2 * face_width;
var h = 2.5 * half_height;
// bolleans for whether face is looking left or right
var lookingLeft = false;
var lookingRight = false;
// compare nose landmarks to check if looking left or right
if(Math.abs(positions.nose_bridge[3][0] - positions.nose_bridge[0][0]) > 0.03){
if(positions.nose_bridge[3][0] < positions.nose_bridge[0][0])
lookingLeft = true;
if(positions.nose_bridge[3][0] > positions.nose_bridge[0][0])
lookingRight = true;
}
else {
lookingLeft = true;
}
// adjustable variables of character identity
var gender = map(this.genderValue, 0, 100, 0, 1);
var hair = map(this.hairValue, 0, 100, 80, 200);
var curlookDirection = map(this.lookDirection, 0, 100, -15, 15);
var curEyelidTop_height = map(this.eyelidTop_height, 0, 100, 0, 70);
var curEyelidBottom_height = map(this.eyelidBottom_height, 0, 100, 0, 70);
var curHue = map(this.hue, 0, 100, 0, 360);
var curSaturation = map(this.saturation, 0, 100, 0, 100);
var curBrightnessPrimary = map(this.brightness, 0, 100, 50, 100);
var curBrightnessSecondary = map(this.brightness, 0, 100, 20, 70);
// sets object scale
var extent = 0;
if(h < w) {
extent = h / 2;
}
else {
extent = w / 2;
}
var scale = extent / 220.0;
// draw left ear if male
// draw rectangle from a centre point
rectMode(CENTER)
// if male face and is looking left
if(gender == 1 & lookingLeft == true) {
// draw ear
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0] - (10 * scale), eye2_pos[1] - (100 * scale), 50 * scale, hair * scale, 100 * scale, 100 * scale, 0, 0);
}
// if male and is looking right
if(gender == 1 & lookingRight == true) {
// draw ear
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0] + (10 * scale), eye1_pos[1] - (100 * scale), 50 * scale, hair * scale, 100 * scale, 100 * scale, 0, 0);
}
// head
// draw rectangle from a centre point
rectMode(CENTER);
// draw face
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0], face_pos[1] - (70 * scale), 300 * scale, 320 * scale, 200 * scale, 200 * scale, 0, 0);
// draw dissection
fill(curHue, curSaturation, curBrightnessSecondary);
ellipse(face_pos[0], face_pos[1] + (90 * scale), 300 * scale, 80 * scale);
// draw bone
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(face_pos[0], face_pos[1] + (90 * scale), 150 * scale, 30 * scale);
// draw right ear if male
rectMode(CENTER);
// if male and looking left
if(gender == 1 & lookingLeft == true) {
// draw ear
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0] + (30 * scale), eye2_pos[1] - (100 * scale), 50 * scale, hair * scale, 100 * scale, 100 * scale, 0, 0);
//cover
noStroke();
fill(curHue, curSaturation, curBrightnessPrimary);
rectMode(CENTER);
rect(face_pos[0] + (30 * scale), eye2_pos[1] - (5 * scale), 70 * scale, 150 * scale);
}
// if male and looking right
if(gender == 1 & lookingRight == true) {
// draw ear
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0] - (30 * scale), eye1_pos[1] - (100 * scale), 50 * scale, hair * scale, 100 * scale, 100 * scale, 0, 0);
//cover
noStroke();
fill(curHue, curSaturation, curBrightnessPrimary);
rectMode(CENTER);
rect(face_pos[0] - (30 * scale), eye1_pos[1] - (5 * scale), 70 * scale, 150 * scale);
}
// features for when looking left
if(lookingLeft == true) {
// left eye
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale);
// pupil
noStroke();
fill(ch3_detailPrimary);
arc(eye1_pos[0] + curlookDirection * scale, eye1_pos[1], (30) * scale, (50) * scale, 20, 340, PIE);
// eyelid
strokeWeight(7 * scale);
stroke(ch3_detailPrimary);
fill(curHue, curSaturation, curBrightnessSecondary);
// top eyelid
arc(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale, 265 - curEyelidTop_height, 275 + curEyelidTop_height, CHORD);
// bottom eyelid
arc(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale, 85 - curEyelidBottom_height, 95 + curEyelidBottom_height, CHORD);
// eyebrow
stroke(ch3_detailPrimary)
noFill();
arc(eye1_pos[0], (eye1_pos[1]), 130 * scale, 110 * scale, 240, 300);
// nose
// if female draw bird style
if(gender < 1) {
// translate to an offset of the centre of the face
push();
translate(face_pos[0] - (100 * scale), face_pos[1] - (70 * scale));
// draw beak
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(curHue, curSaturation, curBrightnessSecondary);
arc(0, 0, 250 * scale, 150 * scale, 335, 385, PIE);
// draw mouth
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
line(5 * scale, 0 * scale, 80 * scale, 0 * scale);
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
noFill();
arc(110 * scale, 0 * scale, 50 * scale, 50 * scale, 140, 210);
// teeth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
// check teeth value
if(Math.abs(upperLip[1] - bottomLip[1]) > 0.28) {
arc(40 * scale, 0 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) > 0.2) {
arc(60 * scale, 0 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) < 0.2) {
}
pop();
}
// if male draw dog style
if(gender == 1) {
// translate to an offset of centre of the face
push();
translate(face_pos[0] - (130 * scale), face_pos[1] - (100 * scale));
// draw snout
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
// top snout
rectMode(CORNER);
rect(0, 0, 140 * scale, 45 * scale, 18 * scale, 0, 0, 18 * scale);
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
// bottom snout
rect(30 * scale, 45 * scale, 110 * scale, 35 * scale, 14 * scale, 0, 0, 14 * scale);
noStroke();
fill(curHue, curSaturation, curBrightnessPrimary);
// re-fill / cover
rect(130 * scale, -7 * scale, 60 * scale, 100 * scale);
// draw nose
noStroke();
fill(ch3_detailPrimary);
push();
rotate(10);
ellipse(0 * scale, 0 * scale, 40 * scale, 28 * scale);
pop();
// mouth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
noFill();
arc(155 * scale, 40 * scale, 50 * scale, 50 * scale, 140, 210);
// teeth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
// check teeth value
if(Math.abs(upperLip[1] - bottomLip[1]) > 0.28) {
arc(70 * scale, 45 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) > 0.2) {
arc(90 * scale, 45 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) < 0.2) {
}
pop();
}
// right eye
// eye
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale);
// pupil
noStroke();
fill(ch3_detailPrimary);
arc(eye2_pos[0] + curlookDirection * scale, eye2_pos[1], (30) * scale, (50) * scale, 20, 340, PIE);
// eyelid
strokeWeight(7 * scale);
stroke(ch3_detailPrimary);
fill(curHue, curSaturation, curBrightnessSecondary);
// top eyelid
arc(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale, 265 - curEyelidTop_height, 275 + curEyelidTop_height, CHORD);
// bottom eyelid
arc(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale, 85 - curEyelidBottom_height, 95 + curEyelidBottom_height, CHORD);
// eyebrow
stroke(ch3_detailPrimary)
noFill();
arc(eye2_pos[0], (eye2_pos[1]), 130 * scale, 110 * scale, 240, 300);
}
// facial feature if looking right
if(lookingRight == true) {
// right eye
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale);
// pupil
noStroke();
fill(ch3_detailPrimary);
arc(eye2_pos[0] + curlookDirection * scale, eye2_pos[1], (30) * scale, (50) * scale, 20, 340, PIE);
// eyelid
strokeWeight(7 * scale);
stroke(ch3_detailPrimary);
fill(curHue, curSaturation, curBrightnessSecondary);
// top eyelid
arc(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale, 265 - curEyelidTop_height, 275 + curEyelidTop_height, CHORD);
// bottom eyelid
arc(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale, 85 - curEyelidBottom_height, 95 + curEyelidBottom_height, CHORD);
// eyebrow
stroke(ch3_detailPrimary)
noFill();
arc(eye2_pos[0], (eye2_pos[1]), 130 * scale, 110 * scale, 240, 300);
// nose
// if female draw bird style
if(gender < 1) {
// translate to an offset of the centre of the face
push();
translate(face_pos[0] + (120 * scale), face_pos[1] - (70 * scale));
// draw beak
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(curHue, curSaturation, curBrightnessSecondary);
arc(0, 0, 250 * scale, 150 * scale, 155, 205, PIE);
// draw mouth
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
line(-5 * scale, 0 * scale, -80 * scale, 0 * scale);
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
noFill();
arc(-110 * scale, 0 * scale, 50 * scale, 50 * scale, 320, 390);
// teeth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
// check teeth value
if(Math.abs(upperLip[1] - bottomLip[1]) > 0.28) {
arc(-40 * scale, 0 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) > 0.2) {
arc(-60 * scale, 0 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) < 0.2) {
}
pop();
}
// if male draw dog style
if(gender == 1) {
// translate to an offset of the centre of the face
push();
translate(face_pos[0], face_pos[1] - (100 * scale));
// draw snout
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
// top snout
rectMode(CORNER);
rect(0, 0, 140 * scale, 45 * scale, 0, 18 * scale, 18 * scale, 0);
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
// bottom snout
rect(0 * scale, 45 * scale, 110 * scale, 35 * scale, 0, 14 * scale, 14 * scale, 0);
noStroke();
fill(curHue, curSaturation, curBrightnessPrimary);
// re-fill / cover
rect(-50 * scale, -7 * scale, 60 * scale, 100 * scale);
// draw nose
noStroke();
fill(ch3_detailPrimary);
push();
rotate(-10);
ellipse(140 * scale, 30 * scale, 40 * scale, 28 * scale);
pop();
// mouth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
noFill();
arc(-15 * scale, 50 * scale, 50 * scale, 50 * scale, 320, 390);
// teeth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
// check teeth value
if(Math.abs(upperLip[1] - bottomLip[1]) > 0.28) {
arc(40 * scale, 45 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) > 0.2) {
arc(60 * scale, 45 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) < 0.2) {
}
pop();
}
// left eye
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale);
// pupil
noStroke();
fill(ch3_detailPrimary);
arc(eye1_pos[0] + curlookDirection * scale, eye1_pos[1], (30) * scale, (50) * scale, 20, 340, PIE);
// eyelid
strokeWeight(7 * scale);
stroke(ch3_detailPrimary);
fill(curHue, curSaturation, curBrightnessSecondary);
// top eyelid
arc(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale, 265 - curEyelidTop_height, 275 + curEyelidTop_height, CHORD);
// bottom eyelid
arc(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale, 85 - curEyelidBottom_height, 95 + curEyelidBottom_height, CHORD);
// eyebrow
stroke(ch3_detailPrimary)
noFill();
arc(eye1_pos[0], (eye1_pos[1]), 130 * scale, 110 * scale, 240, 300);
}
// colorMode(RGB);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.genderValue = settings[0];
this.hairValue = settings[1];
this.lookDirection = settings[2];
this.eyelidTop_height = settings[3];
this.eyelidBottom_height = settings[4];
this.hue = settings[5];
this.saturation = settings[6];
this.brightness = settings[7];
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
properties = new Array(8);
properties[0] = this.genderValue;
properties[1] = this.hairValue;
properties[2] = this.lookDirection;
properties[3] = this.eyelidTop_height;
properties[4] = this.eyelidBottom_height;
properties[5] = this.hue;
properties[6] = this.saturation;
properties[7] = this.brightness;
return properties;
}
}
// given a point, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
65,
57,
51,
68,
87,
5,
29,
42
],
"000002": [
50,
50,
36,
50,
87,
0,
50,
50
],
"000058": [
50,
50,
76,
71,
78,
4,
0,
0
],
"000005": [
50,
50,
50,
85,
62,
10,
45,
77
],
"000006": [
50,
50,
93,
59,
55,
8,
41,
22
],
"000007": [
100,
49,
50,
71,
38,
50,
0,
0
],
"000009": [
50,
50,
31,
50,
100,
5,
41,
29
],
"000010": [
50,
50,
50,
87,
70,
10,
31,
74
],
"000013": [
100,
33,
76,
47,
89,
13,
33,
78
],
"000014": [
50,
50,
50,
73,
85,
50,
0,
0
],
"000015": [
100,
65,
62,
89,
100,
7,
33,
13
],
"000016": [
100,
27,
99,
50,
100,
5,
37,
16
],
"000018": [
50,
50,
50,
70,
93,
11,
32,
65
],
"000020": [
100,
100,
77,
71,
100,
6,
33,
3
],
"000023": [
100,
17,
100,
51,
100,
5,
23,
0
],
"000025": [
100,
0,
48,
66,
66,
6,
32,
15
],
"000028": [
50,
50,
50,
56,
100,
4,
44,
36
],
"000029": [
50,
50,
50,
87,
70,
10,
31,
74
],
"000030": [
100,
79,
76,
59,
94,
9,
33,
40
],
"000031": [
50,
50,
50,
85,
62,
10,
45,
77
],
"000032": [
100,
50,
77,
71,
100,
6,
33,
3
],
"000035": [
50,
50,
50,
50,
50,
50,
0,
0
],
"000037": [
100,
0,
83,
50,
71,
50,
0,
0
],
"000038": [
100,
49,
50,
71,
91,
50,
0,
0
],
"000041": [
100,
100,
0,
45,
100,
50,
0,
0
],
"000042": [
50,
50,
50,
66,
67,
10,
43,
74
],
"000043": [
50,
50,
38,
43,
62,
4,
26,
2
],
"000044": [
50,
50,
50,
73,
85,
50,
0,
0
],
"000045": [
50,
50,
50,
56,
100,
4,
47,
52
],
"000050": [
100,
49,
50,
57,
100,
50,
0,
0
],
"000051": [
100,
0,
59,
60,
85,
0,
0,
49
],
"000048": [
100,
82,
50,
88,
77,
50,
0,
0
],
"000047": [
50,
50,
50,
77,
50,
6,
18,
0
],
"000040": [
50,
50,
50,
65,
70,
4,
19,
6
],
"000052": [
100,
65,
70,
57,
84,
2,
20,
0
],
"000054": [
50,
50,
44,
50,
100,
9,
27,
57
],
"000055": [
100,
53,
42,
61,
78,
38,
0,
0
],
"000056": [
50,
50,
41,
81,
66,
5,
0,
0
],
"000060": [
100,
0,
0,
50,
90,
4,
28,
0
],
"000064": [
100,
59,
52,
75,
89,
6,
28,
8
],
"000065": [
100,
76,
41,
81,
78,
5,
0,
0
],
"000068": [
100,
82,
72,
63,
65,
15,
0,
50
],
"000069": [
100,
41,
63,
0,
90,
31,
0,
0
],
"000071": [
50,
50,
50,
85,
62,
10,
45,
77
],
"000073": [
50,
50,
27,
85,
62,
2,
45,
21
],
"000076": [
100,
94,
25,
75,
89,
6,
16,
0
],
"000077": [
50,
50,
76,
71,
78,
4,
0,
0
],
"000078": [
50,
50,
50,
73,
85,
50,
0,
0
],
"000079": [
100,
0,
63,
66,
66,
5,
37,
48
],
"000080": [
100,
59,
18,
53,
79,
34,
0,
0
],
"000081": [
100,
34,
58,
60,
94,
46,
0,
0
],
"000083": [
50,
50,
39,
55,
81,
4,
46,
30
],
"000085": [
50,
50,
62,
53,
42,
3,
34,
19
],
"000086": [
50,
50,
50,
64,
92,
6,
33,
18
],
"000088": [
50,
50,
64,
61,
90,
5,
53,
61
],
"000091": [
100,
45,
45,
95,
100,
33,
0,
0
],
"000092": [
50,
50,
45,
65,
58,
11,
38,
67
],
"000096": [
50,
50,
50,
40,
71,
0,
38,
0
],
"000097": [
50,
50,
52,
44,
40,
6,
37,
43
],
"000099": [
50,
50,
50,
53,
100,
3,
30,
10
],
"000100": [
50,
50,
74,
48,
41,
7,
35,
31
],
"000103": [
50,
50,
27,
51,
85,
5,
30,
5
],
"000104": [
100,
18,
50,
44,
83,
8,
44,
54
],
"000108": [
50,
50,
37,
59,
76,
10,
38,
75
],
"000106": [
50,
50,
27,
50,
100,
5,
40,
0
],
"000109": [
100,
50,
57,
50,
70,
5,
31,
21
],
"000110": [
50,
50,
50,
50,
88,
5,
37,
23
],
"000111": [
50,
50,
74,
50,
94,
11,
27,
68
],
"000114": [
100,
29,
49,
51,
63,
5,
19,
0
],
"000115": [
100,
0,
50,
67,
79,
7,
18,
71
],
"000116": [
100,
59,
58,
52,
91,
3,
26,
28
],
"000117": [
50,
50,
66,
85,
78,
23,
0,
0
],
"000118": [
50,
50,
23,
61,
90,
0,
18,
0
],
"000121": [
50,
50,
63,
49,
81,
4,
30,
0
],
"000122": [
50,
50,
52,
57,
85,
8,
22,
56
],
"000125": [
100,
0,
48,
53,
76,
20,
0,
26
],
"000126": [
50,
50,
54,
62,
54,
11,
16,
70
],
"000129": [
100,
53,
72,
53,
81,
20,
0,
0
],
"000131": [
50,
50,
100,
63,
89,
4,
4,
0
],
"000132": [
50,
50,
64,
66,
89,
18,
0,
0
],
"000133": [
50,
50,
66,
49,
73,
8,
28,
42
],
"000134": [
100,
0,
0,
55,
80,
51,
0,
0
],
"000135": [
100,
28,
100,
52,
96,
19,
0,
0
],
"000137": [
100,
62,
91,
65,
86,
6,
23,
15
],
"000140": [
50,
50,
38,
55,
82,
10,
33,
61
],
"000142": [
50,
50,
44,
60,
83,
6,
39,
0
],
"000143": [
100,
39,
64,
63,
80,
7,
22,
28
],
"000145": [
50,
50,
46,
58,
100,
5,
26,
0
],
"000146": [
50,
50,
100,
43,
89,
0,
37,
0
],
"000147": [
50,
50,
72,
53,
53,
8,
37,
64
],
"000148": [
50,
50,
100,
59,
74,
0,
13,
0
],
"000150": [
100,
74,
49,
100,
52,
0,
50,
52
],
"000151": [
62,
53,
51,
66,
89,
6,
21,
0
],
"000152": [
100,
39,
44,
64,
100,
5,
23,
33
],
"000153": [
100,
23,
54,
60,
85,
4,
26,
0
],
"000155": [
50,
50,
49,
51,
75,
0,
49,
50
],
"000156": [
50,
50,
52,
58,
62,
8,
30,
45
],
"000157": [
50,
50,
43,
62,
77,
8,
22,
63
],
"000160": [
100,
44,
50,
56,
75,
38,
0,
0
],
"000161": [
50,
50,
31,
62,
73,
5,
0,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
var NUM_SLIDERS = 6;
// other variables can be in here too
//helmet colors
const chen_red = [197, 17, 18];
const lime = [100, 255, 51];
const cyan = [0, 255, 232];
const yellow = [255, 243, 0];
const brown = [95, 60, 12];
const chen_black = [50];
const white = [210];
//eye colors
const eye_blue = [0, 182, 255, 75];
const eye_black = [4, 27, 30, 30];
const eye_green = [20, 135, 49, 75];
const eye_brown = [74, 35, 6, 50];
//mask colors
const mask = [157, 200, 217];
const mask_shade = [76, 95, 109];
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function ChenFace() {
// these are state variables for a face
// (your variables should be different!)
this.helmet_color = 2; // variations of hair colors
this.eye_color = 4; // variations of eye colors
this.gender = 1;
this.ref_shift = 1.5; //location of reflection
this.ref_shift_2 = 1;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for(let i=0; i<segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if(i < segment.length - 1) {
let nx = segment[i+1][0];
let ny = segment[i+1][1];
line(px, py, nx, ny);
}
else if(do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
//helmet
stroke(0, 150);
strokeWeight(0.2);
if (this.helmet_color >= 0 && this.helmet_color <= 1){
fill(chen_black);
} else if (this.helmet_color > 1 && this.helmet_color <= 2){
fill(brown);
} else if (this.helmet_color > 2 && this.helmet_color <= 3){
fill(chen_red);
} else if (this.helmet_color > 3 && this.helmet_color <= 4){
fill(yellow);
} else if (this.helmet_color > 4 && this.helmet_color <= 5){
fill(white);
}
beginShape();
curveVertex(positions.chin[0][0]-0.2, positions.chin[0][1]-0.5);
curveVertex(positions.chin[0][0]-0.2, positions.chin[0][1]-0.5);
curveVertex(positions.chin[0][0]-0.2, positions.chin[0][1]+2.5);
curveVertex(positions.chin[16][0]+0.2, positions.chin[16][1]+2.5);
curveVertex(positions.chin[16][0]+0.2, positions.chin[16][1]-0.5);
curveVertex(positions.chin[16][0]+0.2, positions.chin[16][1]-0.5);
endShape();
beginShape();
vertex(positions.chin[0][0]-0.2, positions.chin[0][1]-0.45);
quadraticVertex(0, positions.nose_bridge[0][1]-4, positions.chin[16][0]+0.2, positions.chin[16][1]-0.45)
endShape();
//mask
noStroke();
fill(mask);
beginShape();
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[3][0]-0.1, positions.chin[3][1]);
curveVertex(positions.nose_tip[2][0], positions.nose_tip[2][1]+0.6);
curveVertex(positions.chin[13][0]-0.1, positions.chin[13][1]);
curveVertex(positions.chin[14][0], positions.chin[14][1]);
curveVertex(positions.chin[16][0], positions.chin[16][1]);
curveVertex(positions.right_eyebrow[4][0]-0.2, positions.right_eyebrow[4][1]);
curveVertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-1);
curveVertex(positions.left_eyebrow[0][0]+0.2, positions.left_eyebrow[0][1]);
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[3][0], positions.chin[3][1]);
endShape();
//eyes
noStroke();
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
if (this.eye_color > 0 && this.eye_color <= 1){
fill(eye_black);
} else if (this.eye_color >1 && this.eye_color <= 2){
fill(eye_brown);
} else if (this.eye_color >2 && this.eye_color <= 3){
fill(eye_green);
} else if (this.eye_color >3 && this.eye_color <= 4) {
fill(eye_blue);
}
if (this.gender >= 0 && this.gender <= 0.5){ //softer edges for female
ellipse(left_eye_pos[0], left_eye_pos[1]+0.25, 0.38, 0.28);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.25, 0.38, 0.28);
fill(255, 50); // eye reflection
ellipse(left_eye_pos[0]+0.1, left_eye_pos[1]+0.2, 0.1);
ellipse(right_eye_pos[0]+0.1, right_eye_pos[1]+0.2, 0.1);
} else{ //harder edges for male
beginShape(); //left eye
vertex(positions.left_eye[0][0], positions.left_eye[0][1]+0.25);
vertex(positions.left_eye[1][0],positions.left_eye[1][1]+0.25);
vertex(positions.left_eye[2][0], positions.left_eye[2][1]+0.25);
vertex(positions.left_eye[3][0], positions.left_eye[3][1]+0.25);
vertex(positions.left_eye[4][0], positions.left_eye[4][1]+0.25);
vertex(positions.left_eye[5][0], positions.left_eye[5][1]+0.25);
endShape();
beginShape(); //right eye
vertex(positions.right_eye[0][0], positions.right_eye[0][1]+0.25);
vertex(positions.right_eye[1][0],positions.right_eye[1][1]+0.25);
vertex(positions.right_eye[2][0], positions.right_eye[2][1]+0.25);
vertex(positions.right_eye[3][0], positions.right_eye[3][1]+0.25);
vertex(positions.right_eye[4][0], positions.right_eye[4][1]+0.25);
vertex(positions.right_eye[5][0], positions.right_eye[5][1]+0.25);
endShape();
// eye reflection
fill(255, 25);
ellipse(left_eye_pos[0]-0.08, left_eye_pos[1]+0.21, 0.15, 0.11);
ellipse(right_eye_pos[0]-0.08, right_eye_pos[1]+0.21, 0.15, 0.11);
}
//blush
if (this.gender >= 0 && this.gender <= 0.5){
fill(255, 222, 254);
ellipse(positions.left_eye[0][0], positions.left_eye[0][1]+0.6, 0.5, 0.1);
ellipse(positions.right_eye[3][0], positions.right_eye[3][1]+0.6, 0.5, 0.1);
} else {
fill(255, 222, 254, 150);
ellipse(positions.left_eye[0][0], positions.left_eye[0][1]+0.6, 0.4, 0.08);
ellipse(positions.right_eye[3][0], positions.right_eye[3][1]+0.6, 0.4, 0.08);
}
//nose
let nose_top = positions.nose_bridge[1];
let nose_bottom = positions.nose_bridge[3];
let nose_end = null;
stroke(76, 95, 109, 25);
strokeWeight(0.08);
line(nose_top[0], nose_top[1], nose_bottom[0], nose_bottom[1]-0.15);
//mouth
noStroke();
fill(255, 25);
beginShape();
vertex(positions.top_lip[1][0],positions.top_lip[1][1]-0.2);
vertex(positions.top_lip[2][0], positions.top_lip[2][1]-0.2);
vertex(positions.top_lip[3][0], positions.top_lip[3][1]-0.2);
vertex(positions.top_lip[4][0], positions.top_lip[4][1]-0.2);
vertex(positions.top_lip[5][0], positions.top_lip[5][1]-0.2);
vertex(positions.bottom_lip[10][0], positions.bottom_lip[10][1]-0.3);
vertex(positions.bottom_lip[9][0], positions.bottom_lip[9][1]-0.3);
vertex(positions.bottom_lip[8][0], positions.bottom_lip[8][1]-0.3);
endShape();
//reflection
let curRefShift = this.ref_shift;
let curRefShift_2 = this.ref_shift_2;
fill(254, 252, 255, 220);
if(nose_top[0] > nose_bottom[0]){
ellipse(positions.nose_bridge[3][0] + curRefShift, right_eye_pos[1]+0.22, 1, 0.5);
ellipse(positions.top_lip[3][0] - curRefShift_2 , positions.top_lip[1][1]-0.2, 0.2, 0.1);
} else{
ellipse(positions.nose_bridge[3][0] - curRefShift, right_eye_pos[1]+0.22, 1, 0.5);
ellipse(positions.top_lip[3][0] + curRefShift_2 , positions.top_lip[1][1]-0.2, 0.2, 0.1);
}
//mask outline
noFill();
stroke(0, 200);
strokeWeight(0.2);
beginShape();
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[3][0]-0.1, positions.chin[3][1]);
curveVertex(positions.nose_tip[2][0], positions.nose_tip[2][1]+0.6);
curveVertex(positions.chin[13][0]-0.1, positions.chin[13][1]);
curveVertex(positions.chin[14][0], positions.chin[14][1]);
curveVertex(positions.chin[16][0], positions.chin[16][1]);
curveVertex(positions.right_eyebrow[4][0]-0.2, positions.right_eyebrow[4][1]);
curveVertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-1);
curveVertex(positions.left_eyebrow[0][0]+0.2, positions.left_eyebrow[0][1]);
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[3][0], positions.chin[3][1]);
endShape();
//decorations
if (this.gender >= 0 && this.gender <= 0.5){ //flower hat for female
stroke(0, 200);
strokeWeight(0.1);
fill(255, 192, 183);
push();
angleMode(DEGREES);
if (nose_top[0] > nose_bottom[0]){
translate(positions.chin[16][0]-0.1, positions.chin[16][1]-0.5);
} else {
translate(positions.chin[0][0]+0.1, positions.chin[0][1]-0.5);
}
for (let i = 0; i < 5; i++){
ellipse(0, 0.35, 0.37, 0.75);
rotate(360/5);
}
noStroke();
fill(236, 180, 172, 200);
ellipse(0, 0, 0.3);
pop();
} else { //plant hat for male
stroke(0, 200);
strokeWeight(0.1);
push();
translate(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-1.3);
fill(3, 77, 13);
if (nose_top[0] > nose_bottom[0]){
beginShape();
vertex(-0.2, -0.4);
vertex(-0.2, -0.7);
quadraticVertex(-1.1, -0.85, -1.5, -1.4);
quadraticVertex(-0.6, -1.9, -0.1, -1.05);
quadraticVertex(0.55, -2.4, 1.4, -1.8);
quadraticVertex(0.9, -0.7, 0.2, -0.7);
vertex(0.2, -0.4);
vertex(-0.2, -0.4);
endShape();
} else {
beginShape();
vertex(0.2, -0.4);
vertex(0.2, -0.7);
quadraticVertex(1.1, -0.85, 1.5, -1.4);
quadraticVertex(0.6, -1.9, 0.1, -1.05);
quadraticVertex(-0.55, -2.4, -1.4, -1.8);
quadraticVertex(-0.9, -0.7, -0.2, -0.7);
vertex(-0.2, -0.4);
vertex(0.2, -0.4);
endShape();
}
pop();
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.helmet_color = map(settings[0], 0, 100, 0, 5);
this.eye_color = map(settings[1], 0, 100, 1, 4);
this.gender = map(settings[2], 0, 100, 0, 1);
this.ref_shift = map(settings[3], 0, 100, 1, 1.8);
this.ref_shift_2 = map(settings[4], 0, 100, 0.3, 1.2);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(6);
settings[0] = map(this.helmet_color, 0, 5, 0, 100);
settings[1] = map(this.eye_color, 1, 4, 0, 100);
settings[2] = map(this.gender, 0, 1, 0, 100);
settings[3] = map(this.ref_shift, 1, 1.8, 0, 100);
settings[4] = map(this.ref_shift_2, 0.3, 1.2, 0, 100);
return settings;
}
}
{
"000001": [
63,
26,
0,
100,
33,
null
],
"000002": [
46,
11.000000000000004,
0,
68,
21.000000000000004,
null
],
"000005": [
68,
16,
0,
68,
85.99999999999999,
null
],
"000006": [
21.000000000000004,
11.000000000000004,
0,
68,
21.000000000000004,
null
],
"000007": [
0,
15,
100,
69,
30,
null
],
"000009": [
23,
13.000000000000004,
0,
100,
30,
null
],
"000010": [
65,
81,
0,
56.99999999999999,
48.00000000000001,
null
],
"000013": [
69,
98,
100,
81.00000000000001,
52.99999999999999,
null
],
"000014": [
0,
0,
0,
81.00000000000001,
26.999999999999996,
null
],
"000015": [
27,
0,
100,
59,
67,
null
],
"000016": [
14.000000000000002,
15,
100,
80.00000000000001,
61.999999999999986,
null
],
"000018": [
71,
33,
0,
46.999999999999986,
61.999999999999986,
null
],
"000020": [
16.000000000000004,
0,
100,
50.99999999999999,
61.999999999999986,
null
],
"000023": [
11.000000000000002,
2.0000000000000018,
100,
56.99999999999999,
59.999999999999986,
null
],
"000025": [
28.000000000000004,
0,
100,
84.00000000000001,
61.999999999999986,
null
],
"000028": [
21.999999999999996,
0,
0,
48.999999999999986,
61.999999999999986,
null
],
"000029": [
64,
75,
0,
55.99999999999999,
57.999999999999986,
null
],
"000030": [
64,
17,
100,
94,
23.000000000000004,
null
],
"000031": [
63,
83,
0,
30,
74.99999999999999,
null
],
"000032": [
72,
0,
100,
34,
42,
null
],
"000035": [
0,
24,
0,
30,
40,
null
],
"000037": [
0,
16,
100,
100,
1.000000000000001,
null
],
"000038": [
19,
80.00000000000001,
100,
55.99999999999999,
30,
null
],
"000040": [
0,
18.000000000000004,
0,
73.00000000000001,
30,
null
],
"000041": [
0,
17,
100,
100,
0,
null
],
"000042": [
75,
69.99999999999999,
0,
68,
9.000000000000002,
null
],
"000043": [
40,
13.999999999999998,
0,
40.00000000000001,
46,
null
],
"000044": [
0,
0,
0,
40.00000000000001,
46,
null
],
"000045": [
43,
20.000000000000004,
0,
40.00000000000001,
46,
null
],
"000047": [
0,
0,
0,
53.99999999999999,
52.99999999999999,
null
],
"000048": [
0,
0,
100,
53.99999999999999,
52.99999999999999,
null
],
"000050": [
0,
13.000000000000004,
100,
86.00000000000001,
52.99999999999999,
null
],
"000051": [
100,
11.000000000000004,
100,
53.99999999999999,
52.99999999999999,
null
],
"000052": [
32,
80.00000000000001,
100,
53.99999999999999,
52.99999999999999,
null
],
"000054": [
67,
79,
0,
53.99999999999999,
52.99999999999999,
null
],
"000055": [
0,
17,
100,
68,
61.999999999999986,
null
],
"000056": [
0,
24,
0,
68,
46.99999999999999,
null
],
"000058": [
0,
77.99999999999999,
0,
56.99999999999999,
67,
null
],
"000060": [
32,
20.000000000000004,
100,
100,
67,
null
],
"000064": [
25,
8,
100,
56.99999999999999,
67,
null
],
"000065": [
0,
13.000000000000004,
100,
56.99999999999999,
67,
null
],
"000068": [
100,
11.000000000000004,
100,
71.00000000000001,
40,
null
],
"000069": [
0,
24,
100,
28.999999999999996,
94,
null
],
"000071": [
62,
45,
0,
84.00000000000001,
50.000000000000014,
null
],
"000073": [
32,
24,
0,
100,
28.000000000000007,
null
],
"000076": [
0,
8,
100,
57.99999999999999,
46.99999999999999,
null
],
"000077": [
31,
0,
0,
89.00000000000003,
46,
null
],
"000078": [
9.999999999999998,
4.0000000000000036,
0,
56.99999999999999,
70,
null
],
"000079": [
100,
24,
100,
87.00000000000003,
34,
null
],
"000080": [
0,
82,
100,
70,
17,
null
],
"000081": [
0,
20.000000000000004,
100,
78.00000000000001,
50.000000000000014,
null
],
"000083": [
25,
23,
0,
72.00000000000001,
50.000000000000014,
null
],
"000085": [
26,
10.000000000000002,
0,
72.00000000000001,
50.000000000000014,
null
],
"000086": [
35,
11.999999999999995,
0,
100,
18,
null
],
"000088": [
36,
23,
0,
79.00000000000001,
18,
null
],
"000091": [
0,
0,
100,
61,
18,
null
],
"000092": [
66,
67,
0,
84.00000000000001,
43,
null
],
"000096": [
27,
9.000000000000002,
0,
61,
48.00000000000001,
null
],
"000097": [
25,
90,
0,
61,
48.00000000000001,
null
],
"000099": [
25,
100,
0,
61,
48.00000000000001,
null
],
"000100": [
70,
1.0000000000000009,
0,
89.00000000000003,
30,
null
],
"000103": [
25,
41,
0,
62,
30,
null
],
"000104": [
62,
23,
100,
51.99999999999999,
39.00000000000001,
null
],
"000106": [
25,
17,
0,
82.00000000000001,
28.000000000000007,
null
],
"000108": [
69,
8,
0,
82.00000000000001,
28.000000000000007,
null
],
"000109": [
68,
50,
100,
67,
28.000000000000007,
null
],
"000110": [
21.999999999999996,
48,
0,
67,
28.000000000000007,
null
],
"000111": [
69,
8,
0,
100,
28.000000000000007,
null
],
"000114": [
0,
20.999999999999996,
100,
52.99999999999999,
39.00000000000001,
null
],
"000115": [
100,
45,
100,
52.99999999999999,
39.00000000000001,
null
],
"000116": [
27,
19.000000000000004,
100,
52.99999999999999,
39.00000000000001,
null
],
"000117": [
0,
27,
0,
87.00000000000003,
28.000000000000007,
null
],
"000118": [
19,
6.999999999999999,
0,
100,
15.999999999999998,
null
],
"000121": [
0,
15,
0,
45.000000000000014,
46.99999999999999,
null
],
"000122": [
66,
13.999999999999998,
0,
42.00000000000001,
65,
null
],
"000125": [
100,
72.00000000000001,
100,
84.00000000000001,
52.99999999999999,
null
],
"000126": [
61,
83,
0,
68,
43,
null
],
"000129": [
0,
4.9999999999999964,
100,
56.99999999999999,
43,
null
],
"000131": [
0,
0,
0,
90.00000000000003,
43,
null
],
"000132": [
0,
11.000000000000004,
0,
90.00000000000003,
43,
null
],
"000133": [
61,
69.99999999999999,
0,
51.99999999999999,
35,
null
],
"000134": [
0,
0,
100,
100,
23.000000000000004,
null
],
"000135": [
0,
0,
100,
85.00000000000001,
23.000000000000004,
null
],
"000137": [
100,
0,
100,
100,
3.9999999999999982,
null
],
"000140": [
70,
75,
0,
68,
24.999999999999993,
null
],
"000142": [
20.999999999999996,
24,
0,
51.99999999999999,
8.000000000000002,
null
],
"000143": [
24,
77.99999999999999,
100,
75.00000000000001,
26.000000000000007,
null
],
"000145": [
0,
10.000000000000002,
0,
82.00000000000001,
26.000000000000007,
null
],
"000146": [
49.00000000000001,
4.0000000000000036,
0,
100,
0,
null
],
"000147": [
64,
71,
0,
55.99999999999999,
0,
null
],
"000148": [
0,
48.99999999999999,
0,
100,
0,
null
],
"000150": [
51,
0,
100,
86.00000000000001,
12,
null
],
"000151": [
28.000000000000004,
0,
0,
36.00000000000001,
54.99999999999999,
null
],
"000152": [
22.000000000000004,
57.99999999999999,
100,
45.000000000000014,
72.99999999999999,
null
],
"000153": [
0,
18.000000000000004,
100,
45.000000000000014,
72.99999999999999,
null
],
"000155": [
54,
13.000000000000004,
0,
77.00000000000001,
61,
null
],
"000156": [
72,
0,
0,
98,
61,
null
],
"000157": [
69,
69,
0,
51.99999999999999,
61,
null
],
"000160": [
0,
6.999999999999999,
100,
51.99999999999999,
31,
null
],
"000161": [
0,
77.99999999999999,
0,
51.99999999999999,
54.000000000000014,
null
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 7;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
const cooper_brown =[250, 155, 117];
const brown1 =[209, 131, 100];
const brown2 =[135, 85, 65];
const brown3 = [79, 50, 38];
const brown4 = [43, 29, 21];
const lip = [247, 134, 89];
const lip1 = [204, 108, 69];
const lip2 = [107, 67, 51];
const lip3 = [79, 40, 25];
const lip4 = [33, 19, 10];
this.show_points = function (segment){
for(let i=0; i<segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
var number = i.toString();
textAlign(CENTER, CENTER);
textSize(0.2);
fill(0);
text(number, px, py, 0.1);
}
}
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function CooperFace() {
// these are state variables for a face
// (your variables should be different!)
this.faceSize = 3;
this.eye = 0.5;
this.lip = 1 ;
this.tooth = 2;
this.mouth = 1;
this.num_eyes = 2;
this.eye_shift = -1;
this.face_colour = 1;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for(let i=0; i<segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if(i < segment.length - 1) {
let nx = segment[i+1][0];
let ny = segment[i+1][1];
line(px, py, nx, ny);
}
else if(do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
let left_eye = segment_average(positions.left_eye);
let right_eye = segment_average(positions.right_eye);
let nose_tip = positions.nose_tip[2];
let top_lip = positions.top_lip[3];
let bottom_lip = positions.bottom_lip[0];
let whiskers = positions.nose_bridge[2];
let nostrils = positions.nose_bridge[2];
let tooth = positions.nose_bridge[3];
noStroke();
//head
if(this.face_colour == 0){
fill(cooper_brown);
}else
if(this.face_colour == 1){
fill(brown1);
}else
if(this.face_colour == 2){
fill(brown2);
}else
if(this.face_colour == 3){
fill(brown3);
}else
if(this.face_colour == 4){
fill(brown4);
}
ellipse(0, -0.3,this.faceSize,4);
// eyes
fill(255);
ellipse(left_eye[0], left_eye[1], 1,this.eye);
ellipse(right_eye[0], right_eye[1],1, this.eye);
let curEyeShift = 0.04 * this.eye_shift;
if(this.num_eyes == 2) {
fill(0);
ellipse(left_eye[0] + curEyeShift, left_eye[1], 0.5);
ellipse(right_eye[0] + curEyeShift, right_eye[1], 0.5);
}
else {
let eyePosX = (left_eye[0] + right_eye[0]) / 2;
let eyePosY = (left_eye[1] + right_eye[1]) / 2;
fill(0);
ellipse(eyePosX, eyePosY, 0.45, 0.27);
fill(0);
ellipse(eyePosX - 0.1 + curEyeShift, eyePosY, 0.18);
}
//mouth
fill(255, 201, 251);
ellipse(top_lip[0],top_lip[1],bottom_lip[0],this.mouth);
//teeth
if(this.tooth == 2){
noStroke();
push();
translate(tooth[0],tooth[1]);
fill(255);
triangle(0.25, 0.5, 0.5, 2, 0.75, 0.5);
triangle(-0.75, 0.5, -0.5, 2, -0.25, 0.5);
pop();
}else
if(this.tooth == 0){
noStroke();
push();
translate(tooth[0],tooth[1]);
fill(255);
triangle(0.25, 0.5, 0.5, 0, 0.75, 0.5);
triangle(-0.75, 0.5, -0.5, 0, -0.25, 0.5);
pop();
}
//lip
if(this.face_colour == 0){
fill(lip);
}else
if(this.face_colour == 1){
fill(lip1);
}else
if(this.face_colour == 2){
fill(lip2);
}else
if(this.face_colour == 3){
fill(lip3);
}else
if(this.face_colour == 4){
fill(lip4);
}
ellipse(nose_tip[0],nose_tip[1], 4, 1);
//nostrils
fill(0);
ellipse(nostrils[0],nostrils[1],this.lip, 0.5);
//whiskers
noFill();
stroke(255, 194, 115);
push();
translate(whiskers[0],whiskers[1]);
angleMode(DEGREES);
strokeWeight(0.05);
arc(0.4, 1, 1.6, 1.2, 290, 50);
arc(0.6, 1, 1.6, 1.2, 290, 50);
arc(0.8, 1, 1.6, 1.2, 290, 50);
arc(0, 1, 1.6, 1.2, 320, 50);
arc(0, 0.52, 0.8, 1.2, 360, 50);
arc(0, 0.6, 0.4, 1.2, 340, 50);
arc(-0.2, 0.6, 0.4, 1.2, 340, 50);
arc(-0.4, 0.6, 0.4, 1.2, 340, 50);
arc(-0.4, 1, 1.6, 1.2, 135, 250);
arc(-0.6, 1, 1.6, 1.2, 135, 250);
arc(-0.8, 1, 1.6, 1.2, 135, 250);
arc(-0.32, 0.96,1, 1.08, 120, 250);
arc(-0.2, 0.88, 0.4, 1.2, 180, 250);
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.faceSize = map(settings[0], 0, 100, 2.8, 4);
this.eye = map(settings[1], 0, 100, 0.5, 0.8);
this.lip = map(settings[2], 0, 100, 0.5, 2);
this.tooth = int(map(settings[3], 0, 100, 0, 2));
this.mouth = map(settings[4], 0, 100, 0.5, 1.5);
this.eye_shift = map(settings[5], 0, 100, -2, 2);
this.face_colour = int(map(settings[6], 0, 100, 0, 4));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(3);
settings[0] = map(this.faceSize, 2.8, 4, 0, 100);
settings[1] = map(this.eye, 0.5, 0.8, 0, 100);
settings[2] = map(this.lip, 0.5, 2, 0, 100);
settings[3] = int(map(this.tooth, 0, 2, 0, 100));
settings[4] = map(this.mouth,0.5,1.5,0,100);
settings[5] = map(this.eye_shift, -2, 2, 0, 100);
settings[6] = int(map(this.face_colour, 0, 4, 0, 100));
return settings;
}
}
{
"000001": [
63.000000000000014,
18.000000000000014,
17,
0,
5.000000000000004,
60,
0
],
"000002": [
77.99999999999999,
24.999999999999982,
4.0000000000000036,
0,
49,
38,
0
],
"000005": [
100,
13.000000000000009,
10.000000000000002,
0,
39,
46,
0
],
"000006": [
52,
16.00000000000001,
0,
0,
33.00000000000001,
95,
50
],
"000007": [
54,
22.000000000000018,
11.000000000000004,
100,
0,
60,
0
],
"000009": [
75.00000000000003,
20.99999999999998,
1.0000000000000009,
0,
37,
42,
0
],
"000010": [
100,
0,
16,
0,
0,
41,
0
],
"000013": [
100,
0,
0,
100,
14.000000000000002,
75,
0
],
"000014": [
100,
14.000000000000009,
9.000000000000002,
0,
0,
37,
75
],
"000015": [
54,
0,
20.999999999999996,
100,
7.000000000000006,
57.99999999999999,
0
],
"000016": [
50,
13.000000000000009,
8,
100,
0,
100,
25
],
"000018": [
81.00000000000003,
14.000000000000009,
19.000000000000004,
0,
30.000000000000004,
45,
0
],
"000020": [
60.00000000000001,
0,
17,
100,
19.999999999999996,
77,
0
],
"000023": [
58.00000000000001,
20.000000000000014,
20.999999999999996,
100,
6.000000000000005,
100,
0
],
"000025": [
66.00000000000001,
6.000000000000004,
4.9999999999999964,
100,
0,
44,
0
],
"000028": [
63.000000000000014,
11.000000000000009,
44.000000000000014,
0,
87.99999999999999,
54,
25
],
"000029": [
81.99999999999999,
17.00000000000001,
0,
0,
55.00000000000001,
45,
0
],
"000030": [
95,
14.000000000000009,
0,
100,
0,
43,
0
],
"000031": [
66.00000000000001,
5.0000000000000036,
22.000000000000007,
0,
25,
43,
0
],
"000032": [
61.00000000000001,
28.999999999999986,
4.0000000000000036,
100,
44.99999999999999,
54,
0
],
"000035": [
65.00000000000001,
39.99999999999999,
0,
0,
7.000000000000006,
53,
0
],
"000037": [
73.00000000000001,
51,
60,
100,
0,
94,
50
],
"000038": [
62.000000000000014,
3.000000000000002,
32,
100,
20.999999999999996,
71,
0
],
"000040": [
73.99999999999997,
33.999999999999986,
0,
0,
0,
66,
25
],
"000041": [
54,
26.000000000000018,
56.99999999999999,
100,
83,
0,
25
],
"000042": [
67.00000000000001,
13.000000000000009,
0,
0,
0,
34,
0
],
"000043": [
49,
23.000000000000018,
4.0000000000000036,
0,
56.999999999999986,
30,
0
],
"000044": [
34.999999999999986,
22.000000000000018,
23,
0,
0,
48,
100
],
"000045": [
56.00000000000001,
7.000000000000004,
6.999999999999999,
0,
66.00000000000001,
70,
25
],
"000047": [
66.00000000000001,
0,
5.999999999999997,
0,
23,
74,
25
],
"000048": [
83.99999999999999,
0,
11.000000000000004,
100,
0,
50,
0
],
"000050": [
75.00000000000003,
0,
28.000000000000004,
100,
79,
62,
25
],
"000051": [
92,
18.000000000000014,
38.99999999999999,
100,
0,
62,
25
],
"000052": [
64.00000000000001,
14.000000000000009,
31,
100,
0,
69,
25
],
"000054": [
71.00000000000001,
14.000000000000009,
6.999999999999999,
0,
55.00000000000001,
71,
0
],
"000055": [
71.00000000000001,
31.999999999999986,
16,
100,
0,
56.99999999999999,
25
],
"000056": [
77.00000000000003,
30.99999999999999,
11.000000000000004,
100,
0,
50,
0
],
"000058": [
77.00000000000003,
24.999999999999982,
5.999999999999997,
0,
0,
71,
0
],
"000060": [
100,
26.000000000000018,
20.000000000000004,
100,
20.999999999999996,
0,
100
],
"000064": [
100,
6.000000000000004,
18.000000000000004,
100,
0,
57.99999999999999,
0
],
"000065": [
75.99999999999997,
6.000000000000004,
40.00000000000001,
100,
23,
57.99999999999999,
25
],
"000068": [
61.00000000000001,
14.000000000000009,
13.000000000000004,
100,
20.999999999999996,
44,
0
],
"000069": [
61.00000000000001,
14.000000000000009,
13.000000000000004,
100,
20.999999999999996,
44,
0
],
"000071": [
81.00000000000003,
24.000000000000018,
1.0000000000000009,
0,
17.999999999999993,
62,
0
],
"000073": [
84.99999999999999,
26.999999999999986,
11.000000000000004,
0,
12,
20.999999999999996,
25
],
"000076": [
100,
26.999999999999986,
18.000000000000004,
100,
0,
15.000000000000002,
25
],
"000077": [
96,
18.000000000000014,
6.999999999999999,
0,
0,
79,
25
],
"000078": [
96,
0,
5.999999999999997,
0,
0,
39,
0
],
"000079": [
53,
13.000000000000009,
24,
100,
0,
80,
25
],
"000080": [
65.00000000000001,
16.00000000000001,
11.000000000000004,
100,
0,
54,
0
],
"000081": [
59.00000000000001,
17.00000000000001,
32,
100,
37,
100,
25
],
"000083": [
38.99999999999999,
18.000000000000014,
4.9999999999999964,
0,
0,
52,
0
],
"000085": [
95,
47,
5.999999999999997,
0,
0,
63,
0
],
"000086": [
100,
31.999999999999986,
5.999999999999997,
0,
27,
27,
0
],
"000088": [
87.99999999999999,
24.999999999999982,
10.000000000000002,
0,
18.999999999999993,
78,
25
],
"000091": [
79.00000000000003,
0,
13.000000000000004,
100,
0,
17.000000000000004,
0
],
"000092": [
73.00000000000001,
10.000000000000007,
5.999999999999997,
0,
0,
46,
0
],
"000096": [
100,
28.999999999999986,
23,
0,
0,
46,
0
],
"000097": [
100,
31.999999999999986,
17,
0,
19.999999999999996,
56.99999999999999,
0
],
"000099": [
52,
0,
23,
0,
47,
50,
0
],
"000100": [
79.99999999999999,
26.999999999999986,
23,
0,
0,
91,
0
],
"000103": [
75.99999999999997,
30.99999999999999,
1.0000000000000009,
0,
0,
43,
0
],
"000104": [
54,
0,
38.00000000000001,
100,
36,
61,
0
],
"000106": [
43.99999999999999,
20.99999999999998,
18.000000000000004,
0,
49,
46,
0
],
"000108": [
58.00000000000001,
22.000000000000018,
0,
0,
40.99999999999999,
51,
0
],
"000109": [
28.000000000000018,
13.000000000000009,
0,
100,
21.999999999999996,
60,
0
],
"000110": [
100,
19.000000000000014,
52,
0,
50,
50,
0
],
"000111": [
100,
19.000000000000014,
38.00000000000001,
0,
47,
100,
100
],
"000114": [
56.00000000000001,
31.999999999999986,
20.000000000000004,
100,
44.99999999999999,
60,
0
],
"000115": [
29.99999999999999,
10.000000000000007,
6.999999999999999,
100,
0,
68,
0
],
"000116": [
39.99999999999999,
0,
6.999999999999999,
100,
37,
76,
0
],
"000117": [
32.999999999999986,
0,
34.99999999999999,
0,
27,
68,
100
],
"000118": [
64.00000000000001,
19.000000000000014,
8,
0,
0,
34,
25
],
"000121": [
51,
23.000000000000018,
15,
0,
0,
56.99999999999999,
25
],
"000122": [
69.99999999999997,
36.999999999999986,
22.000000000000007,
0,
29.000000000000004,
66,
0
],
"000125": [
69.99999999999997,
24.999999999999982,
22.000000000000007,
100,
0,
50,
0
],
"000126": [
60.00000000000001,
24.999999999999982,
6.999999999999999,
0,
29.000000000000004,
80,
0
],
"000129": [
30.99999999999999,
17.00000000000001,
0,
100,
31.000000000000007,
80,
0
],
"000131": [
63.000000000000014,
0,
6.999999999999999,
0,
25,
100,
50
],
"000132": [
84.99999999999999,
24.000000000000018,
23,
0,
49,
82,
50
],
"000133": [
84.99999999999999,
24.000000000000018,
13.999999999999998,
0,
33.00000000000001,
53,
0
],
"000134": [
51,
20.000000000000014,
41.99999999999999,
100,
36,
0,
100
],
"000135": [
37.999999999999986,
22.000000000000018,
17,
100,
0,
100,
50
],
"000137": [
66.00000000000001,
3.000000000000002,
16,
100,
30.000000000000004,
100,
0
],
"000140": [
61.00000000000001,
22.000000000000018,
0,
0,
0,
38,
0
],
"000142": [
42.99999999999999,
20.000000000000014,
8,
0,
10.999999999999998,
38,
0
],
"000143": [
81.99999999999999,
19.000000000000014,
11.999999999999995,
100,
7.9999999999999964,
54,
0
],
"000145": [
67.00000000000001,
0,
8,
0,
76,
57.99999999999999,
0
],
"000146": [
79.00000000000003,
17.00000000000001,
8,
0,
56.999999999999986,
88,
25
],
"000147": [
81.99999999999999,
23.000000000000018,
5.999999999999997,
0,
8.999999999999996,
92,
0
],
"000148": [
47,
32.999999999999986,
2.0000000000000018,
0,
24,
100,
0
],
"000150": [
58.00000000000001,
13.000000000000009,
0,
100,
0,
55.00000000000001,
0
],
"000151": [
61.00000000000001,
13.000000000000009,
27,
0,
53,
59,
25
],
"000152": [
68.00000000000001,
0,
20.999999999999996,
100,
39,
41,
0
],
"000153": [
38.99999999999999,
14.000000000000009,
11.999999999999995,
100,
40.99999999999999,
50,
0
],
"000155": [
71.99999999999997,
20.99999999999998,
13.999999999999998,
0,
40,
59,
25
],
"000156": [
66.00000000000001,
20.99999999999998,
6.999999999999999,
0,
24,
69,
0
],
"000157": [
100,
20.99999999999998,
16,
0,
0,
52,
0
],
"000160": [
62.000000000000014,
13.000000000000009,
11.999999999999995,
100,
0,
63,
0
],
"000161": [
75.99999999999997,
15.00000000000001,
11.000000000000004,
0,
40,
39,
0
]
}
// https://d3js.org/d3-random/ v1.1.2 Copyright 2018 Mike Bostock
!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r(n.d3=n.d3||{})}(this,function(n){"use strict";function r(){return Math.random()}var t=function n(r){function t(n,t){return n=null==n?0:+n,t=null==t?1:+t,1===arguments.length?(t=n,n=0):t-=n,function(){return r()*t+n}}return t.source=n,t}(r),u=function n(r){function t(n,t){var u,e;return n=null==n?0:+n,t=null==t?1:+t,function(){var o;if(null!=u)o=u,u=null;else do{u=2*r()-1,o=2*r()-1,e=u*u+o*o}while(!e||e>1);return n+t*o*Math.sqrt(-2*Math.log(e)/e)}}return t.source=n,t}(r),e=function n(r){function t(){var n=u.source(r).apply(this,arguments);return function(){return Math.exp(n())}}return t.source=n,t}(r),o=function n(r){function t(n){return function(){for(var t=0,u=0;u<n;++u)t+=r();return t}}return t.source=n,t}(r),i=function n(r){function t(n){var t=o.source(r)(n);return function(){return t()/n}}return t.source=n,t}(r),c=function n(r){function t(n){return function(){return-Math.log(1-r())/n}}return t.source=n,t}(r);n.randomUniform=t,n.randomNormal=u,n.randomLogNormal=e,n.randomBates=i,n.randomIrwinHall=o,n.randomExponential=c,Object.defineProperty(n,"__esModule",{value:!0})});
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
//color variables
skinMidtone_color = ["#ffd5be","#ebcebb", "#ffd5be", "#CAA288", "#8c6652"];
skinLowlight_color = ["#f4c4b0", "#e5bbac","#e5b6a2", "#b78c79", "#775041"]
n1= [244, 200, 176, 50];
n2= [229, 187, 172, 50];
n3 = [232, 188, 169, 40];
n4 = [188, 149, 126, 50];
n5 = [124, 84, 68, 50];
noseColor = [n1, n2,n3, n4, n5];
h1= [255, 255, 255, 10];
h2= [249, 245, 239, 10];
h3 = [249, 245, 239, 10];
h4 = [255, 231, 216, 10];
h5 = [255, 231, 216, 10];
noseHighlight = [h1, h2, h3, h4, h5];
skinShadow_color = ["#d6a995", "#d6a995","#ba9584", "#9b7768", "#725241"]
// stroke_color = [skinLowlight_color[1]];
upperLip_color = ["#ba8080", "#d1a3a1", "#dba69b", "#a5776b","#6d453d", "#54322b"]; // 1 longer than the rest for stroke
lowerLip_color = ["#db9d9d", "#ebbdbb", "#ffc9be", "#ca9588", "#8c5c52"];
teeth_color = ["#fcfaf4", "#fff", "#f2ece3", "#f7f2ea", "#efe6da"];
eye_color = ["#3e7191", "#22323d", "#3d4722", "#543f14", "#493127", "#000"];
pupil_color = "#000";
function DockertyFace() {
this.lookPos = 50;
this.eyeAngle = 100;
this.skinColor = 50;
this.eyeColor = 50;
this.eyeSize = 50;
this.draw = function(positions) {
var nose_pos = average_point(positions.nose_bridge);
var eye1_pos = average_point(positions.left_eye);
var eye2_pos = average_point(positions.right_eye);
var half_height = positions.chin[7][1] - nose_pos[1];
var face_width = positions.chin[positions.chin.length-1][0] - positions.chin[0][0];
var eye_squish = map(this.eyeAngle, 0, 100, 50, 100);
var skin_color_value = int(map(this.skinColor, 0, 100, 2, 4.9));
var eye_color_value = int(map(this.eyeColor, 0, 100, 0, 5.9));
var eye_size = map(this.eyeSize, 0, 100, 0.7, 1.5);
var x = nose_pos[0];
var y = nose_pos[1];
var w = 2 * face_width;
var h = 2.5 * half_height;
var extent = 0;
if(h < w) {
extent = h / 2;
}
else {
extent = w / 2;
}
var size = extent / 220.0;
// head
stroke(0, 0, 0, 100);
fill(skinMidtone_color[skin_color_value]);
beginShape();
curveVertex(positions.left_eyebrow[0][0], positions.left_eyebrow[0][1]);
for(var i=0; i<positions.chin.length;i++) {
curveVertex(positions.chin[i][0], positions.chin[i][1]);
}
for(var i=positions.right_eyebrow.length-1; i>=0;i--) {
curveVertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
for(var i=positions.left_eyebrow.length-1; i>=0;i--) {
curveVertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
curveVertex(positions.chin[0][0], positions.chin[0][1]);
endShape(CLOSE);
/////////////////////////////////////////// mouth
//inner mouth
stroke(upperLip_color[skin_color_value+1]);
strokeWeight(0.005);
fill(teeth_color[skin_color_value]);
beginShape();
for(var i=0; i<positions.top_lip.length/2;i++) {
vertex(positions.top_lip[i][0], positions.top_lip[i][1]);
}
for(var i=0; i<6;i++) {
if (i!=3 && i!=9){
vertex(positions.bottom_lip[i][0], positions.bottom_lip[i][1]);
}
}
endShape(CLOSE);
//lips
fill(upperLip_color[skin_color_value]);
beginShape();
for(var i=0; i<positions.top_lip.length;i++) {
curveVertex(positions.top_lip[i][0], positions.top_lip[i][1]);
}
endShape(CLOSE);
fill(lowerLip_color[skin_color_value]);
beginShape();
for(var i=0; i<positions.bottom_lip.length;i++) {
if (i!=3 && i!=9){
curveVertex(positions.bottom_lip[i][0], positions.bottom_lip[i][1]);
}
}
endShape(CLOSE);
noStroke();
///////////////////////////////////////////left eye
eyeball_color = teeth_color[skin_color_value];
iris_color = eye_color[eye_color_value];
push();
scale(1.4);
translate(0.2, 0.4);
//eyeball
beginShape();
fill(eyeball_color)
for(var i=0; i<positions.left_eye.length;i++) {
curveVertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
endShape(CLOSE);
//eye center
push();
translate((eye1_pos[0]-0.1)+(this.lookPos/500), eye1_pos[1]-0.03);
scale(eye_squish/100, 1);
fill(iris_color);
ellipse(0, 0, 20 * size *eye_size, 20 * size*eye_size);
if (eye_color_value == 5){
fill(255, 144, 96, 20);
} else if (eye_color_value == 4){
fill(255, 183, 96, 20);
}else {
fill(230, 250, 200, 20);
}
for(var i=0; i<8;i++) {
ellipse(0, 0, (12+i) * size*eye_size, (12+i) * size*eye_size);
}
fill(pupil_color);
ellipse(0, 0, 8 * size*eye_size, 8 * size*eye_size);
pop();
//eye highlights
fill(255, 255, 255, 5);
for (var i=4; i>0;i-=0.02) {
ellipse((eye1_pos[0]-0.03), eye1_pos[1]-0.07, i * size, i* size)
}
push();
translate(eye1_pos[0], eye1_pos[1]);
rotate(-30);
for (var i=6; i>0;i-=0.02) {
ellipse(0, 0, i * (size/2), i*size);
}
pop();
//lower lid shadow
for(var j=0.04; j>0; j-= 0.02){
push();
translate(-0.02, -j);
scale(0.98, 1)
fill(0, 0, 0, (20/(j*30)));
beginShape();
curveVertex(positions.left_eye[0][0], positions.left_eye[0][1]);
for(var i=5; i>=3;i--) {
curveVertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
for(var i=3; i<=5;i++) {
curveVertex(positions.left_eye[i][0], (positions.left_eye[i][1])+0.1);
}
endShape(CLOSE);
pop();
}
//lower lid shape
beginShape();
fill(skinMidtone_color[skin_color_value]);
curveVertex(positions.left_eye[0][0], positions.left_eye[0][1]);
for(var i=5; i>=3;i--) {
curveVertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
for(var i=3; i<=5;i++) {
curveVertex(positions.left_eye[i][0], (positions.left_eye[i][1])+0.15);
}
endShape(CLOSE);
//eyelid shadow
for(var j=0.01; j<0.1; j+= 0.01){
push();
translate(-0.02, j);
scale(0.98, 1)
beginShape();
fill(0, 0, 0, (20/(j*20)));
curveVertex((positions.left_eye[0][0]), (positions.left_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.left_eye[i][1] + positions.left_eyebrow[i+1][1])/2.2);
var eyelid_value_x = ((positions.left_eye[i][0] + positions.left_eyebrow[i][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
for(var i=3; i>=0;i--) {
curveVertex((positions.left_eye[i][0]), (positions.left_eye[i][1]));
}
endShape(CLOSE);
pop();
}
//eyelid shape
beginShape();
fill(skinLowlight_color[skin_color_value]);
curveVertex((positions.left_eye[0][0]), (positions.left_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.left_eye[i][1] + positions.left_eyebrow[i+1][1])/2.2);
var eyelid_value_x = ((positions.left_eye[i][0] + positions.left_eyebrow[i][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
for(var i=3; i>=0;i--) {
curveVertex((positions.left_eye[i][0]), (positions.left_eye[i][1]));
}
endShape(CLOSE);
//browbone shape
beginShape();
fill(skinMidtone_color[skin_color_value]);
vertex((positions.left_eye[0][0]), (positions.left_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.left_eye[i][1] + positions.left_eyebrow[i+1][1])/2.2);
var eyelid_value_x = ((positions.left_eye[i][0] + positions.left_eyebrow[i][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
curveVertex((positions.left_eyebrow[4][0]+positions.left_eyebrow[3][0])/2.5, (positions.left_eyebrow[3][1]+0.2));
curveVertex((positions.left_eyebrow[1][0]+0.2), (positions.left_eyebrow[1][1])+0.1);
endShape(CLOSE);
pop();
//////////////////////////////////////////////////right eye
push();
scale(1.4);
translate(-0.2, 0.4);
//eyeball
beginShape();
fill(eyeball_color)
for(var i=0; i<positions.right_eye.length;i++) {
curveVertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
endShape(CLOSE);
push();
translate((eye2_pos[0]-0.1)+(this.lookPos/500), eye2_pos[1]-0.03);
scale(eye_squish/100, 1);
//iris
fill(iris_color);
ellipse(0, 0, 20 * size*eye_size, 20 * size*eye_size);
if (eye_color_value == 5){
fill(255, 144, 96, 20);
} else if (eye_color_value == 4){
fill(255, 183, 96, 20);
}else {
fill(230, 250, 200, 20);
}
for(var i=0; i<8;i++) {
ellipse(0, 0, (12+i) * size*eye_size, (12+i) * size*eye_size);
}
//pupil
fill(pupil_color);
ellipse(0, 0, 8 * size*eye_size, 8 * size*eye_size);
pop();
//eye highlights
fill(255, 255, 255, 5);
for (var i=4; i>0;i-=0.02) {
ellipse((eye2_pos[0]-0.1)+0.07, eye2_pos[1]-0.07, i * size, i* size)
}
push();
translate(eye2_pos[0], eye2_pos[1]);
rotate(-30);
for (var i=6; i>0;i-=0.01) {
ellipse(0, 0, i * (size/2), i*size);
}
pop();
//lower lid shadow
for(var j=0.04; j>0; j-= 0.02){
push();
translate(0.02, -j);
scale(0.98, 1)
fill(0, 0, 0, (20/(j*30)));
beginShape();
curveVertex(positions.right_eye[0][0], positions.right_eye[0][1]);
for(var i=5; i>=3;i--) {
curveVertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
for(var i=3; i<=5;i++) {
curveVertex(positions.right_eye[i][0], (positions.right_eye[i][1])+0.1);
}
endShape(CLOSE);
pop();
}
//lower lid shape
beginShape();
fill(skinMidtone_color[skin_color_value]);
curveVertex(positions.right_eye[0][0], positions.right_eye[0][1]);
for(var i=5; i>=3;i--) {
curveVertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
for(var i=3; i<=5;i++) {
curveVertex(positions.right_eye[i][0], (positions.right_eye[i][1])+0.15);
}
endShape(CLOSE);
//eyelid shadow
for(var j=0.01; j<0.1; j+= 0.02){
push();
translate(0.02, j);
scale(0.98, 1)
beginShape();
fill(0, 0, 0, (20/(j*20)));
curveVertex((positions.right_eye[0][0]), (positions.right_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.right_eye[i][1] + positions.right_eyebrow[i][1])/2.2);
var eyelid_value_x = ((positions.right_eye[i][0] + positions.right_eyebrow[i+1][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
for(var i=3; i>=0;i--) {
curveVertex((positions.right_eye[i][0]), (positions.right_eye[i][1]));
}
endShape(CLOSE);
endShape(CLOSE);
pop();
}
//eyelid shape
beginShape();
fill(skinLowlight_color[skin_color_value]);
curveVertex((positions.right_eye[0][0]), (positions.right_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.right_eye[i][1] + positions.right_eyebrow[i][1])/2.2);
var eyelid_value_x = ((positions.right_eye[i][0] + positions.right_eyebrow[i+1][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
for(var i=3; i>=0;i--) {
curveVertex((positions.right_eye[i][0]), (positions.right_eye[i][1]));
}
endShape(CLOSE);
//browbone shape
beginShape();
fill(skinMidtone_color[skin_color_value]);
for(var i=3; i>=0;i--) {
var eyelid_value_y = ((positions.right_eye[i][1] + positions.right_eyebrow[i][1])/2.2);
var eyelid_value_x = ((positions.right_eye[i][0] + positions.right_eyebrow[i+1][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
curveVertex((positions.right_eyebrow[0][0]+0.15), (positions.right_eyebrow[0][1])+0.1);
curveVertex((positions.right_eyebrow[1][0]+0.15), (positions.right_eyebrow[1][1])+0.1);
curveVertex((positions.right_eyebrow[2][0]+positions.right_eyebrow[3][0])/2.5, (positions.right_eyebrow[2][1]+0.15));
endShape(CLOSE);
pop();
////////////////////////////////////////eyebrows
//left eyebrow
var browScale = 0.2
for (var j=0; j<10; j++){
browScale-=0.02;
beginShape();
fill(0, 0, 0, 30);
for(var i=1; i<3;i++) {
vertex((positions.left_eyebrow[i+1][0]), (positions.left_eyebrow[i+1][1]+0.2));
}
vertex((positions.left_eyebrow[4][0]-browScale), (positions.left_eyebrow[4][1]+0.2)-(browScale/2));
vertex((positions.left_eyebrow[4][0]-browScale), (positions.left_eyebrow[4][1])-(browScale/2));
for(var i=3; i>=0;i--) {
if (i!=1){
vertex((positions.left_eyebrow[i][0]), (positions.left_eyebrow[i][1]));
}
}
endShape(CLOSE);
}
//right eyebrow
var browScale = 0
for (var j=0; j<10; j++){
browScale-=0.02;
beginShape();
vertex((positions.right_eyebrow[0][0]-browScale), (positions.right_eyebrow[0][1]+0.2)+(browScale/2));
for(var i=1; i<4;i++) {
vertex((positions.right_eyebrow[i-1][0]), (positions.right_eyebrow[i-1][1]+0.2));
}
for(var i=4; i>=0;i--) {
if (i!= 3){
vertex((positions.right_eyebrow[i][0]), (positions.right_eyebrow[i][1]));
}
}
vertex((positions.right_eyebrow[0][0]-browScale), (positions.right_eyebrow[0][1])+(browScale/2));
endShape(CLOSE);
}
////////////////////////////////////////////// nose
//bottom of nose
beginShape();
fill(skinShadow_color[skin_color_value]);
stroke(0, 0, 0, 80)
strokeWeight(0.02);
vertex(positions.nose_tip[positions.nose_tip.length-1][0], positions.nose_tip[positions.nose_tip.length-1][1]);
vertex(positions.nose_bridge[positions.nose_bridge.length-1][0], positions.nose_bridge[positions.nose_bridge.length-1][1]);
for(var i=0; i<positions.nose_tip.length;i++) {
vertex(positions.nose_tip[i][0], positions.nose_tip[i][1]);
}
vertex(positions.nose_bridge[positions.nose_bridge.length-1][0], positions.nose_bridge[positions.nose_bridge.length-1][1]);
endShape(CLOSE);
//nose bridge
noStroke();
fill(skinMidtone_color[skin_color_value]);
beginShape();
vertex(((positions.nose_bridge[0][0]+positions.right_eye[4][0])/2)-0.3, positions.nose_bridge[0][1]);
vertex(((positions.nose_bridge[0][0]+positions.left_eye[4][0])/2)+0.3, positions.nose_bridge[0][1]);
vertex(positions.nose_tip[0][0], positions.nose_tip[0][1]);
vertex(positions.nose_tip[2][0], positions.nose_bridge[positions.nose_bridge.length-1][1]+0.3);
vertex(positions.nose_tip[4][0], positions.nose_tip[4][1]);
endShape(CLOSE);
fill(noseColor[skin_color_value]);
var noseWidth = 0;
for (var j=0; j<20; j++){
noseWidth+=0.02
beginShape();
vertex(((positions.nose_bridge[0][0]+positions.right_eye[4][0])/2)-0.3, positions.nose_bridge[0][1]+noseWidth);
vertex(((positions.nose_bridge[0][0]+positions.left_eye[4][0])/2)+0.3, positions.nose_bridge[0][1]+noseWidth);
vertex(positions.nose_tip[0][0]+noseWidth, positions.nose_tip[0][1]);
vertex(positions.nose_tip[2][0], positions.nose_bridge[positions.nose_bridge.length-1][1]+0.3);
vertex(positions.nose_tip[4][0]-noseWidth, positions.nose_tip[4][1]);
endShape(CLOSE);
}
//nose highlight
fill(noseHighlight[skin_color_value]);
var highlightWidth = 0.2;
for (var j=0; j<20; j++){
highlightWidth -= 0.01;
beginShape();
vertex(((positions.nose_bridge[1][0]+positions.right_eye[4][0])/2)-0.4, positions.nose_bridge[1][1]+highlightWidth);
vertex(((positions.nose_bridge[1][0]+positions.left_eye[4][0])/2)+0.4, positions.nose_bridge[1][1]+highlightWidth);
vertex(positions.nose_tip[1][0]+highlightWidth, positions.nose_bridge[positions.nose_bridge.length-1][1]+0.2);
vertex(positions.nose_tip[2][0], positions.nose_bridge[positions.nose_bridge.length-1][1]+0.3);
vertex(positions.nose_tip[3][0]-highlightWidth, positions.nose_bridge[positions.nose_bridge.length-1][1]+0.2);
endShape(CLOSE);
}
}
/*// set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.lookPos = settings[0];
this.eyeAngle = settings[1];
this.skinColor = settings[2];
this.eyeColor = settings[3];
this.eyeSize = settings[4];
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
properties = new Array(4);
properties[0] = this.lookPos;
properties[1] = this.eyeAngle;
properties[2] = this.skinColor;
properties[3] = this.eyeColor;
properties[4] = this.eyeSize;
return properties;
}
}
// given a point, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
100,
90,
14,
100,
47
],
"000002": [
44,
72,
0,
66,
42
],
"000058": [
75,
100,
0,
0,
31
],
"000005": [
50,
100,
23,
61,
30
],
"000006": [
64,
84,
51,
100,
36
],
"000007": [
50,
100,
39,
72,
23
],
"000009": [
8,
100,
24,
64,
34
],
"000010": [
50,
100,
19,
0,
73
],
"000013": [
76,
82,
11,
0,
28
],
"000014": [
21,
100,
69,
100,
42
],
"000015": [
36,
84,
20,
23,
0
],
"000016": [
100,
100,
23,
76,
30
],
"000018": [
17,
100,
0,
26,
20
],
"000020": [
73,
100,
21,
15,
9
],
"000023": [
100,
72,
28,
0,
33
],
"000025": [
58,
100,
50,
54,
23
],
"000028": [
50,
100,
32,
86,
71
],
"000029": [
36,
100,
19,
0,
31
],
"000030": [
9,
100,
50,
80,
50
],
"000031": [
50,
100,
23,
0,
6
],
"000032": [
58,
92,
9,
59,
23
],
"000035": [
44,
100,
0,
58,
31
],
"000037": [
65,
62,
50,
100,
50
],
"000038": [
50,
100,
0,
0,
12
],
"000040": [
50,
100,
26,
71,
47
],
"000041": [
28,
38,
50,
75,
64
],
"000042": [
31,
100,
0,
0,
43
],
"000043": [
37,
100,
0,
57,
44
],
"000044": [
45,
100,
69,
100,
65
],
"000045": [
59,
100,
32,
75,
57
],
"000047": [
90,
100,
38,
80,
74
],
"000048": [
82,
100,
0,
80,
38
],
"000050": [
39,
69,
25,
75,
38
],
"000051": [
73,
100,
23,
100,
32
],
"000052": [
62,
100,
0,
0,
37
],
"000054": [
23,
100,
24,
0,
64
],
"000055": [
37,
84,
22,
60,
31
],
"000056": [
29,
90,
20,
0,
38
],
"000060": [
65,
62,
50,
100,
43
],
"000064": [
48,
96,
21,
22,
29
],
"000065": [
49,
100,
38,
70,
50
],
"000068": [
25,
100,
14,
76,
21
],
"000069": [
45,
100,
25,
65,
22
],
"000071": [
50,
100,
23,
61,
45
],
"000073": [
29,
61,
23,
29,
61
],
"000076": [
4,
100,
21,
78,
26
],
"000077": [
100,
79,
0,
0,
74
],
"000078": [
7,
100,
31,
100,
60
],
"000079": [
85,
100,
40,
82,
40
],
"000080": [
26,
100,
21,
24,
36
],
"000081": [
51,
82,
37,
77,
23
],
"000083": [
43,
100,
27,
55,
20
],
"000085": [
52,
100,
24,
32,
88
],
"000086": [
8,
100,
31,
63,
59
],
"000088": [
90,
94,
23,
89,
63
],
"000091": [
54,
88,
11,
20,
44
],
"000092": [
17,
100,
10,
25,
45
],
"000096": [
33,
100,
16,
15,
53
],
"000097": [
57,
100,
30,
0,
62
],
"000099": [
27,
100,
0,
26,
50
],
"000100": [
58,
77,
27,
72,
58
],
"000103": [
27,
100,
18,
30,
49
],
"000104": [
36,
100,
32,
19,
37
],
"000106": [
9,
100,
50,
63,
80
],
"000108": [
43,
100,
21,
0,
45
],
"000109": [
66,
100,
29,
24,
33
],
"000110": [
27,
87,
27,
54,
100
],
"000111": [
83,
100,
35,
22,
70
],
"000114": [
44,
100,
30,
80,
46
],
"000115": [
60,
82,
30,
56,
22
],
"000116": [
45,
100,
26,
80,
31
],
"000117": [
64,
89,
71,
94,
71
],
"000118": [
17,
100,
37,
98,
79
],
"000121": [
48,
100,
16,
100,
55
],
"000122": [
43,
91,
27,
57,
55
],
"000125": [
50,
100,
30,
20,
36
],
"000126": [
79,
100,
14,
0,
86
],
"000129": [
72,
97,
34,
27,
31
],
"000131": [
100,
100,
16,
100,
66
],
"000132": [
52,
100,
48,
87,
67
],
"000133": [
48,
100,
19,
26,
57
],
"000134": [
21,
69,
79,
85,
48
],
"000135": [
96,
79,
38,
100,
70
],
"000137": [
80,
93,
19,
66,
17
],
"000140": [
29,
100,
30,
0,
59
],
"000142": [
38,
96,
25,
27,
41
],
"000143": [
66,
100,
24,
2,
43
],
"000145": [
46,
100,
7,
72,
68
],
"000146": [
45,
56,
37,
100,
34
],
"000147": [
67,
100,
10,
0,
66
],
"000148": [
75,
47,
10,
28,
37
],
"000150": [
40,
100,
19,
11,
39
],
"000151": [
34,
100,
38,
100,
48
],
"000152": [
41,
94,
25,
57,
23
],
"000153": [
44,
98,
17,
68,
33
],
"000155": [
50,
100,
29,
100,
88
],
"000156": [
50,
75,
24,
49,
74
],
"000160": [
40,
100,
26,
70,
36
],
"000161": [
45,
100,
14,
23,
34
],
"000157": [
50,
100,
50,
50,
71
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// other variables can be in here too
// these control the colors used
function FelizardoFace() {
const bg_color = [225, 206, 187];
const fg_color = [151, 102, 52];
const stroke_color = [95, 52, 8];
// these are state variables for a face
// (your variables may be different)
this.tilt_value = 0;
this.mouth_value = 1;
this.eye_size = 0;
this.eyelid = 0;
this.mouth_open = 1;
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
colorMode(HSL, 360, 100, 100, 1);
//head
let head_location = average_point(positions.chin)
//eyes
let eye_L = average_point(positions.left_eye)
let eye_R = average_point(positions.right_eye)
//mouth points
//*top
let m_left = positions.top_lip[0];
let m_m_left = positions.top_lip[1];
let m_top = positions.top_lip[3];
let m_m_right = positions.top_lip[5]
let m_right = positions.top_lip[6];
let m_bot = positions.bottom_lip[9];
//bottom
let m_b1 = positions.bottom_lip[0];
let m_b2 = positions.bottom_lip[1];
let m_b3 = positions.bottom_lip[4];
let m_b4 = positions.bottom_lip[6];
//mouth pts for teeth
let m_teeth = positions.top_lip[10];
let m_teeth2 = positions.top_lip[8];
let m_teeth3 = positions.top_lip[7];
let m_teeth4 = positions.top_lip[11];
//brow points
let b_r1 = positions.right_eyebrow[0];
let b_r2 = positions.right_eyebrow[4];
let b_l1 = positions.left_eyebrow[0];
let b_l2 = positions.left_eyebrow[4];
//cheek pts
let ch_1 = positions.chin[2];
let ch_2 = positions.chin[14];
//CHIN PTS
let b_ch_1 = positions.chin[5];
let b_ch_2 = positions.chin[7];
let b_ch_3 = positions.chin[8];
let b_ch_4 = positions.chin[9];
let b_ch_5 = positions.chin[11];
//*******************************************************************************
//********************** E Y E S ************************************
//*******************************************************************************
//**************** e y e s h a p e **************************
noStroke();
fill(255);
ellipse(eye_L[0], eye_L[1], .9 * this.eye_size, .9 * this.eye_size);
ellipse(eye_R[0], eye_R[1], .9 * this.eye_size, .9 * this.eye_size);
//**************** e y e c o l o u r **************************
//******cornea
fill(1 * this.eye_colour, 75, 50, 1); // eye colour
ellipse(eye_L[0], eye_L[1], .6 * this.eye_size, .6 * this.eye_size);
ellipse(eye_R[0], eye_R[1], .6 * this.eye_size, .6 * this.eye_size);
//********* iris
fill(0);
ellipse(eye_L[0], eye_L[1], .2 * this.eye_size, .2 * this.eye_size);
ellipse(eye_R[0], eye_R[1], .2 * this.eye_size, .2 * this.eye_size);
//************* e y e l i d s *******************
//********** SURPRISED
if (this.eyelid == 0) {
fill(0);
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, 15, 165, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, 15, 165, CHORD);
}
//*********** MELLOW
if (this.eyelid == 1) {
fill(0);
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, -180, 0, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, -180, 0, CHORD);
}
//*********** ANGRY
if (this.eyelid == 2) {
fill(0);
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, -150, 20, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, 160, -30, CHORD);
//lower lids
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, -150, 20, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, 160, -30, CHORD);
}
//*********** SCHLEEP
if (this.eyelid == 3) {
fill(0);
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, -180, 0, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, -180, 0, CHORD);
//lower lids
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, 20, 160, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, 20, 160, CHORD);
}
//*******************************************************************************
//********************** C H I N ******************************
//*******************************************************************************
stroke(0);
strokeWeight(.02);
line(b_ch_2[0], b_ch_2[1], ch_1[0], ch_1[1]); //cheek to jaw connector
line(b_ch_4[0], b_ch_4[1], ch_2[0], ch_2[1]);
fill(20, 0, this.skin);
noStroke();
beginShape();
vertex(b_ch_1[0], b_ch_1[1]);
vertex(b_ch_2[0], b_ch_2[1] + 1 * this.chin);
vertex(b_ch_3[0], b_ch_3[1] + 1 * this.chin);
vertex(b_ch_4[0], b_ch_4[1] + 1 * this.chin);
vertex(b_ch_5[0], b_ch_5[1]);
endShape();
fill(0);
ellipse(b_ch_2[0], b_ch_2[1] - .08, .07, .07); //peg
ellipse(b_ch_4[0], b_ch_4[1] - .08, .07, .07);
//*******************************************************************************
//********************** M O U T H **************************
//*******************************************************************************
//********** bottom lip *check if working properly.
//cheek pivot
fill(0);
ellipse(ch_2[0], ch_2[1], .2, .2);
ellipse(ch_1[0], ch_1[1], .2, .2);
//cheek wires
strokeWeight(.02);
stroke(0);
noFill();
line(ch_2[0], ch_2[1], m_b1[0], m_b1[1]);
line(ch_2[0], ch_2[1], m_b1[0], (m_b1[1] * this.mouth_open) + .05);
line(ch_1[0], ch_1[1], m_b4[0], m_b4[1]);
line(ch_1[0], ch_1[1], m_b4[0], (m_b4[1] * this.mouth_open) + .05);
stroke(360, 70, 60, 1); //bottom lip colour
strokeWeight(.4);
noFill();
bezier(m_b1[0], m_b1[1], m_b2[0], m_b2[1] * this.mouth_open, m_b3[0], m_b3[1] * this.mouth_open, m_b4[0], m_b4[1]);
//********** top_lip
noFill();
strokeWeight(.5);
stroke(360, 100, 60, 1); //thick top lip colour
bezier(m_left[0], m_left[1], m_m_left[0], m_m_left[1] - .2, m_m_right[0], m_m_right[1] - .2, m_right[0], m_right[1]);
strokeWeight(.3);
stroke(360, 100, 40, 1); //top lip shade
bezier(m_left[0], m_left[1] + .1, m_m_left[0], m_m_left[1], m_m_right[0], m_m_right[1], m_right[0], m_right[1] + .1);
//************* top teeth
fill(225);
noStroke();
arc(m_teeth3[0], m_teeth3[1], .45 * .5, .7 * .5, 15 + 20, 165, CHORD); //right back
arc(m_teeth3[0] - .2, m_teeth3[1], .45 * .5, .7 * .5, 15, 165, CHORD); //right back 2
arc(m_teeth4[0], m_teeth4[1], .45 * .5, .7 * .5, 15 - 20, 165 - 10, CHORD); //left back
arc(m_teeth4[0] + .2, m_teeth4[1], .45 * .5, .7 * .5, 15, 165, CHORD); //left back 2
fill(255);
arc(m_teeth[0], m_teeth[1] - .15, .45, .7, 15, 165, CHORD);
arc(m_teeth2[0], m_teeth2[1] - .15, .45, .7, 15, 165, CHORD);
//*******************************************************************************
//********************** M or F **************************************
//*******************************************************************************
if (this.horn == 0) {
fill(100, 0, 50);
ellipse(head_location[0], head_location[1] - 3.29, .5, .25);
fill(20, 0, this.skin);
ellipse(head_location[0], head_location[1] - 3.31, .5, .2);
stroke(200, 0, this.skin - 10);
strokeWeight(.1);
line(head_location[0], head_location[1] - 3.4, head_location[0], head_location[1] - 4.5)
noStroke(0);
fill(20, 0, this.skin + 10);
ellipse(head_location[0], head_location[1] - 4.5, .3, .3);
}
//*******************************************************************************
//********************** B R O W S **************************
//*******************************************************************************
//eyebrow background mechanics
fill(0);
strokeWeight(.02);
stroke(0);
ellipse(head_location[0], head_location[1] - 3, .2, .2);
line(head_location[0], head_location[1] - 3, b_l1[0] * .8, b_l1[1] * 1.4 * this.eyebrows);
line(head_location[0], head_location[1] - 3, b_l2[0] * .8, b_l2[1] * 1.1 * this.eyebrows);
line(head_location[0], head_location[1] - 3, b_r1[0] * .8, b_r1[1] * 1.1 * this.eyebrows);
line(head_location[0], head_location[1] - 3, b_r2[0] * .8, b_r2[1] * 1.4 * this.eyebrows);
strokeWeight(.55);
stroke(20, 0, this.skin);
line(b_l1[0] * .8, b_l1[1] * 1.4 * this.eyebrows, b_l2[0] * .8, b_l2[1] * 1.1 * this.eyebrows); // left eyebrow
line(b_r1[0] * .8, b_r1[1] * 1.1 * this.eyebrows, b_r2[0] * .8, b_r2[1] * 1.4 * this.eyebrows); // right eyebrow
fill(0)
noStroke();
ellipse(b_l1[0] * .8, b_l1[1] * 1.4 * this.eyebrows, .06, .06);
ellipse(b_l2[0] * .8, b_l2[1] * 1.1 * this.eyebrows, .06, .06);
ellipse(b_r1[0] * .8, b_r1[1] * 1.1 * this.eyebrows, .06, .06);
ellipse(b_r2[0] * .8, b_r2[1] * 1.4 * this.eyebrows, .06, .06);
//*******************************************************************************
//*******************************************************************************
//*******************************************************************************
}
/* set internal properties based on list numbers 0-100 */
//put all slider elements here first
this.setProperties = function(settings) {
this.eye_size = map(settings[0], 0, 100, .9, 1.1);
this.eyelid = int(map(settings[1], 0, 100, 0, 4));
this.eyebrows = map(settings[2], 0, 100, .9, 1.1);
this.mouth_open = map(settings[4], 0, 100, 1, 1.5);
this.eye_colour = map(settings[3], 0, 100, 1, 359);
this.horn = int(map(settings[5], 0, 100, 0, 1));
this.skin = map(settings[6], 0, 100, 100, 50);
this.chin = map(settings[7], 0, 100, 0, 1);
}
/* get internal properties as list of numbers 0-100 */
//then wire them up here in this order (flip it round)
this.getProperties = function() {
let settings = new Array(8);
settings[0] = map(this.eye_size, .9, 1.1, 0, 100);
settings[1] = map(this.eyelid, 0, 4, 0, 100);
settings[2] = map(this.eyebrows, 1, 1.5, 0, 100);
settings[4] = map(this.mouth_open, 1, 1.5, 0, 100);
settings[3] = map(this.eye_colour, 1, 359, 0, 100);
settings[5] = map(this.horn, 0, 1, 0, 100);
settings[6] = map(this.skin, 100, 50, 0, 100);
settings[7] = map(this.chin, 0, 1, 0, 100);
return settings;
}
}
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for (var i = 0; i < list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
24,
56,
-12,
27,
42,
100,
69,
1
],
"000002": [
50.999999999999964,
0,
-19.999999999999996,
0,
33.00000000000001,
100,
100,
12
],
"000058": [
51.99999999999997,
75,
-14.79999999999999,
56.00000000000001,
29.000000000000004,
100,
81,
2
],
"000005": [
49.99999999999997,
50,
-19.999999999999996,
28.000000000000004,
10.999999999999988,
100,
76,
32
],
"000006": [
48.99999999999997,
50,
-19.999999999999996,
91,
50,
100,
50,
26
],
"000007": [
49.99999999999997,
25,
-19.999999999999996,
70,
22.00000000000002,
0,
73,
50
],
"000009": [
49.99999999999997,
50,
-19.999999999999996,
0,
78.00000000000003,
100,
63,
0
],
"000010": [
49.99999999999997,
50,
-19.999999999999996,
16,
50,
100,
62,
24
],
"000013": [
49.99999999999997,
0,
-14.399999999999991,
18,
50,
0,
50,
50
],
"000014": [
49.99999999999997,
50,
-19.999999999999996,
65,
50,
100,
32,
50
],
"000015": [
0,
75,
-19.999999999999996,
97,
100,
0,
82,
38
],
"000016": [
49.99999999999997,
50,
-19.999999999999996,
96,
50,
0,
56.00000000000001,
22
],
"000018": [
0,
75,
-19.999999999999996,
17,
18.000000000000014,
100,
77,
2
],
"000020": [
8.000000000000004,
75,
-19.999999999999996,
92,
100,
0,
67,
34
],
"000028": [
0,
50,
-19.999999999999996,
22,
50,
100,
50,
3
],
"000023": [
0,
50,
-15.199999999999992,
90,
50,
0,
87,
20
],
"000025": [
0,
50,
-19.999999999999996,
89,
50,
0,
42,
0
],
"000029": [
0,
75,
-11.99999999999999,
20,
29.000000000000004,
100,
86,
26
],
"000030": [
100,
100,
11.20000000000001,
51,
8.000000000000007,
0,
70,
19
],
"000031": [
15.000000000000007,
75,
-15.999999999999993,
30,
50,
100,
32,
64
],
"000032": [
0,
25,
20.000000000000018,
98,
89.00000000000001,
0,
63,
48
],
"000035": [
100,
100,
-19.999999999999996,
69,
45.000000000000014,
100,
100,
13
],
"000037": [
61.99999999999998,
50,
-19.999999999999996,
75,
41.99999999999999,
0,
31,
60
],
"000038": [
100,
0,
20.000000000000018,
86,
37.999999999999986,
0,
75,
31
],
"000040": [
49.99999999999997,
50,
10.000000000000009,
67,
54,
100,
82,
0
],
"000041": [
70.99999999999999,
0,
20.000000000000018,
69,
50.99999999999998,
0,
59,
45
],
"000042": [
100,
100,
8.000000000000007,
8,
50,
100,
62,
0
],
"000043": [
48.99999999999997,
100,
15.600000000000014,
56.00000000000001,
23,
100,
69,
0
],
"000044": [
100,
25,
0,
66,
14.000000000000012,
100,
20,
18
],
"000045": [
22.00000000000001,
0,
4.400000000000004,
11,
46,
100,
66,
9
],
"000047": [
49.99999999999997,
50,
0,
68,
50,
100,
28.999999999999996,
0
],
"000048": [
100,
75,
1.200000000000001,
61,
43.000000000000014,
0,
100,
57.99999999999999
],
"000050": [
100,
100,
20.000000000000018,
70,
98,
0,
73,
83
],
"000051": [
49.99999999999997,
0,
-16.39999999999999,
46,
50,
0,
57.99999999999999,
0
],
"000052": [
55.99999999999997,
25,
12.800000000000011,
71,
58.999999999999986,
0,
56.00000000000001,
46
],
"000054": [
100,
75,
20.000000000000018,
25,
66.00000000000001,
100,
61,
0
],
"000055": [
100,
25,
2.400000000000002,
72,
39.000000000000014,
0,
70,
44
],
"000056": [
100,
25,
4.800000000000004,
65,
62.000000000000014,
0,
80,
0
],
"000060": [
19.00000000000001,
100,
-19.999999999999996,
67,
100,
0,
11,
36
],
"000064": [
0,
0,
4.800000000000004,
88,
69,
0,
63,
32
],
"000065": [
0,
25,
-5.999999999999983,
64,
41.99999999999999,
0,
28.000000000000004,
23
],
"000068": [
97,
25,
18.000000000000014,
40,
79.99999999999999,
0,
22,
37
],
"000069": [
100,
100,
20.000000000000018,
69,
100,
0,
67,
44
],
"000071": [
62.99999999999998,
0,
-19.199999999999996,
23,
50,
100,
72,
0
],
"000073": [
100,
75,
-6.799999999999984,
67,
66.00000000000001,
100,
70,
0
],
"000076": [
100,
75,
20.000000000000018,
74,
81.99999999999999,
0,
65,
55.00000000000001
],
"000077": [
49.99999999999997,
75,
-7.999999999999985,
60,
25.99999999999998,
100,
71,
0
],
"000078": [
100,
75,
5.200000000000005,
74,
64.99999999999999,
100,
77,
18
],
"000079": [
15.000000000000007,
100,
10.000000000000009,
46,
50,
0,
33,
30
],
"000080": [
100,
25,
6.000000000000005,
72,
23,
0,
57.99999999999999,
26
],
"000081": [
100,
0,
12.400000000000011,
65,
50.99999999999998,
0,
77,
50
],
"000083": [
100,
75,
10.80000000000001,
0,
50,
100,
91,
0
],
"000085": [
93,
100,
12.00000000000001,
0,
22.00000000000002,
100,
74,
0
],
"000086": [
100,
75,
18.400000000000016,
0,
62.000000000000014,
100,
88,
0
],
"000088": [
0,
100,
3.600000000000003,
79,
20.999999999999996,
100,
100,
0
],
"000091": [
49.99999999999997,
50,
14.400000000000013,
70,
25.99999999999998,
0,
64,
23
],
"000092": [
12.000000000000007,
0,
15.200000000000014,
23,
50,
100,
50,
0
],
"000096": [
57.99999999999997,
25,
10.40000000000001,
91,
69,
100,
26,
0
],
"000097": [
69.99999999999999,
75,
8.800000000000008,
40,
14.999999999999991,
100,
50,
0
],
"000099": [
100,
75,
20.000000000000018,
87,
52,
100,
60,
23
],
"000100": [
100,
100,
5.600000000000005,
28.000000000000004,
37.000000000000014,
100,
81,
0
],
"000103": [
51.99999999999997,
50,
0,
66,
50,
100,
50,
0
],
"000104": [
100,
75,
2.8000000000000025,
85,
33.00000000000001,
0,
50,
50
],
"000106": [
93,
0,
20.000000000000018,
90,
66.00000000000001,
100,
30,
0
],
"000108": [
49.99999999999997,
50,
-8.399999999999984,
20,
50,
100,
73,
0
],
"000109": [
49.99999999999997,
100,
8.400000000000007,
74,
49.00000000000002,
0,
54,
27
],
"000110": [
100,
75,
1.200000000000001,
91,
58.00000000000001,
100,
76,
0
],
"000111": [
100,
75,
20.000000000000018,
33,
69,
100,
0,
0
],
"000114": [
49.99999999999997,
50,
0,
71,
50,
0,
50,
50
],
"000115": [
49.99999999999997,
50,
0,
46,
0,
0,
50,
50
],
"000116": [
100,
100,
0,
68,
50,
0,
79,
36
],
"000117": [
100,
25,
-15.59999999999999,
73,
35.00000000000001,
100,
0,
0
],
"000118": [
49.99999999999997,
50,
9.200000000000008,
69,
50,
100,
33,
2
],
"000121": [
49.99999999999997,
0,
0,
62,
50,
100,
50,
0
],
"000122": [
100,
25,
2.0000000000000018,
42,
75,
100,
100,
0
],
"000125": [
96,
0,
20.000000000000018,
53,
60.999999999999986,
0,
43,
27
],
"000126": [
49.99999999999997,
50,
0,
50,
50,
100,
76,
0
],
"000129": [
49.99999999999997,
50,
0.40000000000000036,
62,
24.00000000000002,
0,
73,
43
],
"000131": [
100,
75,
6.000000000000005,
72,
54,
100,
26,
0
],
"000132": [
100,
75,
7.600000000000007,
71,
41.99999999999999,
100,
0,
0
],
"000133": [
92,
75,
17.200000000000017,
22,
28.000000000000025,
100,
33,
0
],
"000134": [
49.99999999999997,
50,
7.200000000000006,
65,
41.000000000000014,
0,
0,
50
],
"000135": [
100,
0,
0,
63,
10.999999999999988,
0,
24,
37
],
"000137": [
0,
75,
-7.5999999999999845,
46,
29.000000000000004,
0,
85,
17
],
"000140": [
100,
100,
-2.39999999999998,
22,
20.999999999999996,
100,
100,
0
],
"000142": [
88.99999999999999,
75,
4.400000000000004,
90,
56.999999999999986,
100,
100,
0
],
"000143": [
100,
25,
20.000000000000018,
86,
69,
0,
50,
35
],
"000145": [
100,
75,
20.000000000000018,
76,
50,
100,
75,
0
],
"000146": [
93,
100,
20.000000000000018,
89,
37.000000000000014,
100,
67,
0
],
"000147": [
94,
100,
20.000000000000018,
50,
50,
100,
67,
0
],
"000148": [
100,
75,
5.200000000000005,
76,
62.999999999999986,
100,
67,
2
],
"000150": [
49.99999999999997,
50,
0,
100,
28.000000000000025,
0,
100,
14.000000000000002
],
"000151": [
0,
100,
14.000000000000012,
68,
50,
100,
79,
0
],
"000152": [
100,
75,
7.200000000000006,
71,
50,
0,
92,
40
],
"000153": [
49.99999999999997,
50,
0,
85,
50,
0,
83,
36
],
"000155": [
93,
100,
12.800000000000011,
0,
49.00000000000002,
100,
65,
0
],
"000156": [
100,
100,
20.000000000000018,
26,
33.00000000000001,
100,
74,
0
],
"000157": [
49.99999999999997,
75,
6.000000000000005,
16,
23,
100,
81,
0
],
"000160": [
49.99999999999997,
50,
0,
69,
25.99999999999998,
0,
79,
83
],
"000161": [
100,
75,
8.000000000000007,
70,
33.999999999999986,
100,
93,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 8;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function HillFace() {
const eye_position = 0.85;
const eye_size1 = 0.6;
const eye_size2 = 0.8;
const pupil_size1 = 0.25;
const pupil_size2 = 0.25;
const rect_height = 4;
const rect_width = 3.5;
const mouth_wide = 1.25;
//BAG COLOURS//
const bag_light = [209, 182, 150];
const bag_mid = [187, 145, 100];
const bag_dark = [144, 102, 73];
const side_shadow_light = [163, 138, 107];
const side_shadow_mid = [140, 109, 75];
const side_shadow_dark = [108, 77, 55];
const top_shadow_light = [182, 158, 129];
const top_shadow_mid = [164, 127, 88];
const top_shadow_dark = [126, 89, 64];
this.eye_value = 2; //1-2
this.eye_brow = 2; //1-2
this.nose_value = 1; //1-2
this.bag_colour = 1; //1-3
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
rectMode(CENTER);
scale(1.5);
noStroke();
///HEAD//////
//front
let face_pos = segment_average(positions.chin);
if (this.bag_colour == 1) {
fill(bag_light);
}
else if (this.bag_colour == 2) {
fill(bag_mid);
}
else if (this.bag_colour == 3) {
fill(bag_dark);
}
rect(0, -0.25, rect_width, rect_height);
//pointy detail
triangle(-1.75, 1.74, -1.75, 2.25, -1.25, 1.74);
push();
triangle(-0.6, 1.74, -0.95, 2.25, -1.3, 1.74);
translate(0.5, 0);
triangle(-0.4, 1.74, -0.75, 2.25, -1.1, 1.74);
translate(0.7, 0);
triangle(-0.4, 1.74, -0.75, 2.25, -1.1, 1.74);
translate(0.6, 0);
triangle(-0.4, 1.74, -0.75, 2.25, -1.1, 1.74);
pop();
triangle(1.25, 1.74, 1.75, 2.25, 1.75, 1.74);
//top
if (this.bag_colour == 1) {
fill(top_shadow_light);
}
else if (this.bag_colour == 2) {
fill(top_shadow_mid);
}
else if (this.bag_colour == 3) {
fill(top_shadow_dark);
}
quad(-2.5, -2.5, -1.75, -2.25, 1.75, -2.25, 1, -2.5);
//side
if (this.bag_colour == 1) {
fill(side_shadow_light);
}
else if (this.bag_colour == 2) {
fill(side_shadow_mid);
}
else if (this.bag_colour == 3) {
fill(side_shadow_dark);
}
quad(-2.5, 1.25, -2.5, -2.5, -1.75, -2.25, -1.75, 1.75);
triangle(-1.75, 1.7, -1.75, 2.25, -2.25, 1.4);
triangle(-2.5, 1.9, -2.5, 1.25, -2, 1.4);
noFill();
stroke(0);
strokeWeight(0.06);
///NOSE//////
let nose_top = positions.nose_bridge[1];
let nose_bottom = positions.nose_bridge[3];
let nose_center = positions.nose_tip[2];
if (this.nose_value == 1) {
line(nose_top[0], nose_top[1], nose_bottom[0], nose_bottom[1]);
line(nose_top[0] - 0.02, nose_top[1], nose_bottom[0], nose_bottom[1]);
arc(nose_center[0], nose_center[1], 0.5, 0.5, 0, 180);
arc(nose_center[0], nose_center[1], 0.5, 0.55, 0, 180);
}
else if (this.nose_value == 2) {
arc(nose_center[0], nose_center[1], 0.5, 0.5, 0, 180);
arc(nose_center[0], nose_center[1], 0.5, 0.55, 0, 180);
}
///MOUTH/////
let mouth_pos = segment_average(positions.bottom_lip);
let lip_top = positions. top_lip[9];
let lip_bottom = positions. bottom_lip[9];
let d = dist(lip_top[0], lip_top[1], lip_bottom[0], lip_bottom[1]);
let mouth = map(d, 0, 1, 0, 10);
let mouth_open = map(mouth, 0, 10, 0, 1);
if (d < 0.2) {
d = 0;
}
ellipse(mouth_pos[0], mouth_pos[1] + 0.1, mouth_wide, mouth_open);
ellipse(mouth_pos[0], mouth_pos[1] + 0.1, mouth_wide, mouth_open + 0.05);
///EYEBROWS/////
let left_eyebrow_pos = segment_average(positions.left_eyebrow);
let right_eyebrow_pos = segment_average(positions.right_eyebrow);
if (this.eye_brow == 1) {
rect(left_eyebrow_pos[0], left_eyebrow_pos[1], 0.7, 0.01);
rect(right_eyebrow_pos[0], right_eyebrow_pos[1], 0.7, 0.01);
}
else if (this.eye_brow == 2) {
fill(0);
rect(left_eyebrow_pos[0], left_eyebrow_pos[1], 0.5, 0.06);
rect(right_eyebrow_pos[0], right_eyebrow_pos[1], 0.5, 0.06);
}
///EYES//////
noFill();
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
if (this.eye_value == 1) {
ellipse(left_eye_pos[0], left_eye_pos[1], eye_size1 - 0.1, eye_size1);
ellipse(right_eye_pos[0], right_eye_pos[1], eye_size1 - 0.1, eye_size1);
ellipse(left_eye_pos[0], left_eye_pos[1], eye_size1 - 0.1, eye_size1 + 0.05);
ellipse(right_eye_pos[0], right_eye_pos[1], eye_size1 - 0.1, eye_size1 + 0.05);
fill(0);
ellipse(left_eye_pos[0], left_eye_pos[1], pupil_size1);
ellipse(right_eye_pos[0], right_eye_pos[1], pupil_size1);
}
else if (this.eye_value == 2) {
arc(left_eye_pos[0], left_eye_pos[1], eye_size2 - 0.2, eye_size2, 0, 180, CHORD);
arc(right_eye_pos[0], right_eye_pos[1], eye_size2 - 0.2, eye_size2, 0, 180, CHORD);
arc(left_eye_pos[0], left_eye_pos[1], eye_size2 - 0.2, eye_size2 + 0.05, 0, 180, CHORD);
arc(right_eye_pos[0], right_eye_pos[1], eye_size2 - 0.2, eye_size2 + 0.05, 0, 180, CHORD);
fill(0);
ellipse(left_eye_pos[0], left_eye_pos[1] + 0.15, pupil_size2);
ellipse(right_eye_pos[0], right_eye_pos[1] + 0.15, pupil_size2);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.eye_value = int(map(settings[0], 0, 100, 1, 2));
this.eye_brow = int(map(settings[1], 0, 100, 1, 2));
this.nose_value = int(map(settings[2], 0, 100, 1, 2));
this.bag_colour = int(map(settings[3], 0, 100, 1, 3));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(4);
settings[0] = map(this.eye_value, 1, 2, 0, 100);
settings[1] = map(this.eye_brow, 1, 2 , 0, 100);
settings[2] = map(this.nose_value, 1, 2, 0, 100);
settings[3] = map(this.bag_colour, 1, 3, 0, 100);
return settings;
}
}
{
"000018": [
100,
100,
100,
0
],
"000020": [
100,
100,
0,
0
],
"000023": [
0,
100,
0,
0
],
"000025": [
100,
100,
0,
0
],
"000028": [
100,
100,
100,
50
],
"000029": [
0,
0,
100,
0
],
"000030": [
100,
0,
0,
0
],
"000031": [
0,
100,
100,
0
],
"000032": [
100,
0,
0,
0
],
"000035": [
100,
100,
100,
0
],
"000037": [
100,
100,
0,
100
],
"000038": [
0,
100,
0,
0
],
"000040": [
100,
100,
100,
0
],
"000041": [
100,
100,
0,
50
],
"000042": [
0,
0,
100,
0
],
"000043": [
100,
100,
100,
0
],
"000044": [
100,
100,
100,
100
],
"000045": [
100,
100,
100,
0
],
"000047": [
100,
100,
100,
50
],
"000048": [
100,
100,
0,
0
],
"000050": [
100,
100,
0,
0
],
"000051": [
100,
0,
0,
0
],
"000052": [
0,
100,
0,
50
],
"000054": [
0,
0,
100,
0
],
"000055": [
100,
100,
0,
0
],
"000056": [
0,
100,
0,
0
],
"000058": [
0,
100,
100,
0
],
"000060": [
100,
100,
0,
100
],
"000064": [
0,
100,
0,
0
],
"000065": [
100,
100,
0,
50
],
"000068": [
100,
0,
0,
0
],
"000069": [
100,
100,
0,
0
],
"000071": [
0,
0,
100,
0
],
"000073": [
100,
100,
100,
0
],
"000076": [
100,
100,
0,
0
],
"000077": [
100,
100,
100,
0
],
"000078": [
100,
100,
100,
0
],
"000079": [
100,
0,
0,
50
],
"000080": [
0,
100,
0,
0
],
"000081": [
100,
100,
0,
50
],
"000083": [
100,
100,
100,
0
],
"000085": [
0,
100,
100,
0
],
"000086": [
100,
100,
100,
0
],
"000088": [
100,
100,
100,
0
],
"000091": [
100,
100,
0,
0
],
"000092": [
0,
0,
100,
0
],
"000096": [
100,
100,
100,
0
],
"000097": [
0,
0,
100,
0
],
"000099": [
0,
0,
100,
0
],
"000100": [
100,
0,
100,
0
],
"000103": [
0,
100,
100,
0
],
"000001": [
100,
0,
100,
0
],
"000002": [
100,
100,
100,
0
],
"000005": [
0,
0,
100,
0
],
"000006": [
100,
0,
100,
50
],
"000007": [
100,
100,
0,
0
],
"000009": [
100,
100,
100,
0
],
"000010": [
0,
0,
100,
0
],
"000013": [
0,
0,
0,
0
],
"000014": [
100,
100,
100,
100
],
"000015": [
100,
100,
0,
0
],
"000016": [
100,
100,
0,
0
],
"000161": [
0,
100,
100,
0
],
"000160": [
100,
100,
0,
0
],
"000157": [
0,
0,
100,
0
],
"000156": [
0,
0,
100,
0
],
"000155": [
100,
100,
100,
0
],
"000153": [
100,
100,
0,
0
],
"000152": [
0,
100,
0,
0
],
"000151": [
100,
100,
100,
50
],
"000150": [
0,
100,
0,
0
],
"000148": [
0,
100,
100,
0
],
"000147": [
0,
0,
100,
0
],
"000146": [
100,
100,
100,
50
],
"000145": [
100,
100,
100,
0
],
"000143": [
0,
0,
0,
0
],
"000142": [
0,
100,
100,
0
],
"000140": [
0,
0,
100,
50
],
"000137": [
100,
100,
0,
0
],
"000135": [
100,
100,
0,
50
],
"000134": [
100,
100,
0,
100
],
"000133": [
0,
0,
100,
0
],
"000132": [
100,
100,
100,
50
],
"000131": [
100,
100,
100,
0
],
"000129": [
0,
100,
0,
0
],
"000126": [
0,
0,
100,
0
],
"000125": [
0,
100,
0,
0
],
"000122": [
100,
0,
100,
0
],
"000121": [
100,
100,
100,
0
],
"000118": [
100,
100,
100,
50
],
"000117": [
100,
100,
100,
100
],
"000116": [
100,
100,
0,
0
],
"000115": [
0,
0,
0,
0
],
"000114": [
100,
100,
0,
0
],
"000111": [
100,
0,
100,
50
],
"000110": [
0,
100,
100,
0
],
"000109": [
0,
0,
0,
0
],
"000108": [
0,
0,
100,
0
],
"000106": [
100,
100,
100,
0
],
"000104": [
0,
0,
0,
0
]
}
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 8;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function HoFace() {
// these are state variables for a face
// (your variables should be different!)
//pumpkin colour (Hair)
const yellow = color(255, 255, 0);
const mid_yellow = color(255, 117, 24);
const dark_yellow = color(127, 51, 0);
const error_green = color(0, 255, 0);
//eye colour
const brown = color(69,24,0);
const blue = color(135,206,250);
const grey = color(128,128,128);
const pink = color(255,182,193);
/*
* earSize can vary from 0 to 4
* earDist is the distance between ears and varies from 0 to 4
* faceColor is 1,2,3,4 for yellow,blue,red, or violet respectively
*/
this.leafSize = 5;
this.leafDist = 5;
this.hairColor = 1;
this.eyeColor = 1;
this.blushColor = 1;
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
noStroke();
push();
if(this.hairColor == 0) {
fill(yellow);
}
else if (this.hairColor==1) {
fill(mid_yellow);
}
else if (this.hairColor==2) {
fill(dark_yellow);
}
else {
fill(error_green);
}
// head
push();
scale(1/3);
translate(-4,0);
noStroke();
ellipse(0, 0, 7,10);
ellipse(2, 0, 5,10);
ellipse(4, 0, 8,10);
ellipse(6, 0, 5,10);
ellipse(8, 0, 7,10);
pop();
pop();
//leaf//
push();
scale(1/3);
let leafRadius = map(this.leafSize, 0, 10, 0.3, 2);
let leafXPos = map(this.leafDist, 0, 10, 0.5, 2);
fill(58,23,11);
noStroke();
rect(-2+leafXPos,-8.5,leafRadius+1.5,4,0.2,1,1,1);
pop();
//leaf//
push();
//nose//
let nose_top = positions.nose_bridge[0];
let nose_bottom = positions.nose_bridge[3];
stroke(0);
strokeWeight(0.15);
// line(nose_top[0], nose_top[1], nose_bottom[0], nose_bottom[1]); //top
fill(0);
triangle(nose_bottom[0], nose_bottom[1], nose_top[0], nose_top[0],nose_bottom[1], nose_bottom[1]);
let nose_end = null;
if(nose_top[0] < nose_bottom[0]) {
nose_end = positions.nose_tip[0];
}
else {
nose_end = positions.nose_tip[4];
}
// let nose_end = positions.nose_tip[4];
let nose_center = positions.nose_tip[2];
pop();
// line(nose_end[0], nose_end[1], nose_center[0], nose_center[1]); //bottom
//nose//
//mouth//
// let top_lip = positions.top_lip[0];
// let bottom_lip = positions.bottom_lip[]
push();
push();
fill(0);
noStroke();
ellipse(positions.bottom_lip[7][0], positions.bottom_lip[6][1],0.2);
ellipse(positions.bottom_lip[8][0], positions.bottom_lip[8][1],0.2);
ellipse(positions.bottom_lip[9][0], positions.bottom_lip[9][1],0.2);
ellipse(positions.bottom_lip[10][0], positions.bottom_lip[10][1],0.2);
ellipse(positions.bottom_lip[0][0], positions.bottom_lip[0][1],0.2);
pop();
pop();
push();
if(this.eyeColor == 0) {
fill(brown);
}
else if (this.eyeColor==1) {
fill(blue);
}
else if (this.eyeColor==2) {
fill(grey);
}
else {
fill(error_green);
}
//eyes//
noStroke();
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
push();
translate(0,0.5);
push();
fill(255);
ellipse(left_eye_pos[0], left_eye_pos[1], 0.5);
ellipse(right_eye_pos[0], right_eye_pos[1], 0.5);
pop();
push();
translate(0,0);
ellipse(left_eye_pos[0], left_eye_pos[1], 0.3);
ellipse(right_eye_pos[0], right_eye_pos[1], 0.3);
pop();
pop();
pop();
//eyes//
if(this.blushColor == 0) {
fill(pink);
}
else if (this.eyeColor==1) {
noFill();
}
else if (this.eyeColor==2) {
noFill();
}
else {
noFill();
}
//blush
ellipse(1.5,0,0.5,0.25);
ellipse(-1.5,0,0.5,0.25);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.leafSize = map(settings[0], 0, 100, 0, 10);
this.leafDist = map(settings[1], 0, 100, 0, 10);
this.hairColor = int(map(settings[2], 0, 100, 0, 3));
this.eyeColor = int(map(settings[3], 0, 100, 0, 3));
this.blushColor = int(map(settings[4], 0, 100, 0, 3));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(5);
settings[0] = map(this.leafSize, 0, 10, 0, 100);
settings[1] = map(this.leafDist, 0, 10, 0, 100);
settings[2] = map(this.hairColor, 0, 4, 0, 100);
settings[3] = map(this.eyeColor, 0, 4, 0, 100);
settings[4] = map(this.blushColor, 0, 4, 0, 100);
return settings;
}
}
{
"000001": [
50,
50,
0,
0,
50
],
"000002": [
50,
50,
50,
0
],
"000005": [
50,
50,
0,
75
],
"000006": [
50,
50,
0,
0
],
"000007": [
50,
50,
75,
0,
50
],
"000009": [
50,
50,
75,
0,
0
],
"000010": [
50,
50,
0,
50,
0
],
"000013": [
50,
50,
0,
0,
75
],
"000014": [
50,
50,
75,
0,
0
],
"000015": [
50,
50,
50,
0,
75
],
"000016": [
50,
50,
75,
0,
50
],
"000018": [
50,
50,
0,
0,
0
],
"000020": [
50,
50,
75,
0,
50
],
"000023": [
50,
50,
75,
0,
50
],
"000025": [
50,
50,
75,
0,
50
],
"000028": [
50,
50,
0,
0,
0
],
"000029": [
50,
50,
0,
25,
0
],
"000030": [
50,
50,
0,
0,
75
],
"000031": [
50,
50,
0,
50,
0
],
"000032": [
50,
50,
0,
0,
75
],
"000035": [
50,
50,
50,
0,
0
],
"000037": [
50,
50,
50,
0,
75
],
"000038": [
50,
50,
50,
50,
50
],
"000040": [
50,
50,
50,
0,
0
],
"000041": [
50,
50,
50,
0,
75
],
"000042": [
50,
50,
0,
50,
0
],
"000043": [
50,
50,
75,
25,
0
],
"000044": [
50,
50,
75,
0,
0
],
"000045": [
50,
50,
50,
0,
0
],
"000047": [
50,
50,
75,
0,
0
],
"000048": [
50,
50,
75,
0,
50
],
"000050": [
50,
50,
75,
0,
25
],
"000051": [
50,
50,
0,
0,
75
],
"000052": [
50,
50,
50,
50,
75
],
"000054": [
50,
50,
0,
0,
0
],
"000055": [
50,
50,
75,
0,
25
],
"000056": [
50,
50,
75,
0,
25
],
"000058": [
50,
50,
75,
25,
0
],
"000060": [
50,
50,
75,
0,
50
],
"000064": [
50,
50,
50,
0,
0
],
"000065": [
50,
50,
75,
0,
50
],
"000068": [
50,
50,
0,
0,
75
],
"000069": [
50,
50,
75,
0,
25
],
"000071": [
50,
50,
0,
0,
0
],
"000073": [
50,
50,
75,
0,
0
],
"000076": [
50,
50,
75,
0,
50
],
"000077": [
50,
50,
75,
0,
0
],
"000078": [
50,
50,
75,
0,
0
],
"000079": [
50,
50,
0,
0,
75
],
"000080": [
50,
50,
75,
0,
50
],
"000081": [
50,
50,
75,
0,
50
],
"000083": [
50,
50,
50,
25,
0
],
"000085": [
50,
50,
50,
0,
0
],
"000086": [
50,
50,
0,
0,
0
],
"000088": [
50,
50,
50,
0,
0
],
"000091": [
50,
50,
75,
0,
50
],
"000092": [
50,
50,
0,
50,
0
],
"000096": [
50,
50,
75,
0,
0
],
"000097": [
50,
50,
50,
0,
0
],
"000099": [
50,
50,
50,
0,
0
],
"000100": [
50,
50,
0,
0,
0
],
"000103": [
50,
50,
75,
25,
0
],
"000104": [
50,
50,
0,
0,
75
],
"000106": [
50,
50,
0,
0,
0
],
"000108": [
50,
50,
0,
50,
0
],
"000109": [
50,
50,
0,
0,
75
],
"000110": [
50,
50,
0,
0,
0
],
"000111": [
50,
50,
0,
0,
0
],
"000114": [
50,
50,
75,
0,
50
],
"000115": [
50,
50,
0,
0,
75
],
"000116": [
50,
50,
50,
0,
50
],
"000117": [
50,
50,
75,
0,
0
],
"000118": [
50,
50,
75,
0,
0
],
"000121": [
50,
50,
75,
0,
0
],
"000122": [
50,
50,
0,
0,
0
],
"000125": [
50,
50,
0,
50,
75
],
"000126": [
50,
50,
0,
0,
0
],
"000129": [
50,
50,
75,
0,
50
],
"000131": [
50,
50,
75,
0,
0
],
"000132": [
50,
50,
75,
0,
0
],
"000133": [
50,
50,
0,
50,
0
],
"000134": [
50,
50,
75,
0,
50
],
"000135": [
50,
50,
75,
0,
50
],
"000137": [
50,
50,
75,
0,
25
],
"000140": [
50,
50,
0,
25,
0
],
"000142": [
50,
50,
75,
25,
0
],
"000143": [
50,
50,
50,
0,
50
],
"000145": [
50,
50,
75,
0,
0
],
"000146": [
50,
50,
50,
0,
0
],
"000147": [
50,
50,
0,
25,
0
],
"000148": [
50,
50,
75,
25,
0
],
"000150": [
50,
50,
75,
0,
50
],
"000151": [
50,
50,
75,
0,
0
],
"000152": [
50,
50,
0,
0,
75
],
"000153": [
50,
50,
75,
0,
50
],
"000155": [
50,
50,
75,
0,
0
],
"000156": [
50,
50,
0,
25,
0
],
"000157": [
50,
50,
0,
25,
0
],
"000160": [
50,
50,
75,
0,
50
],
"000161": [
50,
50,
75,
0,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 3;
// This where you define your own face object
function HowardFace() {
const light = color(250, 200, 140);
const middle = color(230, 155, 75);
const dark = color(170, 125, 70);
const tan = color(250, 235, 200);
//this.mouth_value
this.fur_colour = 1;
this.ear_length = -1;
this.blush = 0;
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
let left_eye = average_point(positions.left_eye);
let right_eye = average_point(positions.right_eye);
let left_eyebrow = average_point(positions.left_eyebrow);
let right_eyebrow = average_point(positions.right_eyebrow);
let left_d = dist(left_eye[0], left_eye[1], left_eyebrow[0], left_eyebrow[1]);
let right_d = dist(right_eye[0], right_eye[1], right_eyebrow[0], right_eyebrow[1]);
let left_eb_move = map(left_d, 0.4, 0.7, 0.6, 1.5, true);
let right_eb_move = map(right_d, 0.4, 0.7, 0.6, 1.5, true);
left_eye[0] *= 3;
left_eye[1] *= 3;
right_eye[0] *= 3;
right_eye[1] *= 3;
if (this.fur_colour == 1) {
fill(light);
} else if (this.fur_colour == 2) {
fill(middle);
} else {
fill(dark);
}
noStroke();
ellipse(0, 0.15, 5, 5.5);
stroke(tan);
noFill();
strokeWeight(0.3);
fill(tan);
ellipse(0, 1.5, 3, 2.2);
// head outline
noFill();
strokeWeight(0.25);
stroke(60, 50, 50);
beginShape();
vertex(0, -2.625);
//bezierVertex(3, -7.5, 7, -5, 8, 1);
//bezierVertex(8, 1, 10, 8, 0, 9);
bezierVertex(1.05, -2.625, 2.45, -1.75, 2.45, 0.35);
bezierVertex(2.45, 0.35, 2.625, 2.8, 0, 2.8);
bezierVertex(-2.625, 2.8, -2.625, 0.25, -2.55, 0.35);
bezierVertex(-2.45, -1.75, -1.05, -2.625, 0, -2.625);
endShape();
//ears
//Ear colour
if (this.fur_colour == 1) {
fill(light);
} else if (this.fur_colour == 2) {
fill(middle);
} else {
fill(dark);
}
//left ear
beginShape();
curveVertex(-2.4, -0.7);
curveVertex(-2.4, -0.7);
curveVertex(-2.8, -1.4 + this.ear_length);
curveVertex(-2.45, -2.45 + this.ear_length);
curveVertex(-1.05, -2.38);
curveVertex(-1.05, -2.38);
endShape();
//right ear
beginShape();
curveVertex(2.345, -0.7);
curveVertex(2.345, -0.7);
curveVertex(2.8, -1.4 + this.ear_length);
curveVertex(2.45, -2.45 + this.ear_length);
curveVertex(1.05, -2.38);
curveVertex(1.05, -2.38);
endShape();
fill(tan);
stroke(tan);
//left ear inside
beginShape();
curveVertex(-2.1, -1.4);
curveVertex(-2.1, -1.4);
curveVertex(-2.24, -1.225 + this.ear_length);
curveVertex(-2.24, -1.75 + this.ear_length);
curveVertex(-1.575, -2);
curveVertex(-1.575, -2);
endShape();
//left ear inside line
beginShape();
curveVertex(-2.1, -1.4);
curveVertex(-2.1, -1.4);
curveVertex(-1.925, -1.645);
curveVertex(-1.6625, -1.925);
curveVertex(-1.575, -2);
curveVertex(-1.575, -2);
endShape();
//right ear inside
beginShape();
curveVertex(2.1, -1.4);
curveVertex(2.1, -1.4);
curveVertex(2.24, -1.225 + this.ear_length);
curveVertex(2.24, -1.75 + this.ear_length);
curveVertex(1.575, -2);
curveVertex(1.575, -2);
endShape();
//right ear inside line
beginShape();
curveVertex(2.1, -1.4);
curveVertex(2.1, -1.4);
curveVertex(1.925, -1.645);
curveVertex(1.6625, -1.925);
curveVertex(1.575, -2);
curveVertex(1.575, -2);
endShape();
//left brow
push();
strokeWeight(0.375)
translate(0, 1 - left_eb_move);
beginShape();
curveVertex(-1.225, -1.12);
curveVertex(-1.225, -1.12);
curveVertex(-1.05, -1.19);
curveVertex(-0.91, -1.19);
curveVertex(-0.805, -1.12);
curveVertex(-0.805, -1.12);
endShape();
beginShape();
curveVertex(-1.225, -1.12);
curveVertex(-1.225, -1.12);
curveVertex(-1.05, -1.085);
curveVertex(-0.91, -1.085);
curveVertex(-0.805, -1.12);
curveVertex(-0.805, -1.12);
endShape();
//right brow
beginShape();
curveVertex(1.225, -1.12);
curveVertex(1.225, -1.12);
curveVertex(1.05, -1.19);
curveVertex(0.91, -1.19);
curveVertex(0.805, -1.12);
curveVertex(0.805, -1.12);
endShape();
beginShape();
curveVertex(1.225, -1.12);
curveVertex(1.225, -1.12);
curveVertex(1.05, -1.085);
curveVertex(0.91, -1.085);
curveVertex(0.805, -1.12);
curveVertex(0.805, -1.12);
endShape();
pop();
// eyes
const green = color('#3bb44a');
const darkGreen = color('#046538');
const lightBlue = color('#9bcde1');
const darkBlue = color('#0c76c1');
const lightBrown = color('#8b5f3c');
const pink = color('#ff9292');
//outline
noStroke();
fill(40);
ellipse(-1.05, -0.175, 0.735);
ellipse(1.05, -0.175, 0.735);
//iris
if (this.blush < 5) {
fill(lightBlue);
} else {
fill(pink);
}
ellipse(-1.05, -0.175, 0.7);
ellipse(1.05, -0.175, 0.7);
//
fill(40);
ellipse(-1.05, -0.175, 0.455);
ellipse(1.05, -0.175, 0.455);
//white reflection
fill(255);
ellipse(-1.225, -0.35, 0.175, 0.14);
ellipse(0.875, -0.35, 0.175, 0.14);
//mouth open
let top_lip_point = positions.top_lip[9];
let bottom_lip_point = positions.bottom_lip[9];
// fill(255, 0, 0);
let d = dist(top_lip_point[0], top_lip_point[1], bottom_lip_point[0], bottom_lip_point[1])
let mouth = map(d, 0, 0.5, 0, 10);
let mouth_size = map(mouth, 0, 10, 0, 1.5);
fill(250, 100, 100);
stroke(40);
strokeWeight(0.15)
ellipse(0, 1.2, 1.5, mouth_size);
//tongue cover
noStroke();
fill(tan);
ellipse(0.525, 1.12, 1.05, 0.77)
ellipse(-0.525, 1.12, 1.05, 0.77)
if (this.fur_colour == 1) {
fill(light);
} else if (this.fur_colour == 2) {
fill(middle);
} else {
fill(dark);
}
ellipse(0, 0.2, 1.4, 1.5);
fill(tan);
ellipse(0, 0.7, 2.1, 0.9);
//nose
fill(40);
ellipse(0, 0.875, 0.7, 0.525);
//mouth
stroke(40)
noFill();
strokeWeight(0.1575);
beginShape();
curveVertex(-0.07, 1.05);
curveVertex(-0.07, 1.05);
curveVertex(0.35, 1.505);
curveVertex(0.77, 1.54);
curveVertex(1.05, 1.33);
curveVertex(1.05, 1.33);
endShape();
beginShape();
curveVertex(0.07, 1.05);
curveVertex(0.07, 1.05);
curveVertex(-0.35, 1.505);
curveVertex(-0.77, 1.54);
curveVertex(-1.05, 1.33);
curveVertex(-1.05, 1.33);
endShape();
//blush
if (this.blush < 5) {
} else {
noStroke()
fill(200, 50, 50, 180);
ellipse(-1.4, 0.7, 0.8, 0.5);
ellipse(1.4, 0.7, 0.8, 0.5);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.fur_colour = int(map(settings[0], 0, 100, 1, 4));
this.ear_length = map(settings[1], 0, 100, 0, -1);
this.blush = map(settings[2], 0, 100, 0, 10);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(4);
settings[0] = map(this.fur_colour, 1, 4, 0, 100);
settings[1] = map(this.ear_length, 0, -1, 0, 100);
settings[2] = map(this.blush, 0, 10, 0, 100);
return settings;
}
}
// given an array of [x,y] points, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for (var i = 0; i < list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
0,
0,
100
],
"000002": [
0,
28.999999999999996,
100
],
"000005": [
0,
0,
100
],
"000006": [
50,
49,
100
],
"000007": [
0,
100,
0
],
"000009": [
0,
56.99999999999999,
100
],
"000010": [
0,
0,
100
],
"000013": [
0,
0,
0
],
"000014": [
50,
100,
100
],
"000015": [
0,
77,
0
],
"000016": [
0,
86,
0
],
"000018": [
0,
0,
100
],
"000020": [
0,
65,
0
],
"000023": [
0,
76,
0
],
"000025": [
0,
62,
0
],
"000028": [
0,
68,
100
],
"000029": [
0,
0,
100
],
"000030": [
0,
0,
0
],
"000031": [
0,
77,
100
],
"000032": [
0,
50,
0
],
"000035": [
0,
100,
100
],
"000037": [
100,
100,
0
],
"000038": [
0,
83,
0
],
"000040": [
0,
83,
100
],
"000041": [
0,
92,
0
],
"000042": [
0,
30,
100
],
"000043": [
0,
75,
100
],
"000044": [
100,
100,
100
],
"000045": [
0,
65,
100
],
"000047": [
50,
100,
100
],
"000048": [
0,
88,
0
],
"000050": [
0,
88,
0
],
"000051": [
0,
0,
0
],
"000052": [
0,
84,
0
],
"000054": [
0,
0,
100
],
"000055": [
0,
100,
0
],
"000056": [
0,
100,
0
],
"000058": [
0,
100,
100
],
"000060": [
100,
0,
0
],
"000064": [
0,
71,
0
],
"000065": [
0,
100,
0
],
"000068": [
0,
0,
0
],
"000069": [
0,
100,
0
],
"000071": [
0,
0,
100
],
"000073": [
0,
62,
100
],
"000076": [
0,
100,
0
],
"000077": [
0,
71,
100
],
"000078": [
0,
71,
100
],
"000079": [
0,
0,
0
],
"000080": [
0,
100,
0
],
"000081": [
0,
100,
0
],
"000083": [
0,
41,
100
],
"000085": [
0,
53,
100
],
"000086": [
0,
37,
100
],
"000088": [
0,
49,
100
],
"000091": [
0,
93,
0
],
"000092": [
0,
0,
100
],
"000096": [
0,
84,
100
],
"000097": [
0,
62,
100
],
"000099": [
0,
53,
100
],
"000100": [
0,
30,
100
],
"000103": [
0,
76,
100
],
"000104": [
0,
33,
0
],
"000106": [
0,
70,
100
],
"000108": [
0,
0,
100
],
"000109": [
0,
46,
0
],
"000110": [
0,
54,
100
],
"000111": [
100,
19,
100
],
"000114": [
0,
100,
0
],
"000115": [
0,
0,
0
],
"000116": [
0,
59,
0
],
"000117": [
100,
100,
100
],
"000118": [
0,
100,
100
],
"000121": [
0,
100,
100
],
"000122": [
0,
0,
100
],
"000125": [
0,
35,
0
],
"000126": [
50,
0,
100
],
"000129": [
0,
90,
0
],
"000131": [
50,
100,
100
],
"000132": [
50,
100,
100
],
"000133": [
0,
51,
100
],
"000134": [
100,
100,
0
],
"000135": [
50,
100,
0
],
"000137": [
0,
17,
0
],
"000140": [
50,
0,
100
],
"000142": [
0,
66,
100
],
"000143": [
0,
54,
0
],
"000145": [
0,
84,
100
],
"000146": [
0,
63,
100
],
"000147": [
0,
0,
100
],
"000148": [
0,
86,
100
],
"000150": [
0,
24,
0
],
"000151": [
0,
84,
100
],
"000152": [
0,
61,
0
],
"000153": [
0,
61,
0
],
"000155": [
0,
34,
100
],
"000156": [
0,
0,
100
],
"000157": [
0,
0,
100
],
"000160": [
0,
100,
0
],
"000161": [
0,
100,
100
]
}
//var DEBUG_MODE = true;
// var NUM_SLIDERS = 8;
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
function HuFace() {
const face = [134, 89, 54];
const brown = [96, 60, 16];
const orange = [181, 135, 78];
const yellow = [164, 116, 10];
const grey = [129, 120, 101];
const pink = [217, 194, 182];
const horns_color = [254, 233, 217];
const nose_color = [53, 37, 18];
const ear_color = [234, 192, 158];
this.earringc = 1;
this.earDist = 0.3;
this.eyeDist = 0;
this.mouthDist = -0.1;
this.faceColor = 1;
this.fur = 1;
this.furColor = 3;
this.horns = -0.1;
this.draw = function(positions) {
noStroke();
//horns
fill(horns_color);
beginShape();
vertex(positions.chin[0][0]+0.5, positions.left_eyebrow[2][1]-0.3);
vertex(positions.chin[0][0]-0.1,positions.left_eyebrow[2][1]+0.3);
vertex(positions.chin[0][0]-0.5,positions.left_eyebrow[2][1]-1.3);
vertex(positions.left_eyebrow[0][0], positions.left_eyebrow[2][1]-3-this.horns);
vertex(positions.chin[0][0], positions.left_eyebrow[2][1]-1.5);
endShape();
beginShape();
vertex(positions.chin[16][0]-0.4, positions.right_eyebrow[2][1]-0.3);
vertex(positions.chin[16][0]-1.4,positions.right_eyebrow[2][1]+1.3);
vertex(positions.chin[16][0]-0.5,positions.right_eyebrow[2][1]-1.5);
vertex(positions.right_eyebrow[4][0], positions.right_eyebrow[2][1]-3-this.horns);
vertex(positions.chin[16][0], positions.right_eyebrow[2][1]-1.3);
endShape();
//earring
if(this.earringc == 1) {
fill(255, 255, 255);
}
else if (this.earringc == 2) {
fill(pink);
}
else if (this.earringc == 3) {
fill(ear_color);
}
else if (this.earringc == 4) {
fill(yellow);
}
else {
fill(horns_color);
}
ellipse(positions.chin[0][0]-0.3, positions.chin[0][1]-0.1, this.earDist, 0.6);
//fur
if(this.furColor == 1) {
fill(brown);
}
else if (this.furColor == 2) {
fill(pink);
}
else if (this.furColor == 3) {
fill(grey);
}
else if (this.furColor == 4) {
fill(face);
}
else {
fill(horns_color);
}
bezier(positions.chin[0][0]-1.1, positions.chin[0][1]-0.7,positions.chin[0][0]-2, positions.chin[0][1]-this.fur, positions.chin[0][0], positions.chin[0][1], positions.chin[0][0]+1.5, positions.left_eyebrow[2][1]-0.1);
bezier(positions.chin[16][0]+0.9, positions.chin[16][1]-0.7,positions.chin[16][0]+2, positions.chin[16][1]-this.fur, positions.chin[16][0], positions.chin[16][1], positions.chin[16][0]-1.5, positions.right_eyebrow[2][1]-0.1);
//ear
push();
fill(ear_color);
bezier(positions.chin[0][0]-1, positions.chin[0][1]-1,positions.chin[0][0]-2, positions.chin[0][1], positions.chin[0][0], positions.chin[0][1], positions.chin[0][0]+1.5, positions.left_eyebrow[2][1]-0.5);
bezier(positions.chin[16][0]+0.8, positions.chin[16][1]-1,positions.chin[16][0]+2, positions.chin[16][1], positions.chin[16][0], positions.chin[16][1], positions.chin[16][0]-1.5, positions.right_eyebrow[2][1]-0.5);
pop();
// face
if(this.faceColor == 1) {
fill(face);
}
else if (this.faceColor== 2) {
fill(orange);
}
else if (this.faceColor== 3) {
fill(yellow);
}
else if (this.faceColor== 4) {
fill(grey);
}
else {
fill(brown);
}
noStroke();
beginShape();
vertex(positions.chin[0][0]-0.3, positions.chin[0][1]-0.8);
vertex(positions.chin[16][0]-0.3, positions.chin[16][1]-0.8);
vertex(positions.chin[8][0], positions.chin[8][1]);
endShape();
bezier(positions.chin[0][0]-0.3, positions.chin[0][1]-0.79,positions.left_eyebrow[0][0], positions.left_eyebrow[2][1]-1.2, positions.right_eyebrow[4][0], positions.right_eyebrow[2][1]-1.2,positions.chin[16][0]-0.3, positions.chin[16][1]-0.79);
bezier(positions.chin[0][0]-0.29, positions.chin[0][1]-0.8, positions.chin[0][0]-0.4,positions.chin[1][1], positions.chin[7][0], positions.chin[8][1], positions.chin[8][0]+0.01, positions.chin[8][1]);
bezier(positions.chin[16][0]-0.31, positions.chin[16][1]-0.8, positions.chin[16][0]+0.4, positions.chin[15][1], positions.chin[9][0], positions.chin[8][1], positions.chin[8][0]-0.01, positions.chin[8][1]);
//nose bridge
stroke(0);
noFill();
bezier(positions.right_eyebrow[0][0], positions.right_eyebrow[0][1]+0.2, positions.nose_bridge[0][0], positions.nose_bridge[0][1],positions.nose_bridge[2][0]+0.3, positions.nose_bridge[2][1], positions.nose_tip[4][0], positions.nose_tip[4][1]);
bezier(positions.left_eyebrow[4][0], positions.left_eyebrow[4][1]+0.2, positions.nose_bridge[0][0], positions.nose_bridge[0][1],positions.nose_bridge[2][0]+0.3, positions.nose_bridge[2][1], positions.nose_tip[0][0], positions.nose_tip[0][1]);
//up nose
fill(nose_color);
noStroke();
let nose_up = positions.nose_tip[0];
let nose_upr = positions.nose_tip[4];
ellipse(nose_up[0], nose_up[1]+0.3,0.5, 0.3);
ellipse(nose_upr[0], nose_up[1]+0.3,0.5, 0.3);
stroke(2);
noFill();
bezier(positions.nose_tip[0][0]-0.1,positions.nose_tip[0][1]+0.1,positions.nose_tip[2][0],positions.nose_tip[2][1]+0.1,positions.nose_tip[2][0]+0.3,positions.nose_tip[2][1],positions.nose_tip[4][0]+0.1,positions.nose_tip[4][1]+0.1);
//eyebows
let left_eyebrow1 = positions.left_eyebrow[4];
let left_eyebrow2 = positions.left_eyebrow[2];
let left_eyebrow3 = positions.left_eyebrow[0];
let right_eyebrow1 = positions.right_eyebrow[4];
let right_eyebrow2 = positions.right_eyebrow[2];
let right_eyebrow3 = positions.right_eyebrow[0];
noFill();
bezier(left_eyebrow1[0], left_eyebrow1[1], left_eyebrow2[0], left_eyebrow2[1], left_eyebrow2[0], left_eyebrow2[1], left_eyebrow3[0], left_eyebrow3[1]);
bezier(right_eyebrow1[0], right_eyebrow1[1], right_eyebrow2[0], right_eyebrow2[1], right_eyebrow2[0], right_eyebrow2[1], right_eyebrow3[0], right_eyebrow3[1]);
//eyes
stroke(0);
fill(255);
ellipse(positions.left_eye[1][0], positions.left_eye[5][1], 0.8, 0.5);
ellipse(positions.right_eye[2][0], positions.right_eye[4][1], 0.8, 0.5);
noStroke();
fill(0);
ellipse(positions.left_eye[1][0]-this.eyeDist, positions.left_eye[5][1], 0.7, 0.48);
ellipse(positions.right_eye[2][0]-this.eyeDist,positions.right_eye[4][1], 0.7, 0.48);
//mouth
let up_mouth = positions.top_lip[0];
stroke(0);
noFill();
bezier(positions.top_lip[0][0]-this.mouthDist,positions.bottom_lip[5][1],positions.bottom_lip[4][0],positions.bottom_lip[4][1]+0.1, positions.bottom_lip[2][0],positions.bottom_lip[2][1]+0.1, positions.bottom_lip[0][0]+this.mouthDist,positions.bottom_lip[1][1]);
}
this.setProperties = function(settings) {
this.earDist = map(settings[0], 0, 100, 0.1, 0.3);
this.eyeDist = map(settings[1], 0, 100, -0.07, 0.08);
this.faceColor = int(map(settings[2], 0, 100, 0, 4));
this.earringc = int(map(settings[3], 0, 100, 0, 4));
this.mouthDist = map(settings[4], 0, 100, -0.2, 0);
this.fur = map(settings[5], 0, 100, 0, -0.6);
this.furColor = int(map(settings[6], 0, 100, 0, 4));
this.horns = map(settings[7], 0, 100, -0.5, 0.3);
}
this.getProperties = function() {
let settings = new Array(7);
settings[0] = map(this.earDist, 0.1, 0.3, 0, 100);
settings[1] = map(this.eyeDist, -0.05, 0.06, 0, 100);
settings[2] = map(this.faceColor, 0, 4, 0, 100);
settings[3] = map(this.earringc, 0, 4, 0, 100);
settings[4] = map(this.mouthDist, -0.2, -0.1, 0, 100);
settings[5] = map(this.fur, 0, -0.6, 0, 100);
settings[6] = map(this.furColor, 0, 4, 0, 100);
settings[7] = map(this.horns, -0.5, 0.3,0, 100);
return settings;
}
}
{
"000001": [
100,
40.45454545454545,
25,
100,
0,
0,
75,
50
],
"000002": [
34.99999999999999,
50.000000000000014,
50,
25,
88,
34,
75,
35.99999999999999
],
"000005": [
100,
30.909090909090914,
25,
25,
0,
0,
75,
50
],
"000006": [
100,
30.909090909090914,
25,
50,
49,
19,
25,
28.000000000000004
],
"000007": [
56.999999999999986,
45.909090909090914,
0,
50,
49,
100,
25,
15
],
"000009": [
56.999999999999986,
103.18181818181822,
75,
25,
50,
72,
50,
54
],
"000010": [
25.999999999999996,
41.818181818181834,
100,
50,
36.99999999999999,
21.000000000000004,
75,
95
],
"000013": [
25.999999999999996,
35,
100,
50,
147.99999999999997,
21.000000000000004,
75,
95
],
"000014": [
25.999999999999996,
58.18181818181819,
100,
50,
200,
21.000000000000004,
75,
95
],
"000015": [
25.999999999999996,
60.909090909090914,
25,
50,
0,
21.000000000000004,
75,
95
],
"000016": [
25.999999999999996,
-18.181818181818183,
25,
50,
0,
21.000000000000004,
75,
95
],
"000018": [
25.999999999999996,
40.45454545454545,
100,
50,
0,
26,
25,
95
],
"000020": [
25.999999999999996,
36.36363636363637,
100,
0,
0,
100,
0,
0
],
"000023": [
25.999999999999996,
-18.181818181818183,
25,
0,
102,
17,
0,
73.99999999999999
],
"000025": [
25.999999999999996,
58.18181818181819,
25,
0,
200,
38,
25,
65
],
"000028": [
25.999999999999996,
48.63636363636365,
75,
0,
200,
13,
0,
100
],
"000029": [
0,
48.63636363636365,
100,
0,
200,
13,
0,
100
],
"000030": [
17.000000000000004,
48.63636363636365,
50,
0,
200,
13,
0,
100
],
"000031": [
17.000000000000004,
48.63636363636365,
0,
0,
200,
13,
25,
100
],
"000032": [
17.000000000000004,
43.181818181818194,
25,
0,
200,
13,
25,
100
],
"000035": [
17.000000000000004,
40.45454545454545,
50,
0,
200,
13,
100,
100
],
"000037": [
17.000000000000004,
36.36363636363637,
100,
0,
200,
16,
0,
100
],
"000038": [
17.000000000000004,
47.27272727272728,
75,
0,
200,
16,
25,
100
],
"000040": [
37.99999999999999,
47.27272727272728,
25,
100,
104,
0,
25,
94
],
"000041": [
37.99999999999999,
45.909090909090914,
0,
100,
200,
45.00000000000001,
50,
75.00000000000001
],
"000042": [
37.99999999999999,
44.54545454545456,
25,
100,
200,
45.00000000000001,
50,
75.00000000000001
],
"000043": [
37.99999999999999,
43.181818181818194,
25,
100,
200,
45.00000000000001,
50,
75.00000000000001
],
"000044": [
37.99999999999999,
40.45454545454545,
25,
100,
200,
45.00000000000001,
0,
75.00000000000001
],
"000045": [
37.99999999999999,
36.36363636363637,
25,
100,
200,
45.00000000000001,
75,
75.00000000000001
],
"000047": [
37.99999999999999,
30.909090909090914,
0,
0,
200,
45.00000000000001,
75,
75.00000000000001
],
"000048": [
37.99999999999999,
14.545454545454545,
25,
0,
200,
100,
75,
0
],
"000050": [
37.99999999999999,
70.45454545454547,
75,
100,
200,
19,
25,
0
],
"000051": [
37.99999999999999,
48.63636363636365,
25,
100,
200,
19,
25,
85
],
"000052": [
37.99999999999999,
29.545454545454547,
50,
75,
200,
35,
0,
85
],
"000054": [
37.99999999999999,
43.181818181818194,
25,
50,
128,
33,
75,
85
],
"000055": [
37.99999999999999,
45.909090909090914,
25,
50,
0,
33,
75,
85
],
"000056": [
37.99999999999999,
56.818181818181834,
100,
50,
200,
42.00000000000001,
0,
85
],
"000058": [
37.99999999999999,
39.090909090909086,
100,
50,
200,
42.00000000000001,
0,
85
],
"000060": [
37.99999999999999,
62.27272727272728,
0,
50,
40.00000000000001,
19,
25,
56.00000000000001
],
"000064": [
100,
48.63636363636365,
25,
50,
80.00000000000001,
19,
25,
56.00000000000001
],
"000065": [
100,
48.63636363636365,
25,
50,
160.00000000000003,
19,
25,
56.00000000000001
],
"000068": [
100,
50.000000000000014,
0,
0,
49.999999999999986,
19,
75,
56.00000000000001
],
"000069": [
100,
50.000000000000014,
0,
0,
100,
19,
75,
56.00000000000001
],
"000071": [
100,
40.45454545454545,
100,
0,
200,
30,
25,
100
],
"000073": [
100,
51.36363636363637,
100,
50,
200,
30,
25,
100
],
"000076": [
100,
51.36363636363637,
100,
50,
200,
30,
0,
100
],
"000077": [
100,
28.181818181818187,
75,
50,
200,
30,
25,
100
],
"000078": [
100,
45.909090909090914,
75,
50,
200,
30,
25,
100
],
"000079": [
100,
40.45454545454545,
75,
50,
200,
30,
25,
100
],
"000080": [
100,
85.45454545454547,
75,
50,
200,
30,
25,
100
],
"000081": [
100,
54.0909090909091,
25,
50,
200,
6,
50,
72.99999999999999
],
"000083": [
100,
55.45454545454547,
50,
25,
0,
35,
0,
100
],
"000085": [
100,
56.818181818181834,
50,
25,
0,
35,
0,
100
],
"000086": [
100,
107.2727272727273,
0,
25,
0,
35,
0,
100
],
"000088": [
100,
28.181818181818187,
0,
25,
0,
35,
0,
100
],
"000091": [
100,
20.000000000000004,
0,
75,
200,
69,
100,
100
],
"000092": [
100,
63.63636363636365,
50,
75,
200,
69,
100,
100
],
"000096": [
100,
69.09090909090911,
75,
75,
0,
69,
100,
100
],
"000097": [
100,
36.36363636363637,
75,
75,
0,
69,
100,
100
],
"000099": [
100,
33.63636363636364,
25,
0,
0,
17,
0,
100
],
"000100": [
100,
51.36363636363637,
25,
0,
0,
59,
50,
39.00000000000001
],
"000103": [
100,
60.909090909090914,
50,
50,
76.00000000000001,
49,
75,
87
],
"000104": [
100,
47.27272727272728,
100,
50,
152.00000000000003,
49,
75,
87
],
"000106": [
56.999999999999986,
45.909090909090914,
0,
50,
16.000000000000014,
47,
0,
56.99999999999999
],
"000108": [
56.999999999999986,
44.54545454545456,
0,
50,
32,
47,
75,
56.99999999999999
],
"000109": [
56.999999999999986,
43.181818181818194,
0,
50,
64,
47,
100,
56.99999999999999
],
"000110": [
35.99999999999999,
60.909090909090914,
50,
50,
128,
81,
25,
56.99999999999999
],
"000111": [
35.99999999999999,
-18.181818181818183,
50,
50,
23.999999999999993,
30,
0,
56.99999999999999
],
"000114": [
35.99999999999999,
50.000000000000014,
50,
50,
47.999999999999986,
54,
25,
56.99999999999999
],
"000115": [
35.99999999999999,
44.54545454545456,
25,
50,
96,
33,
50,
56.99999999999999
],
"000116": [
35.99999999999999,
45.909090909090914,
25,
25,
47.999999999999986,
54,
50,
56.99999999999999
],
"000117": [
35.99999999999999,
44.54545454545456,
50,
25,
96,
54,
0,
56.99999999999999
],
"000118": [
35.99999999999999,
95,
50,
25,
192,
54,
0,
56.99999999999999
],
"000121": [
35.99999999999999,
36.36363636363637,
50,
25,
200,
54,
0,
56.99999999999999
],
"000122": [
35.99999999999999,
30.909090909090914,
100,
25,
200,
54,
25,
56.99999999999999
],
"000125": [
35.99999999999999,
55.45454545454547,
75,
25,
200,
54,
75,
56.99999999999999
],
"000126": [
35.99999999999999,
56.818181818181834,
25,
25,
0,
36,
0,
56.99999999999999
],
"000129": [
35.99999999999999,
-18.181818181818183,
25,
50,
113.99999999999999,
56.99999999999999,
0,
56.99999999999999
],
"000131": [
35.99999999999999,
-18.181818181818183,
25,
50,
200,
56.99999999999999,
0,
56.99999999999999
],
"000132": [
35.99999999999999,
-18.181818181818183,
50,
50,
38.00000000000001,
56.99999999999999,
0,
56.99999999999999
],
"000133": [
100,
-18.181818181818183,
0,
50,
139.99999999999997,
34,
0,
56.99999999999999
],
"000134": [
100,
118.18181818181819,
0,
50,
200,
34,
0,
56.99999999999999
],
"000135": [
100,
-18.181818181818183,
100,
50,
46.000000000000014,
34,
75,
56.99999999999999
],
"000137": [
100,
-18.181818181818183,
25,
50,
92,
34,
75,
56.99999999999999
],
"000140": [
100,
66.36363636363637,
50,
50,
145.99999999999997,
34,
50,
56.99999999999999
],
"000142": [
100,
71.81818181818184,
0,
50,
0,
0,
25,
89
],
"000143": [
53.000000000000014,
44.54545454545456,
50,
50,
0,
0,
25,
89
],
"000145": [
53.000000000000014,
43.181818181818194,
75,
75,
94,
48,
75,
89
],
"000146": [
100,
40.45454545454545,
50,
25,
188,
48,
75,
100
],
"000147": [
100,
59.54545454545455,
25,
25,
86,
48,
75,
100
],
"000148": [
100,
63.63636363636365,
100,
25,
100,
64,
100,
100
],
"000150": [
100,
69.09090909090911,
0,
25,
200,
64,
100,
100
],
"000151": [
70,
50.000000000000014,
50,
25,
0,
51,
50,
100
],
"000152": [
70,
50.000000000000014,
50,
25,
0,
51,
50,
100
],
"000153": [
70,
50.000000000000014,
100,
25,
0,
51,
50,
100
],
"000155": [
70,
50.000000000000014,
100,
25,
0,
73,
75,
100
],
"000156": [
24.999999999999996,
37.727272727272734,
0,
25,
0,
49,
100,
100
],
"000157": [
24.999999999999996,
33.63636363636364,
0,
25,
0,
49,
100,
100
],
"000160": [
24.999999999999996,
28.181818181818187,
75,
25,
36.00000000000001,
80,
50,
100
],
"000161": [
24.999999999999996,
48.63636363636365,
25,
25,
72.00000000000001,
80,
75,
100
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 4;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
//skin colour
//brown
const brownS = [74, 52, 33];
//white
const whiteS = [232, 223, 218];
//tan
const tanS = [191, 148, 107];
//hair colour
//red
const redH = [181, 63, 16];
//blonde
const blondeH = [214, 171, 77];
//brown
const brownH = [51, 29, 0];
//black
const blackH = [28, 27, 26];
this.show_points = function(segment) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
var number = i.toString();
textAlign(CENTER, CENTER);
textSize(0.2);
fill(0);
text(number, px, py, 0.1);
}
}
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i = 0; i < s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len, sum_y / s_len];
}
// This where you define your own face object
function IdrisFace() {
// these are state variables for a face
// (your variables should be different!)
//all to max, chnage later
this.green = 3;
this.flower = 1.8;
this.facex = 3;
this.bflower = 1.4;
this.skin = 2;
this.hair = 4;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if (i < segment.length - 1) {
let nx = segment[i + 1][0];
let ny = segment[i + 1][1];
line(px, py, nx, ny);
} else if (do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
// outer fuzz for female hair
//red
if (this.hair == 1) {
if (this.green == 3 || this.green === 2) {
fill(redH);
push();
angleMode(DEGREES);
translate(0, -1.4);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1.8, 1.44);
rotate(20);
}
pop();
}
}
//blonde
if (this.hair == 2) {
if (this.green == 3 || this.green === 2) {
fill(blondeH);
push();
angleMode(DEGREES);
translate(0, -1.4);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1.8, 1.44);
rotate(20);
}
pop();
}
}
//brown
if (this.hair == 3) {
if (this.green == 3 || this.green === 2) {
fill(brownH);
push();
angleMode(DEGREES);
translate(0, -1.4);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1.8, 1.44);
rotate(20);
}
pop();
}
}
//black
if (this.hair == 4) {
if (this.green == 3 || this.green === 2) {
fill(blackH);
push();
angleMode(DEGREES);
translate(0, -1.4);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1.8, 1.44);
rotate(20);
}
pop();
}
}
//female hair
//red
if (this.hair == 1) {
if (this.green == 3 || this.green === 2) {
noStroke();
fill(redH);
ellipse(0, -1.4, 4.68);
fill(50, 168, 82);
push();
angleMode(DEGREES);
translate(-0.72, -2.7);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.8, -2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.72, -3);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
}
}
//blonde
if (this.hair == 2) {
if (this.green == 3 || this.green === 2) {
noStroke();
fill(blondeH);
ellipse(0, -1.4, 4.68);
fill(23, 158, 191);
push();
angleMode(DEGREES);
translate(-0.72, -2.7);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.8, -2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.72, -3);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
}
}
//brown
if (this.hair == 3) {
if (this.green == 3 || this.green === 2) {
noStroke();
fill(brownH);
ellipse(0, -1.4, 4.68);
fill(204, 8, 96);
push();
angleMode(DEGREES);
translate(-0.72, -2.7);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.8, -2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.72, -3);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
}
}
//black
if (this.hair == 4) {
if (this.green == 3 || this.green === 2) {
noStroke();
fill(blackH);
ellipse(0, -1.4, 4.68);
fill(255);
push();
angleMode(DEGREES);
translate(-0.72, -2.7);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.8, -2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.72, -3);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
}
}
// head code
if (this.skin == 1) {
fill(brownS);
noStroke();
ellipse(0, -0.4, this.facex, 3.6);
}
if (this.skin == 2) {
fill(tanS);
noStroke();
ellipse(0, -0.4, this.facex, 3.6);
}
if (this.skin == 3) {
fill(whiteS);
noStroke();
ellipse(0, -0.4, this.facex, 3.6);
}
//beard
//red
if (this.hair == 1) {
fill(redH);
if (this.green < 2) {
ellipse(0, 1.75, 2.5, 2.5);
push();
angleMode(DEGREES);
translate(0, 1.75);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1, 1);
rotate(20);
}
//flowers for beard
pop();
fill(50, 168, 82);
push();
angleMode(DEGREES);
translate(-0.9, 2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.2, 1.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.3, 2.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
}
}
//blonde
if (this.hair == 2) {
fill(blondeH);
if (this.green < 2) {
ellipse(0, 1.75, 2.5, 2.5);
push();
angleMode(DEGREES);
translate(0, 1.75);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1, 1);
rotate(20);
}
//flowers for beard
pop();
fill(23, 158, 191);
push();
angleMode(DEGREES);
translate(-0.9, 2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.2, 1.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.3, 2.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
}
}
//brown
if (this.hair == 3) {
fill(brownH);
if (this.green < 2) {
ellipse(0, 1.75, 2.5, 2.5);
push();
angleMode(DEGREES);
translate(0, 1.75);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1, 1);
rotate(20);
}
//flowers for beard
pop();
fill(204, 8, 96);
push();
angleMode(DEGREES);
translate(-0.9, 2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.2, 1.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.3, 2.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
}
}
//black
if (this.hair == 4) {
fill(blackH);
if (this.green < 2) {
ellipse(0, 1.75, 2.5, 2.5);
push();
angleMode(DEGREES);
translate(0, 1.75);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1, 1);
rotate(20);
}
//flowers for beard
pop();
fill(255);
push();
angleMode(DEGREES);
translate(-0.9, 2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.2, 1.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.3, 2.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
}
}
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
//blush
if (this.green == 3 || this.green === 2) {
fill(196, 118, 118, 60);
noStroke();
ellipse(left_eye_pos[0], left_eye_pos[1] + 1, 0.7, 0.5);
ellipse(right_eye_pos[0], right_eye_pos[1] + 1, 0.7, 0.5);
}
//nose
let nose_top = positions.nose_bridge[0];
let nose_bottom = positions.nose_bridge[2];
let nose_bottom2 = positions.nose_bridge[3];
// print(nose_top, nose_bottom);
stroke(59, 41, 26);
strokeWeight(0.1);
line(nose_top[0], nose_top[1], nose_bottom[0], nose_bottom[1]);
fill(255);
stroke(59, 41, 26);
let nose_end = null;
if (nose_top[0] < nose_bottom[0]) {
nose_end = positions.nose_tip[0];
} else {
nose_end = positions.nose_tip[4];
}
let nose_center = positions.nose_tip[2];
push();
noFill()
strokeWeight(0.1);
angleMode(DEGREES);
arc(nose_bottom2[0], nose_bottom2[1], 0.5, 0.5, 180, 0, OPEN);
pop();
noStroke();
fill(59, 41, 26);
ellipse(nose_bottom2[0] - 0.07, nose_bottom2[1], 0.07, 0.1);
ellipse(nose_bottom2[0] + 0.07, nose_bottom2[1], 0.07, 0.1);
//glasses code
fill(40, 43, 43);
stroke(122, 122, 122);
strokeWeight(0.072);
ellipse(left_eye_pos[0], left_eye_pos[1], 1.2);
ellipse(right_eye_pos[0], right_eye_pos[1], 1.2);
//middlerim
fill(0);
push();
stroke(122, 122, 122);
rectMode(CENTER);
rect(nose_top[0], nose_top[1], 0.72, 0.108);
pop();
//mouth code
let mouthstart = positions.top_lip[0];
let mouthstart2 = positions.top_lip[7];
let mouthbot = positions.bottom_lip[0];
let mouthbot2 = positions.bottom_lip[7];
let mouth = segment_average(positions.top_lip);
let mouth2 = segment_average(positions.bottom_lip);
fill(92, 40, 19);
noStroke();
stroke(64, 27, 27);
strokeWeight(0.07);
push();
//bottom lip
translate(mouth2[0], mouth2[1]);
angleMode(DEGREES)
arc(0, mouth[0], mouthbot[0], 0.5, 0, 180, OPEN);
//top lip
strokeWeight(0.2);
arc(0, mouth[0], mouthbot[0], 0.2, 180, 0, OPEN);
pop();
noStroke();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.facex = map(settings[1], 0, 100, 2.52, 3);
this.green = int(map(settings[0], 0, 100, 1, 3));
this.flower = map(settings[0], 0, 100, 0.36, 1.8);
this.earingsy = map(settings[3], 0, 100, 0.72, 2);
this.bflower = map(settings[0], 0, 100, 0.36, 1.4);
this.skin = int(map(settings[2], 0, 100, 1, 3));
this.hair = int(map(settings[3], 0, 100, 1, 4));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(4);
settings[1] = map(this.facex, 2.52, 3, 0, 100);
settings[0] = map(this.green, 1, 3, 0, 100);
settings[0] = map(this.flower, 0.36, 1.8, 0, 100);
settings[3] = map(this.earingsy, 0.72, 2, 0, 100);
settings[0] = map(this.bflower, 0.36, 1.4, 0, 100);
settings[2] = map(this.skin, 1, 3, 0, 100);
settings[3] = map(this.hair, 1, 4, 0, 100);
return settings;
}
}
{
"000001": [
0,
93,
100,
100
],
"000002": [
100,
46.00000000000002,
100,
0
],
"000005": [
67,
57.000000000000014,
50,
33.33333333333333
],
"000006": [
98.00000000000001,
53.99999999999998,
0,
33.33333333333333
],
"000007": [
0,
100,
100,
100
],
"000009": [
100,
100,
100,
66.66666666666666
],
"000010": [
86,
78.00000000000001,
100,
33.33333333333333
],
"000013": [
0,
100,
100,
33.33333333333333
],
"000014": [
100,
31.00000000000001,
0,
100
],
"000015": [
0,
100,
100,
66.66666666666666
],
"000016": [
0,
100,
50,
66.66666666666666
],
"000018": [
96.00000000000001,
78.00000000000001,
100,
33.33333333333333
],
"000020": [
0,
100,
100,
66.66666666666666
],
"000023": [
0,
100,
100,
100
],
"000025": [
0,
100,
50,
66.66666666666666
],
"000028": [
100,
51.000000000000036,
50,
66.66666666666666
],
"000029": [
92.00000000000001,
67.00000000000003,
50,
33.33333333333333
],
"000030": [
0,
100,
50,
33.33333333333333
],
"000031": [
100,
100,
100,
66.66666666666666
],
"000032": [
0,
100,
100,
33.33333333333333
],
"000035": [
100,
47.999999999999986,
100,
100
],
"000037": [
0,
100,
0,
100
],
"000038": [
0,
100,
100,
100
],
"000040": [
100,
100,
50,
100
],
"000041": [
0,
100,
50,
100
],
"000042": [
94,
66.00000000000004,
100,
33.33333333333333
],
"000043": [
100,
57.000000000000014,
50,
66.66666666666666
],
"000044": [
100,
10.999999999999991,
0,
100
],
"000045": [
100,
35.00000000000003,
50,
0
],
"000047": [
100,
47.00000000000001,
50,
100
],
"000048": [
0,
100,
100,
100
],
"000050": [
0,
74,
100,
100
],
"000051": [
0,
100,
100,
33.33333333333333
],
"000052": [
0,
19.000000000000036,
100,
66.66666666666666
],
"000054": [
100,
88.00000000000003,
100,
33.33333333333333
],
"000055": [
0,
100,
100,
100
],
"000056": [
0,
72.00000000000003,
100,
100
],
"000058": [
100,
81.99999999999996,
100,
100
],
"000060": [
0,
100,
0,
100
],
"000064": [
0,
100,
100,
66.66666666666666
],
"000065": [
0,
100,
50,
100
],
"000068": [
0,
100,
100,
100
],
"000069": [
0,
100,
100,
100
],
"000071": [
82,
63.99999999999999,
100,
33.33333333333333
],
"000073": [
68.00000000000001,
59.999999999999964,
50,
0
],
"000076": [
0,
100,
100,
100
],
"000077": [
100,
100,
100,
66.66666666666666
],
"000078": [
100,
100,
50,
66.66666666666666
],
"000079": [
0,
100,
100,
66.66666666666666
],
"000080": [
0,
100,
100,
100
],
"000081": [
0,
100,
0,
100
],
"000083": [
100,
34.00000000000005,
100,
0
],
"000085": [
100,
100,
100,
0
],
"000086": [
100,
100,
100,
66.66666666666666
],
"000088": [
100,
42.00000000000001,
100,
0
],
"000091": [
0,
100,
100,
100
],
"000092": [
87.99999999999999,
69.99999999999997,
50,
33.33333333333333
],
"000096": [
100,
100,
100,
0
],
"000097": [
70,
84.99999999999999,
50,
0
],
"000099": [
100,
25.00000000000002,
100,
0
],
"000100": [
87.99999999999999,
81.99999999999996,
100,
33.33333333333333
],
"000103": [
100,
54.99999999999996,
100,
66.66666666666666
],
"000104": [
25,
86.99999999999996,
100,
33.33333333333333
],
"000106": [
100,
27.999999999999968,
100,
66.66666666666666
],
"000108": [
87.99999999999999,
78.00000000000001,
100,
33.33333333333333
],
"000109": [
0,
84.99999999999999,
50,
0
],
"000110": [
100,
100,
100,
66.66666666666666
],
"000111": [
94.99999999999999,
32.99999999999997,
0,
33.33333333333333
],
"000114": [
0,
100,
100,
100
],
"000115": [
0,
100,
100,
66.66666666666666
],
"000116": [
0,
100,
100,
66.66666666666666
],
"000117": [
100,
0,
0,
100
],
"000118": [
100,
71.00000000000006,
50,
66.66666666666666
],
"000121": [
100,
100,
50,
100
],
"000122": [
98.00000000000001,
83.00000000000001,
100,
33.33333333333333
],
"000125": [
0,
100,
100,
66.66666666666666
],
"000126": [
84,
71.00000000000006,
50,
33.33333333333333
],
"000129": [
0,
42.00000000000001,
100,
100
],
"000131": [
100,
83.00000000000001,
0,
100
],
"000132": [
100,
100,
0,
100
],
"000133": [
84,
57.000000000000014,
50,
33.33333333333333
],
"000134": [
0,
100,
0,
100
],
"000135": [
0,
100,
0,
100
],
"000137": [
0,
100,
100,
66.66666666666666
],
"000140": [
96.00000000000001,
71.00000000000006,
50,
33.33333333333333
],
"000142": [
100,
41.00000000000002,
100,
66.66666666666666
],
"000143": [
0,
100,
100,
66.66666666666666
],
"000145": [
100,
100,
100,
100
],
"000146": [
100,
100,
50,
0
],
"000147": [
82,
74.99999999999997,
50,
33.33333333333333
],
"000148": [
100,
54.99999999999996,
100,
100
],
"000150": [
0,
100,
100,
0
],
"000151": [
100,
74.99999999999997,
50,
100
],
"000152": [
0,
100,
100,
0
],
"000153": [
0,
100,
100,
66.66666666666666
],
"000155": [
100,
100,
100,
0
],
"000156": [
64,
83.00000000000001,
100,
33.33333333333333
],
"000157": [
82,
85.99999999999997,
100,
33.33333333333333
],
"000160": [
0,
100,
100,
100
],
"000161": [
100,
100,
100,
100
]
}
{
"000001": [
100,
74,
100,
56.00000000000001,
12.5,
61,
100,
31,
30
],
"000002": [
100,
0,
100,
0,
0,
52,
52,
20.000000000000004,
0
],
"000005": [
100,
0,
100,
56.00000000000001,
0,
6,
100,
55.00000000000001,
24
],
"000007": [
0,
100,
0,
100,
0,
95,
0,
75.00000000000001,
27
],
"000009": [
100,
100,
100,
54,
50,
92,
100,
28.000000000000004,
21
],
"000010": [
100,
100,
100,
53,
25,
3,
50,
31,
18
],
"000013": [
0,
100,
0,
56.00000000000001,
0,
6,
0,
61,
14
],
"000014": [
100,
100,
100,
95.99999999999999,
25,
100,
100,
56.00000000000001,
100
],
"000015": [
34,
0,
0,
50,
0,
14,
0,
55.00000000000001,
21
],
"000016": [
0,
61,
0,
56.00000000000001,
0,
89,
0,
61,
24
],
"000018": [
100,
100,
100,
56.00000000000001,
25,
0,
100,
42,
15
],
"000020": [
49,
100,
0,
51,
0,
100,
0,
62,
23
],
"000023": [
28.000000000000004,
48,
0,
49,
0,
91,
0,
61,
15
],
"000025": [
1,
0,
0,
53,
0,
85,
0,
62,
52
],
"000028": [
100,
100,
100,
90,
25,
100,
100,
39.00000000000001,
67
],
"000029": [
100,
100,
100,
53,
25,
8,
100,
28.000000000000004,
18
],
"000030": [
37,
53,
0,
56.00000000000001,
0,
0,
0,
71.99999999999999,
33
],
"000031": [
100,
100,
100,
56.00000000000001,
0,
19,
100,
31,
21
],
"000032": [
22,
54,
0,
51,
0,
10,
0,
43,
21
],
"000035": [
100,
48,
100,
11.999999999999998,
0,
100,
100,
25,
13
],
"000037": [
0,
0,
0,
50,
0,
100,
0,
72.99999999999999,
100
],
"000038": [
27,
0,
0,
51,
0,
88,
0,
79.00000000000001,
22
],
"000006": [
100,
100,
100,
99,
0,
100,
100,
34,
100
],
"000040": [
100,
0,
100,
93,
100,
100,
100,
44,
28
],
"000041": [
54,
100,
0,
51,
12.5,
100,
0,
67,
100
],
"000042": [
100,
100,
100,
53,
25,
11,
100,
27,
18
],
"000043": [
100,
100,
100,
23,
25,
100,
100,
49,
20
],
"000044": [
100,
100,
100,
78,
100,
100,
100,
50,
92
],
"000045": [
100,
100,
100,
90,
0,
91,
100,
24,
35
],
"000047": [
100,
100,
100,
100,
25,
100,
100,
16,
45
],
"000048": [
48,
100,
0,
56.00000000000001,
0,
100,
0,
71.99999999999999,
0
],
"000050": [
30,
100,
0,
51,
0,
100,
0,
89,
39
],
"000051": [
0,
0,
0,
50,
0,
100,
0,
83,
56
],
"000052": [
34,
42,
0,
53,
0,
90,
0,
84,
17
],
"000054": [
100,
100,
100,
56.99999999999999,
25,
7,
100,
28.000000000000004,
33
],
"000055": [
20.999999999999996,
100,
0,
51,
0,
100,
0,
76.00000000000001,
22
],
"000056": [
56.00000000000001,
100,
51,
94,
0,
100,
100,
38.00000000000001,
0
],
"000058": [
100,
100,
100,
56.00000000000001,
25,
100,
100,
7.000000000000001,
7
],
"000060": [
0,
0,
0,
50,
0,
100,
0,
0,
100
],
"000064": [
14.000000000000002,
57,
0,
50,
0,
100,
0,
80.00000000000001,
17
],
"000065": [
30,
0,
0,
100,
0,
100,
0,
91,
56
],
"000068": [
45,
100,
2,
0,
87.5,
100,
0,
0,
34
],
"000069": [
27,
100,
0,
53,
0,
100,
0,
67,
16
],
"000071": [
100,
100,
100,
56.00000000000001,
50,
4,
100,
33,
24
],
"000073": [
100,
100,
100,
100,
25,
91,
100,
41,
18
],
"000076": [
75.99999999999999,
10,
0,
50,
12.5,
100,
0,
100,
100
],
"000077": [
100,
100,
100,
56.00000000000001,
25,
100,
100,
33,
48
],
"000078": [
100,
100,
100,
38,
0,
100,
100,
83,
37
],
"000079": [
1,
0,
0,
53,
0,
97,
0,
53,
42
],
"000160": [
30,
100,
0,
51,
0,
100,
0,
77.00000000000001,
32
],
"000157": [
100,
47,
100,
55.00000000000001,
0,
17,
75,
43,
35
],
"000156": [
52,
100,
100,
56.00000000000001,
0,
11,
100,
31,
35
],
"000153": [
0,
52,
0,
52,
0,
100,
0,
54,
34
],
"000152": [
0,
57,
0,
51,
37.5,
76,
0,
45,
34
],
"000151": [
100,
51,
100,
94,
0,
100,
35,
47,
78
],
"000150": [
30,
0,
0,
52,
62.5,
100,
0,
61,
12
],
"000148": [
96,
0,
100,
45,
25,
99,
100,
28.000000000000004,
28
],
"000147": [
100,
35,
100,
62,
0,
13,
91,
31,
46
],
"000146": [
100,
100,
100,
0,
0,
94,
100,
40.00000000000001,
74
],
"000145": [
100,
100,
100,
38,
0,
100,
100,
32,
75
],
"000143": [
14.000000000000002,
0,
0,
52,
0,
42,
0,
65,
24
],
"000142": [
100,
100,
100,
73,
0,
100,
100,
44,
24
],
"000140": [
100,
45,
100,
51,
0,
12,
100,
34,
51
],
"000137": [
0,
0,
0,
52,
100,
94,
0,
65,
23
],
"000135": [
28.000000000000004,
63,
0,
0,
0,
100,
0,
100,
85
],
"000134": [
0,
0,
0,
0,
0,
100,
0,
76.00000000000001,
100
],
"000133": [
100,
0,
100,
47.99999999999999,
25,
17,
100,
40.00000000000001,
48
],
"000132": [
100,
51,
100,
0,
0,
100,
100,
55.00000000000001,
100
],
"000131": [
100,
100,
100,
0,
12.5,
100,
100,
38.00000000000001,
70
],
"000129": [
37,
0,
0,
51,
0,
100,
0,
67,
27
],
"000126": [
100,
100,
100,
50,
12.5,
0,
100,
50,
39
],
"000125": [
0,
0,
0,
52,
0,
100,
0,
71.99999999999999,
57
],
"000122": [
100,
100,
100,
69,
25,
0,
100,
34,
0
],
"000121": [
100,
100,
100,
8,
0,
100,
100,
36.99999999999999,
100
],
"000080": [
1,
100,
0,
51,
0,
100,
0,
69.99999999999999,
39
],
"000081": [
14.000000000000002,
100,
0,
0,
0,
100,
0,
71.99999999999999,
69
],
"000083": [
100,
100,
100,
54,
12.5,
50,
100,
28.999999999999996,
23
],
"000085": [
100,
100,
100,
37,
25,
89,
100,
31,
33
],
"000086": [
100,
0,
100,
42,
0,
81,
79,
50,
24
],
"000088": [
100,
100,
100,
95.99999999999999,
12.5,
53,
93,
26,
13
],
"000091": [
13,
100,
0,
56.99999999999999,
0,
100,
0,
68.99999999999999,
26
],
"000092": [
100,
100,
100,
56.00000000000001,
0,
8,
97,
31,
38
],
"000096": [
100,
100,
100,
0,
0,
100,
100,
39.00000000000001,
31
],
"000097": [
100,
0,
100,
70,
0,
44,
88,
36.99999999999999,
42
],
"000099": [
100,
45,
100,
31,
12.5,
91,
100,
36.99999999999999,
36
],
"000100": [
43,
0,
100,
100,
0,
17,
100,
35.99999999999999,
27
],
"000103": [
100,
48,
100,
44,
25,
100,
100,
31,
33
],
"000104": [
0,
0,
0,
64,
0,
14,
0,
55.00000000000001,
22
],
"000106": [
100,
48,
100,
34,
12.5,
50,
100,
35.99999999999999,
28
],
"000108": [
100,
100,
100,
54,
0,
7,
100,
31,
42
],
"000109": [
28.999999999999996,
46,
0,
51,
0,
21,
0,
61,
24
],
"000110": [
100,
100,
100,
56.00000000000001,
0,
50,
94,
42,
26
],
"000111": [
100,
100,
100,
63,
0,
100,
100,
39.00000000000001,
84
],
"000114": [
51,
100,
0,
95,
0,
100,
0,
65,
71
],
"000115": [
0,
0,
0,
51,
0,
16,
0,
39.00000000000001,
24
],
"000116": [
20.999999999999996,
100,
0,
64,
0,
92,
0,
70.99999999999999,
28
],
"000117": [
100,
100,
100,
0,
25,
100,
100,
39.00000000000001,
64
],
"000118": [
100,
100,
100,
90,
0,
100,
97,
40.00000000000001,
100
],
"000155": [
100,
0,
99,
0,
0,
100,
99,
43,
27
],
"000161": [
100,
40,
100,
54,
0,
100,
100,
45,
0
]
}
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
function JordanFace() {
const bg_color = [0, 0, 0];
const fg_color = [255, 255, 255];
const stroke_color = [95, 52, 8];
this.eyepaint_value = 2;
this.mouth_value = 1;
this.tilt_value = 0;
this.colour2_value = 0;
this.draw = function(positions) {
rotate(this.tilt_value);
var eye1_pos = positions.left_eye;
var eye2_pos = positions.right_eye;
var toplip_pos = positions.top_lip;
var bottomlip_pos = positions.bottom_lip;
// Here I set my colour variables for the face and eye paint colour
if (this.colour_value === 1) {
var colour1 = color(240,10,10,120);
}
if (this.colour_value === 2) {
var colour1 = color(0,0,255,150);
}
if (this.colour_value === 3) {
var colour1 = color(255,255,255,120);
}
if (this.colour2_value === 1) {
var colour2 = color(240,10,10,80);
}
if (this.colour2_value === 2) {
var colour2 = color(0,0,255,80);
}
if (this.colour2_value === 3) {
var colour2 = color(255,255,255,80);
}
if (this.colour2_value === 4) {
var colour2 = color(255,255,255,0);
}
//face
// Here I use the points around the jaw and eyebrows to make a face shape that is filled
// to provide a base for the face paint
fill(colour2);
noStroke();
beginShape();
for(var i=0; i<positions.chin.length;i++) {
vertex(positions.chin[i][0], positions.chin[i][1]);
}
for(var i=positions.right_eyebrow.length-1; i>=0;i--) {
vertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
for(var i=positions.left_eyebrow.length-1; i>=0;i--) {
vertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
endShape(CLOSE);
// eyes
if (this.eyepaint_value === 1) {
;
// This is my first variant of the eye make up that makes a curved triangle going down from the eye.
fill(colour1);
beginShape();
vertex(eye1_pos[4][0]+.2 , eye1_pos[3][1]+.21);
quadraticVertex(-1.5, -.2, eye1_pos[1][0] -.4 , 1.2);
quadraticVertex(-1.5, -.2, eye1_pos[0][0] , eye1_pos[3][1]+.25);
endShape();
beginShape();
vertex(eye2_pos[4][0]-.2 , eye2_pos[3][1]+.21);
quadraticVertex(1.5, -.2, eye2_pos[1][0] +.4 , 1.2);
quadraticVertex(1.5, -.2, eye2_pos[3][0], eye2_pos[0][1]+.25);
endShape();
noStroke();
}
if (this.eyepaint_value === 2) {
;
// For my second eye make-up variant I've made a diamond shape mapped to the eye corners.
fill(colour1);
triangle(eye1_pos[3][0] +.2,eye1_pos[3][1],eye1_pos[0][0]-.25,eye1_pos[0][1],eye1_pos[2][0],-2.5);
triangle(eye1_pos[3][0]+.2,eye1_pos[3][1],eye1_pos[0][0]-.25,eye1_pos[0][1],eye1_pos[1][0],.5);
triangle(eye2_pos[3][0]+.25,eye2_pos[3][1],eye2_pos[0][0]-.2,eye2_pos[0][1],eye2_pos[1][0],-2.5);
triangle(eye2_pos[3][0]+.25,eye2_pos[3][1],eye2_pos[0][0]-.2,eye2_pos[0][1],eye2_pos[2][0],.5);
}
if (this.eyepaint_value === 3) {
;
// I've made a variant of the eye make up that is a stripe across the face
// I didn't end up using this variant as it does not work well visually
// However I've kept the code in place to show my process and so that it can be seen when changing the settings
fill(colour1);
rect(eye1_pos[0][0] -.25 ,eye1_pos[2][1] -.2,3,.6,.2);
}
// I've seperated the dark makeup around the eye from the other parts so I can turn it on and off independently.
// However I've left it on for all variants as it works best visually.
if (this.eyeshadow_value === 1) {
fill(0,0,0,120)
bezier(eye1_pos[3][0]+.2 , eye1_pos[3][1], -1.6 , -1.9 , -1.8 , -.3, eye1_pos[3][0]+.2 , eye1_pos[3][1] );
bezier(eye2_pos[0][0] -.2, eye2_pos[0][1], 1.6 , -1.9 , 1.8 , -.3, eye2_pos[0][0]-.2 , eye2_pos[0][1]);
fill(255,0,0);
fill(fg_color);
}
// mouth
if (this.mouth_value === 1) {
// My first mouth variant is a quad below the lip
fill(0,0,0,120);
quad(bottomlip_pos[2][0],bottomlip_pos[2][1],bottomlip_pos[4][0],bottomlip_pos[4][1],
bottomlip_pos[4][0] +.1,bottomlip_pos[4][1]+.6,bottomlip_pos[2][0] -.1,bottomlip_pos[2][1]+.6,2);
}
if (this.mouth_value === 2) {
// The second mouth variant is a kind of exaggerated lipstick that makes the mouth appear much larger.
fill(0,0,0,120);
bezier(toplip_pos[0][0]-.2, toplip_pos[0][1],0,toplip_pos[4][1]-.2,0,toplip_pos[4][1]-.2,toplip_pos[6][0]+.2,toplip_pos[6][1]);
bezier(toplip_pos[0][0]-.2, toplip_pos[0][1],-.4,bottomlip_pos[3][1]+.3,.4,bottomlip_pos[3][1]+.3,toplip_pos[6][0]+.2,toplip_pos[6][1]);
}
}
this.setProperties = function(settings) {
this.eyepaint_value = int(map(settings[0], 0, 100, 1, 3));
this.mouth_value = int(map(settings[1], 0, 100, 1, 2));
this.colour_value = int(map(settings[3], 0, 100 ,1, 3));
this.eyeshadow_value = int(map(settings[4], 0, 100 ,1, 2));
this.colour2_value = int(map(settings[5], 0, 100 ,1, 3));
}
this.getProperties = function() {
let settings = new Array(5);
settings[0] = map(this.eyepaint_value, 1, 3, 0, 100);
settings[1] = map(this.mouth_value, 1, 2, 0, 100);
settings[3] = map(this.colour_value, 1, 3, 0, 100);
settings[4] = map(this.eyeshadow_value, 1, 2, 0, 100);
settings[5] = map(this.colour2_value, 1, 3, 0, 100);
console.log(settings[5]);
return settings;
}
}
{
"000001": [
0,
75,
0,
0,
0,
100
],
"000002": [
50,
50,
null,
0,
0,
100
],
"000005": [
0,
0,
null,
0,
0,
100
],
"000006": [
50,
50,
null,
50,
0,
0
],
"000007": [
0,
100,
null,
0,
0,
100
],
"000009": [
50,
50,
null,
0,
0,
100
],
"000010": [
50,
50,
null,
0,
0,
100
],
"000013": [
0,
100,
null,
0,
0,
100
],
"000014": [
0,
0,
null,
50,
0,
0
],
"000015": [
0,
100,
null,
0,
0,
100
],
"000016": [
0,
100,
null,
0,
0,
100
],
"000018": [
50,
50,
null,
0,
0,
100
],
"000020": [
50,
100,
null,
0,
0,
100
],
"000023": [
0,
100,
null,
0,
0,
100
],
"000025": [
0,
100,
null,
0,
0,
100
],
"000028": [
50,
0,
null,
0,
0,
100
],
"000029": [
50,
50,
null,
0,
0,
100
],
"000030": [
0,
100,
null,
0,
0,
100
],
"000031": [
0,
0,
null,
0,
0,
100
],
"000032": [
0,
100,
null,
0,
0,
100
],
"000035": [
50,
50,
null,
0,
0,
100
],
"000037": [
0,
100,
null,
50,
0,
0
],
"000038": [
0,
100,
null,
0,
0,
100
],
"000040": [
0,
0,
null,
0,
0,
100
],
"000041": [
50,
100,
null,
100,
0,
50
],
"000042": [
50,
50,
null,
0,
0,
100
],
"000043": [
50,
50,
null,
0,
0,
100
],
"000044": [
50,
50,
null,
50,
0,
0
],
"000045": [
50,
0,
null,
0,
0,
100
],
"000047": [
50,
50,
null,
50,
0,
0
],
"000048": [
0,
100,
null,
0,
0,
100
],
"000050": [
0,
100,
null,
0,
0,
100
],
"000051": [
0,
100,
null,
0,
0,
100
],
"000052": [
0,
100,
null,
100,
0,
50
],
"000054": [
50,
50,
null,
0,
0,
100
],
"000055": [
0,
100,
null,
0,
0,
100
],
"000056": [
50,
0,
null,
0,
0,
100
],
"000058": [
50,
50,
null,
0,
0,
100
],
"000060": [
0,
100,
null,
50,
0,
0
],
"000064": [
0,
100,
null,
0,
0,
100
],
"000065": [
0,
100,
null,
100,
0,
50
],
"000068": [
0,
100,
null,
100,
0,
50
],
"000069": [
0,
100,
null,
0,
0,
100
],
"000071": [
50,
50,
null,
0,
0,
100
],
"000073": [
50,
50,
null,
0,
0,
100
],
"000076": [
0,
100,
null,
0,
0,
100
],
"000077": [
50,
50,
null,
0,
0,
100
],
"000078": [
50,
50,
null,
0,
0,
100
],
"000079": [
0,
100,
null,
0,
0,
100
],
"000080": [
0,
100,
null,
0,
0,
100
],
"000081": [
0,
100,
null,
0,
0,
100
],
"000083": [
50,
50,
null,
0,
0,
100
],
"000085": [
50,
50,
null,
0,
0,
100
],
"000086": [
0,
0,
null,
0,
0,
100
],
"000088": [
50,
50,
null,
0,
0,
100
],
"000091": [
0,
100,
null,
0,
0,
100
],
"000092": [
50,
50,
null,
0,
0,
100
],
"000096": [
50,
50,
null,
100,
0,
50
],
"000097": [
50,
50,
null,
0,
0,
100
],
"000099": [
50,
50,
null,
0,
0,
100
],
"000100": [
0,
0,
null,
0,
0,
100
],
"000103": [
50,
0,
null,
0,
0,
100
],
"000104": [
0,
100,
null,
0,
0,
100
],
"000106": [
50,
0,
null,
0,
0,
100
],
"000108": [
50,
50,
null,
0,
0,
100
],
"000109": [
0,
100,
null,
100,
0,
50
],
"000110": [
50,
50,
null,
0,
0,
100
],
"000111": [
0,
0,
null,
50,
0,
0
],
"000114": [
0,
100,
null,
0,
0,
100
],
"000115": [
0,
100,
null,
0,
0,
100
],
"000116": [
0,
100,
null,
0,
0,
100
],
"000117": [
50,
50,
null,
50,
0,
0
],
"000118": [
0,
0,
null,
50,
0,
0
],
"000121": [
50,
0,
null,
0,
0,
100
],
"000122": [
0,
0,
null,
0,
0,
100
],
"000125": [
0,
100,
null,
100,
0,
50
],
"000126": [
50,
50,
null,
100,
0,
50
],
"000129": [
0,
100,
null,
0,
0,
100
],
"000131": [
50,
50,
null,
100,
0,
50
],
"000132": [
50,
50,
null,
50,
0,
0
],
"000133": [
50,
0,
null,
0,
0,
100
],
"000134": [
0,
100,
null,
50,
0,
0
],
"000135": [
0,
100,
null,
50,
0,
0
],
"000137": [
0,
100,
null,
0,
0,
100
],
"000140": [
50,
0,
null,
0,
0,
100
],
"000142": [
50,
50,
null,
0,
0,
100
],
"000143": [
0,
100,
null,
0,
0,
100
],
"000145": [
50,
50,
null,
0,
0,
100
],
"000146": [
50,
50,
null,
100,
0,
50
],
"000147": [
50,
0,
null,
0,
0,
100
],
"000148": [
0,
0,
null,
0,
0,
100
],
"000150": [
0,
100,
null,
0,
0,
100
],
"000151": [
50,
50,
null,
50,
0,
0
],
"000152": [
0,
100,
null,
0,
0,
100
],
"000153": [
0,
100,
null,
0,
0,
100
],
"000155": [
50,
50,
null,
0,
0,
100
],
"000156": [
0,
0,
null,
0,
0,
100
],
"000157": [
50,
50,
null,
0,
0,
100
],
"000160": [
0,
100,
null,
0,
0,
100
],
"000161": [
50,
50,
null,
0,
0,
100
]
}
{
"000001": [
0,
17,
56.99999999999999,
98,
0,
null,
null
],
"000002": [
0,
0,
51,
100,
0,
null,
null
],
"000005": [
0,
11,
11,
0,
100,
null,
null
],
"000006": [
0,
100,
80,
100,
62,
null,
null
],
"000007": [
100,
11,
100,
100,
100,
null,
null
],
"000009": [
0,
0,
87,
53,
1,
null,
null
],
"000010": [
0,
0,
0,
0,
69,
null,
null
],
"000013": [
100,
13,
0,
1,
0,
null,
null
],
"000014": [
0,
100,
100,
100,
50,
null,
null
],
"000015": [
100,
0,
100,
22,
90,
null,
null
],
"000016": [
100,
25,
100,
100,
31,
null,
null
],
"000018": [
0,
0,
0,
10,
0,
null,
null
],
"000020": [
100,
17,
100,
39,
89,
null,
null
],
"000023": [
100,
0,
100,
0,
18,
null,
null
],
"000025": [
100,
16,
89,
100,
89,
null,
null
],
"000028": [
0,
39,
62,
100,
1,
null,
null
],
"000029": [
0,
0,
0,
0,
0,
null,
null
],
"000030": [
100,
41,
42,
100,
100,
null,
null
],
"000031": [
0,
0,
70,
0,
0,
null,
null
],
"000032": [
100,
8,
43,
100,
100,
null,
null
],
"000035": [
0,
0,
100,
52,
81,
null,
null
],
"000037": [
100,
100,
100,
100,
100,
null,
null
],
"000038": [
100,
21,
100,
0,
0,
null,
null
],
"000040": [
0,
0,
100,
52,
30,
null,
null
],
"000041": [
100,
32,
100,
100,
0,
null,
null
],
"000042": [
0,
1,
64,
0,
21,
null,
null
],
"000043": [
0,
6,
93,
48,
0,
null,
null
],
"000044": [
0,
100,
100,
100,
51,
null,
null
],
"000045": [
0,
8,
55.00000000000001,
100,
0,
null,
null
],
"000047": [
0,
100,
100,
100,
0,
null,
null
],
"000048": [
100,
0,
100,
22,
100,
null,
null
],
"000050": [
100,
14.000000000000002,
100,
88,
0,
null,
null
],
"000051": [
100,
34,
50,
100,
28.999999999999996,
null,
null
],
"000052": [
100,
39,
91,
0,
39,
null,
null
],
"000054": [
0,
0,
0,
13,
0,
null,
null
],
"000055": [
100,
10,
100,
100,
100,
null,
null
],
"000056": [
100,
0,
100,
26,
52,
null,
null
],
"000058": [
0,
0,
100,
0,
100,
null,
null
],
"000060": [
100,
99,
69,
100,
0,
null,
null
],
"000064": [
100,
0,
100,
0,
51,
null,
null
],
"000065": [
100,
55.00000000000001,
100,
100,
0,
null,
null
],
"000068": [
100,
35,
91,
78,
0,
null,
null
],
"000069": [
100,
9,
100,
87,
100,
null,
null
],
"000071": [
0,
3,
0,
0,
15,
null,
null
],
"000073": [
0,
14.000000000000002,
100,
70,
41,
null,
null
],
"000076": [
100,
10,
100,
100,
78,
null,
null
],
"000077": [
0,
0,
100,
49,
28.000000000000004,
null,
null
],
"000078": [
0,
0,
98,
17,
24,
null,
null
],
"000079": [
100,
22,
56.00000000000001,
100,
31,
null,
null
],
"000080": [
100,
0,
100,
0,
32,
null,
null
],
"000081": [
100,
52,
100,
100,
0,
null,
null
],
"000083": [
0,
1,
66,
16,
31,
null,
null
],
"000085": [
0,
0,
60,
12,
25,
null,
null
],
"000086": [
0,
0,
68,
57.99999999999999,
100,
null,
null
],
"000088": [
0,
0,
49,
100,
100,
null,
null
],
"000091": [
100,
0,
100,
32,
100,
null,
null
],
"000092": [
0,
7.000000000000001,
0,
0,
18,
null,
null
],
"000096": [
0,
18,
100,
100,
100,
null,
null
],
"000097": [
0,
1,
35,
0,
75,
null,
null
],
"000099": [
0,
21,
30,
9,
0,
null,
null
],
"000100": [
0,
1,
26,
100,
51,
null,
null
],
"000103": [
0,
0,
92,
4,
100,
null,
null
],
"000104": [
100,
0,
31,
0,
0,
null,
null
],
"000106": [
0,
39,
77,
100,
0,
null,
null
],
"000108": [
0,
0,
1,
0,
0,
null,
null
],
"000109": [
100,
25,
65,
0,
21,
null,
null
],
"000110": [
0,
0,
62,
0,
0,
null,
null
],
"000111": [
0,
100,
32,
95,
0,
null,
null
],
"000114": [
100,
0,
100,
100,
0,
null,
null
],
"000115": [
100,
0,
41,
2,
50,
null,
null
],
"000116": [
100,
0,
91,
99,
0,
null,
null
],
"000117": [
0,
100,
100,
97,
24,
null,
null
],
"000118": [
0,
85,
100,
85,
28.999999999999996,
null,
null
],
"000121": [
0,
50,
100,
87,
21,
null,
null
],
"000122": [
0,
0,
0,
85,
0,
null,
null
],
"000125": [
100,
36,
52,
1,
73,
null,
null
],
"000126": [
0,
53,
0,
0,
0,
null,
null
],
"000129": [
100,
0,
100,
0,
0,
null,
null
],
"000131": [
0,
86,
100,
100,
0,
null,
null
],
"000132": [
0,
99,
100,
100,
0,
null,
null
],
"000133": [
0,
9,
35,
0,
0,
null,
null
],
"000134": [
100,
100,
100,
100,
0,
null,
null
],
"000135": [
100,
89,
100,
100,
28.999999999999996,
null,
null
],
"000137": [
100,
4,
0,
18,
0,
null,
null
],
"000140": [
0,
50,
1,
0,
100,
null,
null
],
"000142": [
0,
0,
100,
0,
100,
null,
null
],
"000143": [
100,
0,
82,
0,
0,
null,
null
],
"000145": [
0,
5,
100,
87,
0,
null,
null
],
"000146": [
0,
39,
83,
100,
0,
null,
null
],
"000147": [
0,
40,
21,
49,
80,
null,
null
],
"000148": [
0,
0,
100,
2,
89,
null,
null
],
"000150": [
100,
1,
52,
11,
51,
null,
null
],
"000151": [
0,
77,
100,
100,
0,
null,
null
],
"000152": [
100,
11,
49,
9,
0,
null,
null
],
"000153": [
100,
13,
100,
55.00000000000001,
0,
null,
null
],
"000155": [
0,
30,
49,
88,
0,
null,
null
],
"000156": [
0,
0,
0,
0,
0,
null,
null
],
"000157": [
0,
0,
0,
0,
79,
null,
null
],
"000160": [
100,
0,
100,
100,
80,
null,
null
],
"000161": [
0,
0,
100,
0,
0,
null,
null
]
}
{
"000001": [
61,
30,
63,
5.999999999999999,
76,
73,
100,
0
],
"000002": [
0,
30,
32,
14.000000000000002,
69,
100,
100,
0
],
"000005": [
2,
98,
37,
50,
63,
19,
100,
0
],
"000006": [
47,
28.000000000000004,
92,
13,
63,
97,
100,
0
],
"000007": [
92,
89.00000000000003,
43,
7.000000000000001,
0,
0,
0,
0
],
"000009": [
77,
65,
39,
16,
63,
100,
100,
0
],
"000010": [
27,
26,
82,
54,
52,
32,
100,
0
],
"000013": [
0,
82.00000000000001,
48,
51,
0,
100,
0,
0
],
"000014": [
75,
32,
31,
0,
69,
100,
100,
0
],
"000015": [
61,
91.00000000000003,
41,
57.99999999999999,
0,
21,
0,
0
],
"000016": [
39,
77.00000000000001,
41,
11.999999999999998,
0,
0,
0,
0
],
"000018": [
33,
26,
36,
18,
49,
100,
100,
35
],
"000020": [
70,
97,
84,
50,
0,
21,
0,
33
],
"000023": [
74,
94,
45,
53,
0,
16,
0,
0
],
"000025": [
78,
100,
69,
5.999999999999999,
0,
17,
0,
0
],
"000028": [
0,
20.999999999999996,
32,
9,
62,
73,
100,
0
],
"000029": [
25,
35.99999999999999,
66,
50,
52,
100,
100,
0
],
"000030": [
36,
100,
50,
28.000000000000004,
0,
0,
0,
32
],
"000031": [
12,
31,
41,
51,
44,
100,
100,
0
],
"000032": [
61,
100,
93,
74,
2,
28.000000000000004,
0,
0
],
"000035": [
100,
17.999999999999993,
42,
15,
62,
18,
100,
0
],
"000037": [
100,
100,
28.000000000000004,
100,
0,
0,
0,
0
],
"000038": [
83,
100,
41,
53,
0,
100,
0,
8
],
"000040": [
100,
17.999999999999993,
71,
9,
70,
0,
100,
0
],
"000041": [
100,
100,
37,
50,
0,
100,
0,
0
],
"000042": [
69,
27,
76,
54,
68,
13,
100,
0
],
"000043": [
68,
28.999999999999996,
80,
14.000000000000002,
60,
100,
100,
0
],
"000044": [
89,
20.999999999999996,
86,
0,
88,
14.000000000000002,
100,
2
],
"000045": [
49,
23,
96,
9,
53,
100,
100,
0
],
"000047": [
100,
15,
91,
0,
53,
100,
100,
0
],
"000048": [
97,
83.00000000000001,
78,
0,
0,
0,
0,
0
],
"000050": [
91,
80.00000000000001,
81,
0,
0,
100,
0,
0
],
"000051": [
89,
78.00000000000001,
86,
23,
0,
0,
0,
30
],
"000052": [
68,
100,
46,
47,
0,
0,
0,
0
],
"000054": [
50,
28.000000000000004,
44,
64,
49,
100,
100,
0
],
"000055": [
88,
86.00000000000001,
67,
11,
0,
0,
0,
0
],
"000056": [
86,
20.000000000000004,
38,
51,
28.999999999999996,
15,
71,
0
],
"000058": [
100,
0,
84,
52,
87,
0,
100,
0
],
"000060": [
71,
81.00000000000001,
28.000000000000004,
15,
0,
86,
0,
0
],
"000064": [
71,
91.00000000000003,
45,
50,
0,
23,
0,
0
],
"000065": [
92,
50.000000000000014,
100,
11.999999999999998,
0,
100,
0,
2
],
"000068": [
89,
80.00000000000001,
86,
13,
0,
100,
42.00000000000001,
26
],
"000069": [
72,
98,
86,
14.000000000000002,
0,
31,
18,
0
],
"000071": [
0,
28.999999999999996,
100,
13,
62,
100,
100,
0
],
"000073": [
38,
24,
86,
17,
50,
100,
100,
0
],
"000076": [
81,
100,
87,
0,
0,
16,
0,
0
],
"000077": [
100,
20.000000000000004,
36,
0,
39,
10,
100,
0
],
"000078": [
94,
24,
32,
13,
69,
30,
100,
0
],
"000079": [
68,
87.00000000000003,
46,
11,
0,
19,
0,
37
],
"000080": [
74,
74.00000000000001,
93,
50,
0,
11,
0,
0
],
"000081": [
100,
80.00000000000001,
41,
7.000000000000001,
0,
100,
0,
0
],
"000083": [
34,
13.000000000000004,
42,
11,
89,
33,
100,
0
],
"000085": [
38,
26,
50,
14.000000000000002,
65,
0,
100,
0
],
"000086": [
33,
6.999999999999999,
95,
50,
72,
100,
100,
0
],
"000088": [
50,
13.000000000000004,
50,
14.000000000000002,
50,
100,
100,
0
],
"000091": [
91,
100,
52,
18,
0,
0,
0,
0
],
"000092": [
18,
43,
30,
15,
71,
100,
100,
0
],
"000096": [
100,
30,
83,
15,
67,
14.000000000000002,
100,
0
],
"000097": [
22,
33,
78,
51,
55.00000000000001,
100,
100,
0
],
"000099": [
50,
12.000000000000004,
50,
50,
46,
68,
100,
0
],
"000100": [
28.999999999999996,
34.99999999999999,
45,
14.000000000000002,
74,
32,
100,
0
],
"000103": [
72,
23,
77,
36,
81,
16,
100,
0
],
"000104": [
50,
59.999999999999986,
35,
50,
0,
100,
0,
0
],
"000106": [
100,
21.999999999999996,
46,
9,
57.99999999999999,
100,
100,
0
],
"000108": [
50,
23,
50,
47.99999999999999,
71,
100,
100,
0
],
"000109": [
41,
69,
36,
50,
0,
100,
0,
0
],
"000110": [
27,
34.99999999999999,
30,
50,
43,
100,
100,
0
],
"000111": [
2,
30,
100,
17,
50,
100,
100,
0
],
"000114": [
44,
100,
39,
17,
0,
87,
0,
0
],
"000115": [
0,
83.00000000000001,
40,
50,
0,
13,
0,
0
],
"000116": [
84,
75.00000000000001,
17,
5.999999999999999,
0,
100,
0,
0
],
"000117": [
100,
4,
11,
0,
72,
100,
100,
0
],
"000118": [
56.99999999999999,
24,
13,
10,
63,
9,
100,
0
],
"000121": [
84,
20.000000000000004,
78,
7.000000000000001,
61,
0,
100,
0
],
"000122": [
50,
20.000000000000004,
50,
11,
67,
100,
100,
32
],
"000125": [
93,
83.00000000000001,
43,
50,
0,
17,
0,
48
],
"000126": [
32,
17.999999999999993,
46,
25,
63,
100,
100,
0
],
"000129": [
100,
87.00000000000003,
28.000000000000004,
18,
18,
100,
46.99999999999999,
0
],
"000131": [
96,
20.999999999999996,
65,
0,
60,
100,
100,
0
],
"000132": [
100,
16,
85,
8,
56.99999999999999,
100,
100,
0
],
"000133": [
17,
30,
36,
49,
54,
100,
100,
0
],
"000134": [
67,
92.00000000000003,
45,
0,
0,
100,
0,
0
],
"000135": [
100,
100,
28.000000000000004,
0,
0,
18,
50,
0
],
"000161": [
78,
17.999999999999993,
41,
23.999999999999996,
59,
100,
100,
0
],
"000160": [
90,
86.00000000000001,
43,
14.000000000000002,
0,
22,
0,
0
],
"000157": [
25,
32,
31,
49,
50,
20,
100,
0
],
"000156": [
5,
27,
50,
50,
50,
50,
50,
0
],
"000155": [
12,
19.000000000000004,
39,
4,
64,
100,
100,
0
],
"000137": [
46,
100,
35,
53,
0,
100,
0,
0
],
"000140": [
14.000000000000002,
40,
50,
47.99999999999999,
51,
0,
100,
0
],
"000143": [
69,
85.00000000000001,
50,
50,
0,
100,
0,
0
],
"000145": [
82,
26,
50,
5.999999999999999,
49,
100,
100,
0
],
"000146": [
12,
58.999999999999986,
42,
8,
70,
93,
100,
0
],
"000147": [
27,
28.999999999999996,
50,
50,
50,
100,
50,
0
],
"000148": [
90,
19.000000000000004,
50,
50,
46,
100,
100,
0
],
"000150": [
0,
100,
55.00000000000001,
36,
0,
35,
69,
0
],
"000151": [
81,
25,
46,
0,
61,
100,
100,
0
],
"000152": [
56.00000000000001,
77.00000000000001,
50,
18,
0,
100,
18,
0
],
"000153": [
70,
78.00000000000001,
46,
11.999999999999998,
0,
100,
0,
0
],
"000142": [
50,
50.000000000000014,
50,
50,
50,
13,
50,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// other variables can be in here too
// these control the colors used
const kelly_bg_color = [225, 206, 187];
const kelly_fg_color = [151, 102, 52];
const kelly_stroke_color = [95, 52, 8];
function KellyFace() {
this.hairColor = 50;
this.wrinkleWeight = 50;
this.skinColor = 50;
this.spots = 50;
this.draw = function(positions) {
var base_tone1 = color("#ffcfaf"); //light color
var base_tone2 = color("#a56e48"); //dark color
var blush_base = color("#701702");
var nose_pos = average_point(positions.nose_bridge);
var eye1_pos = average_point(positions.left_eye);
var eye2_pos = average_point(positions.right_eye);
var half_height = positions.chin[7][1] - nose_pos[1];
var face_width = positions.chin[positions.chin.length - 1][0] - positions.chin[0][0];
//mine
var chin_R = positions.chin[positions.chin.length - 1];
var chin_L = positions.chin[0];
var chin_center = positions.chin[8];
var eyecorner_L = positions.left_eye[0];
var eyecorner_R = positions.right_eye[3];
var x = nose_pos[0];
var y = nose_pos[1];
var w = 2 * face_width;
var h = 2.5 * half_height;
// var curHairLength = map(this.hairLength, 0, 100, 0, 3);
var curHairColor = map(this.hairColor, 0, 120, 255, 20);
var curWrinkleWeight = map(this.wrinkleWeight, 0, 100, 0.0001, 0.065);
var curSpots = map(this.spots, 0, 100, 0, 1);
var curSkincolor = map(this.skinColor, 0, 100, 0, 1);
var skin_tone = lerpColor(base_tone1,base_tone2,curSkincolor);
var blush_color = lerpColor(blush_base,skin_tone,0.55);
var extent = 0;
if (h < w) {
extent = h / 2;
} else {
extent = w / 2;
}
var scale = extent / 220.0;
var eyeShift = 0.35;
for (var i = positions.left_eye.length - 1; i >= 0; i--) {
positions.left_eye[i][1]+=eyeShift;
positions.right_eye[i][1]+=eyeShift;
}
eye1_pos = average_point(positions.left_eye);
eye2_pos = average_point(positions.right_eye);
var eye3_pos = average_point([eye1_pos,eye2_pos]);
//head
var foreheadCenter = average_point([chin_L, chin_R]);
var face_height = distanceBetween(foreheadCenter, chin_center);
push();
noFill();
stroke(blush_color);
fill(skin_tone);
strokeWeight(0.07);
//head outline
beginShape();
curveVertex(-1.5, -2);
curveVertex(chin_L[0], chin_L[1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[4][0], positions.chin[4][1]);
curveVertex(positions.chin[6][0], positions.chin[6][1]);
curveVertex(chin_center[0], chin_center[1]);
curveVertex(positions.chin[10][0], positions.chin[10][1]);
curveVertex(positions.chin[12][0], positions.chin[12][1]);
curveVertex(positions.chin[14][0], positions.chin[14][1]);
curveVertex(chin_R[0], chin_R[1]);
//forehead
curveVertex(chin_R[0] - 0.5, chin_R[1] - face_height * 0.45);
curveVertex(foreheadCenter[0], foreheadCenter[1] - face_height * 0.65);
curveVertex(chin_L[0] + 0.5, chin_L[1] - face_height * 0.45);
//close
curveVertex(chin_L[0], chin_L[1]);
curveVertex(positions.chin[1][0], positions.chin[1][1]);
endShape();
pop();
//wrinkels
var wrink_width = face_width*0.2;
var wrink_stroke = curWrinkleWeight;
if (wrink_stroke > 0.0001) {
push();
translate(eye3_pos[0],face_height*-0.65);
rotate(angleBetween(eye1_pos,eye2_pos));
noFill();
stroke(blush_color);
strokeWeight(wrink_stroke);
line(-wrink_width,0,wrink_width , 0);
strokeWeight(wrink_stroke);
beginShape();
curveVertex( - 1, + 0.3 + wrink_stroke);
curveVertex( - wrink_width * 0.8, 0.11 );
curveVertex( + wrink_width * 0.8, 0.11 );
curveVertex( + 1, + 0.3 + wrink_stroke);
endShape();
beginShape();
curveVertex( - 1, - 0.3 - wrink_stroke);
curveVertex( - wrink_width * 0.8, -0.11 );
curveVertex( + wrink_width * 0.8, -0.11);
curveVertex( + 1, - 0.3 - wrink_stroke);
endShape();
pop();
}
//brows
var brow_outer_l = positions.left_eyebrow[0];
var brow_inner_l = positions.left_eyebrow[4];
var brow_upper_l = positions.left_eyebrow[2];
var brow_outer_r = positions.right_eyebrow[4]
var brow_inner_r = positions.right_eyebrow[0];
var brow_upper_r = positions.right_eyebrow[2];
var brow_height_left = (distanceBetween(brow_outer_l, brow_upper_l) + distanceBetween(brow_inner_l, brow_upper_l)) / 4;
var brow_height_right = (distanceBetween(brow_outer_r, brow_upper_r) + distanceBetween(brow_inner_r, brow_upper_r)) / 4;
var brow_width_right = distanceBetween(brow_outer_r, brow_inner_r) * 0.7;
var brow_width_left = distanceBetween(brow_outer_l, brow_inner_l) * 0.7;
// console.log(curHairColor);
var brow_color = curHairColor;
var brow_outline = curHairColor*0.95;
push();
fill(brow_color);
stroke(brow_outline);
//left brow
translate(brow_upper_l[0], brow_upper_l[1]);
rotate(angleBetween(brow_inner_l, brow_outer_l));
ellipse(0, brow_height_left / 4 - eyeShift, brow_width_left, brow_height_left);
pop();
push();
//right brow
fill(brow_color);
stroke(brow_outline);
translate(brow_upper_r[0], brow_upper_r[1]);
rotate(angleBetween(brow_outer_r, brow_inner_r));
ellipse(0, brow_height_right / 4 - eyeShift, brow_width_right, brow_height_left);
pop();
//eyes
//eyes are drawn always closed, with glasses
var blink_weight_L = Math.abs(average_point([positions.left_eye[1], positions.left_eye[2]])[1] - average_point([positions.left_eye[4], positions.left_eye[5]])[1]) / 3;
var blink_weight_R = Math.abs(average_point([positions.right_eye[1], positions.right_eye[2]])[1] - average_point([positions.right_eye[4], positions.right_eye[5]])[1]) / 3;
push();
stroke(blush_color);
noFill();
strokeWeight(blink_weight_L);
beginShape(); //left eye
curveVertex(positions.left_eye[5][0], positions.left_eye[4][1]);
curveVertex(positions.left_eye[0][0], positions.left_eye[0][1]);
curveVertex(positions.left_eye[1][0], positions.left_eye[1][1]);
curveVertex(positions.left_eye[2][0], positions.left_eye[2][1]);
curveVertex(positions.left_eye[3][0], positions.left_eye[3][1]);
curveVertex(positions.left_eye[4][0], positions.left_eye[4][1]);
endShape();
strokeWeight(blink_weight_R);
beginShape(); //right eye
curveVertex(positions.right_eye[5][0], positions.right_eye[4][1]);
curveVertex(positions.right_eye[0][0], positions.right_eye[0][1]);
curveVertex(positions.right_eye[1][0], positions.right_eye[1][1]);
curveVertex(positions.right_eye[2][0], positions.right_eye[2][1]);
curveVertex(positions.right_eye[3][0], positions.right_eye[3][1]);
curveVertex(positions.right_eye[4][0], positions.right_eye[4][1]);
endShape();
pop();
// lens size calculated from average distance between each outer point in positions.eye(l/r) and "eye_pos" center
var l_lens_size;
var r_lens_size;
var frame_color = '#494c56';
var lens_color = color(255, 90);
for (var i = 0; i < positions.left_eye.length; i++) {
l_lens_size = distanceBetween(positions.left_eye[i], eye1_pos);
r_lens_size = distanceBetween(positions.right_eye[i], eye2_pos);
}
l_lens_size /= positions.left_eye.length;
r_lens_size /= positions.right_eye.length;
l_lens_size = 0.4 + l_lens_size * 30;
r_lens_size = 0.4 + r_lens_size * 30;
push();
fill(lens_color);
strokeWeight(0.095);
stroke(frame_color);
//lenses
ellipse(eye1_pos[0], eye1_pos[1], l_lens_size, l_lens_size);
ellipse(eye2_pos[0], eye2_pos[1], r_lens_size, r_lens_size);
//glasses legs (called 'temples')
var temple_connect_angle = -TWO_PI / 32;
var temple_connect_l = rim_vert(eye1_pos, l_lens_size / 2, PI - temple_connect_angle);
var temple_connect_r = rim_vert(eye2_pos, r_lens_size / 2, temple_connect_angle);
noFill();
var bridge_control_offset = distanceBetween(eye1_pos, eye2_pos) - (l_lens_size / 2) - (r_lens_size / 2);
beginShape();
curveVertex(positions.nose_bridge[3][0] * -0.30, (positions.nose_bridge[3][1] + bridge_control_offset) / 2);
curveVertex(eye1_pos[0] + (l_lens_size / 2), eye1_pos[1]);
curveVertex(eye2_pos[0] - (r_lens_size / 2), eye2_pos[1]);
curveVertex(positions.nose_bridge[3][0] * -0.30, (positions.nose_bridge[3][1] + bridge_control_offset) / 2);
endShape();
if (temple_connect_l[0] > chin_L[0]) {
line(chin_L[0], chin_L[1], temple_connect_l[0], temple_connect_l[1]);
}
if (temple_connect_r[0] < chin_R[0]) {
line(chin_R[0], chin_R[1], temple_connect_r[0], temple_connect_r[1]);
}
pop();
//mouth
// for positions.top_lip & positions.bottom_lip: inside = 8,9,10 | outside = 2,3,4 | end = 11
// top_lip[0] is in left mouth corner
// bottom_lip[0] is in right mouth corner
// bottom[0] + top[6] || bottom[6] + top[0] will always intersect
var top_lip_outside = [positions.top_lip[2], positions.top_lip[3], positions.top_lip[4]];
var bottom_lip_outside = [positions.bottom_lip[2], positions.bottom_lip[3], positions.bottom_lip[4]];
var mouthCorner_LT = positions.top_lip[0]; // Left/Top
var mouthCorner_RB = positions.bottom_lip[0]; // Right/Bottom
var top_lip_inside = [positions.top_lip[8], positions.top_lip[9], positions.top_lip[10]];
var bottom_lip_inside = [positions.bottom_lip[8], positions.bottom_lip[9], positions.bottom_lip[10]];
// var mouth_angle = angleBetween(positions.bottom_lip[0], positions.top_lip[0]);
var mouth_width = distanceBetween(positions.bottom_lip[0], positions.top_lip[0]);
var smile;
var lip_thickness = 0;
var mouth_open = 0;
var innverAv = [];
for (var i = 2; i > 0; i--) {
mouth_open += distanceBetween(top_lip_inside[i], bottom_lip_inside[i]);
lip_thickness += distanceBetween(top_lip_inside[i], top_lip_outside[i]);
lip_thickness += distanceBetween(bottom_lip_inside[i], bottom_lip_outside[i]);
innverAv.push(top_lip_inside[i]);
innverAv.push(bottom_lip_inside[i]);
}
innverAv = average_point(innverAv);
cornerAv = average_point([mouthCorner_LT, mouthCorner_RB]);
mouth_open /= 3;
lip_thickness /= 6;
smile = cornerAv[1] - innverAv[1];
push();
strokeWeight(lip_thickness * 0.75);
stroke(blush_color);
noFill();
beginShape();
curveVertex(mouthCorner_LT[0] - smile, mouthCorner_LT[1] + smile * 2);
curveVertex(mouthCorner_LT[0] + mouth_width * 0.15, mouthCorner_LT[1] - smile);
curveVertex(mouthCorner_RB[0] - mouth_width * 0.15, mouthCorner_RB[1] - smile);
curveVertex(mouthCorner_RB[0] - smile, mouthCorner_RB[1] + smile * 2);
endShape();
pop();
fill('red');
stroke('red');
// debugShowPoints(positions.left_eye);
//debugShowPoints(hair_L);
function toms_face() {
// head
stroke(kelly_stroke_color);
fill(kelly_fg_color);
beginShape();
for (var i = 0; i < positions.chin.length; i++) {
vertex(positions.chin[i][0], positions.chin[i][1]);
}
for (var i = positions.right_eyebrow.length - 1; i >= 0; i--) {
vertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
for (var i = positions.left_eyebrow.length - 1; i >= 0; i--) {
vertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
endShape(CLOSE);
// mouth
noStroke();
fill(kelly_bg_color);
beginShape();
for (var i = 0; i < positions.top_lip.length; i++) {
vertex(positions.top_lip[i][0], positions.top_lip[i][1]);
}
endShape(CLOSE);
beginShape();
for (var i = 0; i < positions.bottom_lip.length; i++) {
vertex(positions.bottom_lip[i][0], positions.bottom_lip[i][1]);
}
endShape(CLOSE);
// nose
beginShape();
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]);
for (var i = 0; i < positions.nose_tip.length; i++) {
vertex(positions.nose_tip[i][0], positions.nose_tip[i][1]);
}
endShape(CLOSE);
// eyes
beginShape();
for (var i = 0; i < positions.left_eye.length; i++) {
vertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
endShape(CLOSE);
beginShape();
for (var i = 0; i < positions.right_eye.length; i++) {
vertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
endShape(CLOSE);
fill(kelly_fg_color);
ellipse(eye1_pos[0], eye1_pos[1], 16 * scale, 16 * scale);
ellipse(eye2_pos[0], eye2_pos[1], 16 * scale, 16 * scale);
fill(kelly_stroke_color);
beginShape();
for (var i = 0; i < positions.right_eyebrow.length; i++) {
vertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
endShape(CLOSE);
beginShape();
for (var i = 0; i < positions.left_eyebrow.length; i++) {
vertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
endShape(CLOSE);
strokeWeight(1);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.hairColor = settings[0];
this.wrinkleWeight = settings[1];
this.skinColor = settings[2];
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
properties = new Array(3);
properties[0] = this.hairColor;
properties[1] = this.wrinkleWeight;
properties[2] = this.skinColor;
return properties;
}
}
// given a point, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for (var i = 0; i < list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
function rim_vert(vert, rad, angl) { //find the co-oridnates for a point on a circle
var x = Math.cos(angl) * rad;
var y = Math.sin(angl) * rad;
return [x + vert[0], y + vert[1]];
}
function angleBetween(p1, p2) {
//angle given with reference to horizon line
var c;
c = Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180 / Math.PI;
return c;
}
function distanceBetween(p1, p2) {
var a = p1[0] - p2[0];
var b = p1[1] - p2[1];
var c = Math.abs(Math.sqrt(a * a + b * b));
return c;
}
function debugShowPoints(arr, txtsiz) {
push();
textSize(0.25);
if (txtsiz) {
textSize(txtsiz);
}
noStroke();
for (var i = arr.length - 1; i >= 0; i--) {
text(i, arr[i][0], arr[i][1]);
}
pop();
}
{
"000001": [
83,
0,
17
],
"000002": [
54,
41
],
"000058": [
100,
7,
4
],
"000005": [
18,
0,
18
],
"000006": [
45,
27,
57
],
"000007": [
94,
67,
34
],
"000009": [
66,
31,
9
],
"000010": [
20,
40,
20
],
"000013": [
0,
71,
0
],
"000014": [
100,
17,
71
],
"000015": [
74,
64,
36
],
"000016": [
80,
40,
27
],
"000018": [
11,
36,
4
],
"000020": [
76,
47,
17
],
"000023": [
87,
70,
20
],
"000025": [
71,
32,
16
],
"000028": [
59,
66,
21
],
"000029": [
5,
6,
13
],
"000030": [
14,
61,
15
],
"000031": [
29,
93,
0
],
"000032": [
9,
60,
23
],
"000035": [
100,
0,
0
],
"000037": [
100,
16,
67
],
"000038": [
87,
100,
7
],
"000040": [
93,
7,
14
],
"000041": [
98,
100,
19
],
"000042": [
23,
34,
0
],
"000043": [
74,
45,
20
],
"000044": [
100,
0,
93
],
"000045": [
69,
17,
14
],
"000047": [
100,
55,
17
],
"000048": [
90,
7,
0
],
"000050": [
78,
100,
17
],
"000051": [
0,
100,
30
],
"000052": [
70,
100,
22
],
"000054": [
12,
72,
10
],
"000055": [
97,
64,
8
],
"000056": [
100,
23,
7
],
"000060": [
72,
80,
96
],
"000064": [
74,
49,
2
],
"000065": [
80,
25,
9
],
"000068": [
42,
100,
21
],
"000069": [
100,
69,
7
],
"000071": [
5,
39,
14
],
"000073": [
79,
12,
29
],
"000076": [
100,
75,
9
],
"000077": [
100,
0,
0
],
"000078": [
84,
18,
5
],
"000079": [
0,
59,
21
],
"000080": [
98,
21,
0
],
"000081": [
98,
87,
0
],
"000083": [
64,
14,
4
],
"000085": [
71,
18,
6
],
"000086": [
50,
4,
7
],
"000088": [
70,
0,
7
],
"000091": [
94,
22,
5
],
"000092": [
17,
69,
8
],
"000096": [
77,
0,
17
],
"000097": [
31,
21,
19
],
"000099": [
57,
21,
8
],
"000100": [
27,
34,
5
],
"000103": [
67,
0,
5
],
"000104": [
10,
82,
3
],
"000106": [
38,
23,
21
],
"000108": [
2,
36,
4
],
"000109": [
11,
50,
28
],
"000110": [
73,
40,
17
],
"000111": [
34,
13,
65
],
"000114": [
92,
34,
14
],
"000115": [
0,
17,
0
],
"000116": [
59,
85,
36
],
"000117": [
100,
0,
67
],
"000118": [
91,
15,
69
],
"000121": [
91,
67,
37
],
"000122": [
0,
81,
0
],
"000125": [
20,
100,
18
],
"000126": [
0,
35,
21
],
"000129": [
90,
41,
31
],
"000131": [
91,
29,
14
],
"000132": [
100,
33,
59
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 6;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
// example of a global function
// given a segment, this returns the average point [x, y]
// This where you define your own face object
function LeeFace() {
// these are state variables for a face
// (your variables should be different!)
this.mouth_value= 4;
this.petal_colour = 1;
this.petal_layer = 1;
this.petal_length = 2;
this.eye_size_y = 1.5;
this.eye_colour = 1;
this.face_colour =1;
/* Slider 1 - Hair colour - blue for dark hair, cyan for lgiht hair or no hair, red for red hair
Slider 2 - Petal Layers - 1 for feminine, 2 for masculine
Slider 3 - Petal Shape - Pointy for short hair, rounded for long hair
Slider 4 - Eye size
Slider 5 -Eye colour - purple for blue eyes, green for green eyes, brown for brown eyes
Slider 6 -Skin Colour - light for lighter skin, dark for darker skin.
*/
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw = function(positions) {
//VARIABLES
const blue = color(83, 40, 237,180);
const cyan_bonus = color(48, 252, 255, 220);
const red = color(227, 29, 23,180);
const red_stroke = color(235, 62, 56 );
const blue_stroke = color(68, 21, 171);
const cyan_b_stroke = color(48, 252, 255);
const purple_eyes = color(92, 0, 163);
const green_eyes = color(0, 122, 104);
const brown_eyes = color(166, 91, 0);
const darker = color(255, 131, 8);
const lighter = color(255, 166, 0);
let bottom_lip3 = positions.bottom_lip[2];
let bottom_lip4 = positions.bottom_lip[3];
let bottom_lip5 = positions.bottom_lip[4];
let top_lip1 = positions.top_lip[1];
let top_lip2 = positions.top_lip[2];
let top_lip3 = positions.top_lip[3];
let top_lip4 = positions.top_lip[4];
let top_lip6 = positions.top_lip[5];
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos= segment_average(positions.right_eye);
let nose_pos = positions.nose_bridge[0];
let mouth_top = positions.top_lip[3];
let mouth_bottom = positions.bottom_lip[3];
let right_eyebrow = positions.right_eyebrow;
let left_eyebrow = positions.left_eyebrow;
let right_brow_0 = positions.right_eyebrow[0];
let right_brow_1 = positions.right_eyebrow[1];
let right_brow_2 = positions.right_eyebrow[2];
let right_brow_3 = positions.right_eyebrow[3];
let right_brow_4 = positions.right_eyebrow[4];
let left_brow_0 = positions.left_eyebrow[0];
let left_brow_1 = positions.left_eyebrow[1];
let left_brow_2 = positions.left_eyebrow[2];
let left_brow_3 = positions.left_eyebrow[3];
let left_brow_4 = positions.left_eyebrow[4];
// rotation in degrees
angleMode(DEGREES);
//rotate(tilt_value);
strokeWeight(0.05);
//PETAL COLOURS--BLUE, CYAN OR RED------------------------------
if(this.petal_colour == 1) {
fill(blue);
stroke(blue_stroke);
}
else if(this.petal_colour ==2) {
fill(cyan_bonus);
stroke(cyan_b_stroke);
}
else if(this.petal_colour ==3) {
fill(red);
stroke(red_stroke);
}
//PETAL LAYERS -- ONE OR TWO------------------------------
if(this.petal_layer == 1) {
beginShape();
curveVertex(0,0);
curveVertex(0, 0);
curveVertex(-2.8, 1.2);
curveVertex(-this.petal_length,-0.8);
curveVertex(-2.8, -2.8);
curveVertex(0,-1.6);
curveVertex(0,-1.6);
endShape();
beginShape();
curveVertex(0,-1.6);
curveVertex(0, -1.6);
curveVertex(2.8, -2.8);
curveVertex(this.petal_length,-0.8);
curveVertex(2.8, 1.2);
curveVertex(0,0);
curveVertex(0,0);
endShape();
beginShape();
curveVertex(-0.8,-0.8);
curveVertex(-0.8,-0.8);
curveVertex(-2, -3.6);
curveVertex(0, -this.petal_length-0.8);
curveVertex(2, -3.6);
curveVertex(0.8, -0.8);
curveVertex(0.8,-0.8);
endShape();
beginShape();
curveVertex(-0.8,-0.8);
curveVertex(-0.8,-0.8);
curveVertex(-2, 2);
curveVertex(0, this.petal_length-0.8);
curveVertex(2, 2);
curveVertex(0.8, -0.8);
curveVertex(0.8,-0.8);
endShape();
}
else if(this.petal_layer ==2){
beginShape();
curveVertex(0,0);
curveVertex(0, 0);
curveVertex(-2.8, 1.2);
curveVertex(-this.petal_length,-0.8);
curveVertex(-2.8, -2.8);
curveVertex(0,-1.6);
curveVertex(0,-1.6);
endShape();
beginShape();
curveVertex(0,-1.6);
curveVertex(0, -1.6);
curveVertex(2.8, -2.8);
curveVertex(this.petal_length,-0.8);
curveVertex(2.8, 1.2);
curveVertex(0,0);
curveVertex(0,0);
endShape();
beginShape();
curveVertex(-0.8,-0.8);
curveVertex(-0.8,-0.8);
curveVertex(-2, -3.6);
curveVertex(0, -this.petal_length-0.8);
curveVertex(2, -3.6);
curveVertex(0.8, -0.8);
curveVertex(0.8,-0.8);
endShape();
beginShape();
curveVertex(-0.8,-0.8);
curveVertex(-0.8,-0.8);
curveVertex(-2, 2);
curveVertex(0, this.petal_length-0.8);
curveVertex(2, 2);
curveVertex(0.8, -0.8);
curveVertex(0.8,-0.8);
endShape();
fill(174, 82, 255, 170);
//SECOND LAYER OF PETALS
beginShape();
curveVertex(-0.8, 0);
curveVertex(-0.8, 0);
curveVertex(-2, 0.4);
curveVertex(-this.petal_length/1.2, -0.8);
curveVertex(-2, -2);
curveVertex(-0.8, -1.6);
curveVertex(-0.8, -1.6);
endShape();
beginShape();
curveVertex(0.8, 0);
curveVertex(0.8, 0);
curveVertex(2, 0.4);
curveVertex(this.petal_length/1.2, -0.8);
curveVertex(2, -2);
curveVertex(0.8, -1.6);
curveVertex(0.8, -1.6);
endShape();
beginShape();
curveVertex(0.8, 0);
curveVertex(0.8, 0);
curveVertex(1.2, 1.2);
curveVertex(0, this.petal_length/1.2 -0.8);
curveVertex(-1.2, 1.2);
curveVertex(-0.8, 0);
curveVertex(-0.8, 0);
endShape();
beginShape();
curveVertex(0.8, -1.6);
curveVertex(0.8, -1.6);
curveVertex(1.2, -2.8);
curveVertex(0, -this.petal_length/1.2 -0.8);
curveVertex(-1.2, -2.8);
curveVertex(-0.8, -1.6);
curveVertex(-0.8, -1.6);
endShape();
}
//FACE COLOUR--LIGHTER OR DARKER----------------------------------------------------------------------
if(this.face_colour ==1){
fill(lighter);
stroke(255, 83, 3);
}
else if(this.face_colour ==2){
fill(darker);
stroke(255, 83, 3);
}
//HEAD
ellipse(0, -0.8, 2.4);
//EYES
//WHITE
fill(255);
strokeWeight(0.05);
stroke(255, 224, 153);
noStroke();
ellipse(left_eye_pos[0], left_eye_pos[1]+0.05,0.6, this.eye_size_y);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.05, 0.6, this.eye_size_y);
//EYE COLOUR
if (this.eye_colour == 1){
fill(purple_eyes);
}
else if(this.eye_colour ==2){
fill(green_eyes);
}
else if( this.eye_colour ==3){
fill(brown_eyes);
}
//IRIS
noStroke();
ellipse(left_eye_pos[0],left_eye_pos[1]+0.05,0.4,this.eye_size_y/2);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.05,0.4,this.eye_size_y/2);
//HIGHLIGHTS------------------
noStroke();
fill(255);
//left hl
ellipse(left_eye_pos[0]+0.1,left_eye_pos[1],this.eye_size_y/6);
//right hl
ellipse(right_eye_pos[0]+0.1,right_eye_pos[1],this.eye_size_y/6);
//MOUTH
noStroke();
if(this.face_colour ==1){
fill(224, 108, 0);
}
else if(this.face_colour ==2){
fill(184, 61, 0);
}
push();
scale(0.8);
translate(0, -0.8);
beginShape();
curveVertex(top_lip1[0], top_lip1[1]);
curveVertex(top_lip1[0], top_lip1[1]);
curveVertex(bottom_lip3[0] - 0.4, bottom_lip3[1] );
curveVertex(bottom_lip4[0], bottom_lip4[1] +0.02);
curveVertex(bottom_lip5[0] + 0.4, bottom_lip5[1]);
curveVertex(top_lip6[0], top_lip6[1]);
curveVertex(top_lip4[0], top_lip4[1]-0.1);
curveVertex(top_lip3[0]+0.1, top_lip3[1]-0.15);
curveVertex(top_lip3[0]-0.1, top_lip3[1]-0.15);
curveVertex(top_lip2[0], top_lip2[1]-0.1);
curveVertex(top_lip2[0], top_lip2[1]-0.1);
endShape();
endShape();
pop();
//EYEBROWS --------------------------
stroke(15, 33, 92);
strokeWeight(0.3);
noFill();
beginShape();
curveVertex(left_brow_0[0], left_brow_0[1]),
curveVertex(left_brow_1[0], left_brow_1[1]),
curveVertex(left_brow_2[0], left_brow_2[1]),
curveVertex(left_brow_3[0], left_brow_3[1]),
curveVertex(left_brow_4[0], left_brow_4[1]),
endShape();
beginShape();
curveVertex(right_brow_0[0], right_brow_0[1]),
curveVertex(right_brow_1[0], right_brow_1[1]),
curveVertex(right_brow_2[0], right_brow_2[1]),
curveVertex(right_brow_3[0], right_brow_3[1]),
curveVertex(right_brow_4[0], right_brow_4[1]),
endShape();
//NOSE -----------------------------
//NOSE COLOUR -- BASED ON SKIN COLOUR
if(this.face_colour ==1){
fill(224, 108, 0);
}
else if (this.face_colour ==2){
fill(194, 78, 0);
}
//DRAW NOSE
noStroke();
ellipse(nose_pos[0], nose_pos[1]+0.4, 0.2, 0.1);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.petal_colour = int(map(settings[0], 0, 100, 1, 3));
this.petal_layer = int(map(settings[1], 0, 100, 1, 2));
this.petal_length = map(settings[2], 0, 100, 2, 3);
this.eye_size_y = map(settings[3], 0, 100, 0.4, 1);
this.eye_colour = int(map(settings[4], 0, 100, 1, 3));
this.face_colour = int(map(settings[5], 0, 100, 1, 2));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(6);
settings[0] = map(this.petal_colour, 1,3, 0, 100);
settings[1] = map(this.petal_layer, 1, 2, 0, 100);
settings[2] = map(this.petal_length, 2, 3, 0, 100);
settings[3] = map(this.eye_size_y, 0.4, 1, 0, 100);
settings[4] = map(this.eye_colour, 1, 3, 0, 100);
settings[5] = map(this.face_colour, 1, 2, 0, 100);
return settings;
}
}
{
"000001": [
50,
0,
100,
100,
100,
0
],
"000002": [
100,
0,
100,
100,
100,
0
],
"000005": [
50,
0,
100,
81,
50,
0
],
"000006": [
0,
0,
100,
100,
100,
100
],
"000007": [
0,
100,
0,
27.000000000000007,
100,
0
],
"000009": [
100,
0,
100,
100,
100,
0
],
"000010": [
50,
0,
100,
100,
0,
0
],
"000013": [
50,
100,
0,
12.000000000000002,
50,
0
],
"000014": [
0,
0,
100,
100,
100,
100
],
"000015": [
0,
100,
0,
0,
100,
0
],
"000016": [
0,
100,
0,
0,
100,
0
],
"000018": [
50,
0,
100,
51.99999999999999,
50,
0
],
"000020": [
0,
100,
0,
19,
100,
0
],
"000023": [
0,
100,
0,
14.999999999999996,
0,
0
],
"000025": [
0,
100,
0,
25.000000000000007,
100,
0
],
"000028": [
100,
0,
100,
100,
100,
0
],
"000029": [
50,
0,
100,
100,
50,
0
],
"000030": [
50,
100,
0,
93.00000000000001,
50,
0
],
"000031": [
50,
0,
100,
61,
0,
0
],
"000032": [
0,
100,
0,
61,
100,
0
],
"000035": [
0,
0,
100,
100,
100,
0
],
"000037": [
0,
100,
0,
33.000000000000014,
100,
100
],
"000038": [
0,
100,
0,
12.000000000000002,
50,
0
],
"000040": [
0,
0,
100,
100,
100,
0
],
"000041": [
0,
100,
0,
20,
100,
100
],
"000042": [
50,
0,
100,
64,
50,
0
],
"000043": [
0,
0,
100,
100,
100,
0
],
"000044": [
0,
0,
100,
100,
100,
100
],
"000045": [
100,
0,
100,
34.000000000000014,
100,
0
],
"000047": [
0,
0,
100,
0,
100,
100
],
"000048": [
0,
100,
0,
9,
100,
0
],
"000050": [
0,
100,
0,
9,
100,
0
],
"000051": [
50,
100,
0,
78,
100,
0
],
"000052": [
0,
100,
0,
45.00000000000001,
50,
0
],
"000054": [
50,
0,
100,
30.00000000000001,
50,
0
],
"000055": [
0,
100,
0,
13.000000000000004,
100,
0
],
"000056": [
0,
100,
39.000000000000014,
13.000000000000004,
100,
0
],
"000058": [
0,
0,
100,
85.00000000000001,
0,
0
],
"000060": [
100,
100,
0,
20,
100,
100
],
"000064": [
0,
100,
0,
0,
50,
0
],
"000065": [
0,
100,
0,
0,
100,
100
],
"000068": [
0,
100,
0,
0,
100,
0
],
"000069": [
0,
100,
0,
100,
100,
0
],
"000071": [
50,
0,
100,
100,
50,
0
],
"000073": [
0,
0,
100,
52.99999999999999,
100,
0
],
"000076": [
0,
100,
25,
52.99999999999999,
100,
100
],
"000077": [
0,
0,
100,
100,
100,
0
],
"000078": [
0,
0,
100,
100,
100,
0
],
"000079": [
50,
100,
0,
36,
100,
100
],
"000080": [
0,
100,
0,
0,
50,
0
],
"000081": [
0,
100,
0,
0,
100,
100
],
"000083": [
100,
0,
100,
100,
50,
0
],
"000085": [
100,
0,
100,
100,
50,
0
],
"000086": [
100,
0,
100,
100,
50,
0
],
"000088": [
100,
0,
100,
68,
100,
0
],
"000091": [
0,
100,
0,
0,
100,
0
],
"000092": [
50,
0,
100,
78,
50,
0
],
"000096": [
0,
0,
100,
100,
100,
100
],
"000097": [
50,
0,
100,
100,
0,
0
],
"000099": [
50,
0,
100,
100,
50,
0
],
"000100": [
50,
0,
100,
100,
100,
0
],
"000103": [
0,
0,
100,
100,
50,
0
],
"000104": [
50,
100,
0,
0,
0,
0
],
"000106": [
100,
0,
100,
100,
100,
0
],
"000108": [
50,
0,
100,
100,
0,
0
],
"000109": [
50,
100,
0,
48.999999999999986,
50,
0
],
"000110": [
0,
0,
100,
17,
50,
0
],
"000111": [
50,
0,
100,
0,
100,
100
],
"000114": [
0,
100,
0,
100,
100,
0
],
"000115": [
50,
100,
0,
0,
50,
0
],
"000116": [
0,
100,
0,
37,
100,
0
],
"000117": [
0,
0,
100,
100,
100,
100
],
"000118": [
0,
0,
100,
100,
100,
100
],
"000121": [
0,
0,
100,
100,
100,
100
],
"000122": [
50,
0,
100,
81.99999999999999,
100,
0
],
"000125": [
0,
100,
0,
55.99999999999999,
50,
100
],
"000126": [
50,
0,
100,
100,
50,
100
],
"000129": [
0,
100,
0,
32.000000000000014,
100,
0
],
"000131": [
0,
0,
100,
72.00000000000001,
100,
100
],
"000132": [
0,
0,
100,
44.00000000000001,
100,
100
],
"000133": [
50,
0,
100,
100,
0,
0
],
"000134": [
0,
100,
0,
73.00000000000001,
100,
100
],
"000135": [
0,
100,
0,
43.00000000000001,
100,
100
],
"000137": [
0,
100,
0,
0,
100,
0
],
"000140": [
50,
0,
100,
100,
0,
0
],
"000142": [
0,
0,
100,
100,
0,
0
],
"000143": [
50,
100,
0,
32.000000000000014,
50,
0
],
"000145": [
0,
0,
100,
0,
100,
0
],
"000146": [
100,
0,
100,
65,
100,
100
],
"000147": [
50,
0,
100,
100,
50,
0
],
"000148": [
0,
0,
100,
30.00000000000001,
50,
0
],
"000150": [
100,
100,
0,
85.00000000000001,
50,
0
],
"000151": [
0,
0,
100,
26.000000000000007,
100,
100
],
"000152": [
0,
100,
0,
25.000000000000007,
50,
0
],
"000153": [
0,
100,
0,
25.000000000000007,
100,
0
],
"000155": [
100,
0,
100,
100,
100,
0
],
"000156": [
50,
0,
100,
62,
0,
0
],
"000157": [
50,
0,
100,
68,
50,
0
],
"000160": [
0,
100,
0,
42.00000000000001,
100,
0
],
"000161": [
0,
0,
100,
0,
50,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 5;
// other variables can be in here too
// these control the colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
function LuoFace() {
// these are state variables for a face
// (your variables may be different)
this.face = 4; // 1-5
this.spot = 5; // 0-10
this.shape = 1;
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
let face = this.face;
let mouth = 5;
let blush = 5;
let spot = this.spot;
let spot_col = 5;
let spot_size = 1;
let eyebrows_rotate = 50;
let glasses = 5;
// Colour Sets
let face1 = '#ffe3fc'; //white
let face2 = '#f5ad8e'; //pink
let face3 = '#fcf06a'; //yellow
let face4 = '#d9764c'; //brown
let face5 = '#66756a'; //grey
let face6 = '#315070'; //blue
let face7 = '#8a5189'; //purple
let face8 = '#a65561'; //red
let face9 = '#5b8a5a'; //green
let face10 = '#de4e26'; //orange
let faceColour;
let left_eye = average_point(positions.left_eye);
let right_eye = average_point(positions.right_eye);
let left_eyebrow = average_point(positions.left_eyebrow);
let right_eyebrow = average_point(positions.right_eyebrow);
let left_d = dist(left_eye[0], left_eye[1], left_eyebrow[0], left_eyebrow[1]);
let right_d = dist(right_eye[0], right_eye[1], right_eyebrow[0], right_eyebrow[1]);
let left_eb_move = map(left_d, 0.4, 0.7, 0, 2, true);
let right_eb_move = map(right_d, 0.4, 0.7, 0, 2, true);
// print(left_d);
left_eye[0] *= 3;
left_eye[1] *= 3;
right_eye[0] *= 3;
right_eye[1] *= 3;
push();
scale(0.33);
// Rabbit (Brown)
//fill(221,168,128);
strokeWeight(0.3);
stroke(0);
beginShape();
endShape();
if(this.shape <2){
//soft SHAPES
noStroke();
// Face Colour
if(face == 1){
faceColour = face1; //***WHITE***//
}else if (face == 2){
faceColour = face2; //***dark***//
}else if (face == 3){
faceColour = face3; //***Yellow***//
}else if (face == 4){
faceColour = face4; //***Brown***//
}else{
faceColour = face5; //***Grey***//
}
fill(faceColour);
strokeWeight(0.3);
stroke(0);
ellipse(-0.5, 1.8, 15, 11);
push();
angleMode(RADIANS);
arc(-3.9, -3, 4.5, 16, -4, -0.4);//ear left
arc(2.4, -3.2, 5, 16, -2.8, 0.65);//ear right
pop();
} else {
//unsoft shape
if(face == 1){
faceColour = face6; //***WHITE***//
}else if (face == 2){
faceColour = face8; //***dark***//
}else if (face == 3){
faceColour = face7; //***Yellow***//
}else if (face == 4){
faceColour = face9; //***Brown***//
}else{
faceColour = face10; //***Grey***//
}
fill(faceColour);
strokeWeight(0.2);
stroke(0);
rect(-8, -4, 15, 11);
push();
angleMode(RADIANS);
rect(-3, -4, -2.5, -9.5);
rect(5, -4, -3, -6.5);
//arc(-3.9, -3, 4.5, 16, -4, -0.4);//ear left
//arc(2.4, -3.2, 5, 16, -2.8, 0.65);//ear right
pop();
}
// spot (Colour, Spot)
let amount = map(spot_col, 0, 10, 0, 1);
let colourWhite = color('#dbdbdb');
let colourDark = color('#e6655c');
let spotColour = lerpColor(colourWhite, colourDark, amount);
let spotFace = map(spot, 0, 100, 0, 100);
let spotS = map(spot_size, 0, 100, 1.3, 15);
strokeWeight(spotS);
stroke(spotColour);
if (spotFace == 0){
}
if (spotFace >= 2){
line(-0.5, -3, -0.5, -2);
}
if (spotFace >=4){
line(-6.5, 3, -3, 3);
}
if (spotFace >=6){
line(2.5, 2, 5.5, 2);
}
if (spotFace >=8){
line(3, 0, 5.5, 0);
}
if (spotFace >=10){
line(-6.5, 0.5, -4.5, 0.5);
}
// Mouth
strokeWeight(0.4);
stroke(0);
line(-1.55, -1, -0.05, -1);
let top_lip_point = positions.top_lip[9];
let bottom_lip_point = positions.bottom_lip[9];
// fill(255, 0, 0);
let d = dist(top_lip_point[0], top_lip_point[1], bottom_lip_point[0], bottom_lip_point[1])
// print(d);
// Mouth Open
if(d < 0.1) {
d = 0;
}
mouth = map(d, 0, 0.5, 0, 10);
let mouth_size = map(mouth, 0, 10, 0, 3.5);
strokeWeight(0.3);
fill('#fffcf7');
rect(-1.6, 2, 1.6, mouth_size, 0.08);
// Blush
noStroke();
if (blush > 3 && blush < 6){
fill('#ed4415'); //red
ellipse(-3.6, 0.5, 1.5, 1);
ellipse(2.3, 0.5, 1.5, 1);
}
// Eyes
noStroke();
fill(0);
// ellipse(-2.2, -2, 1.1, 1.1);
// ellipse(0.5, -2, 1.1, 1.1);
ellipse(left_eye[0], left_eye[1]+ 1.5, 2, 2); //eye size left
ellipse(right_eye[0] - 1.6, right_eye[1] + 1.7, 2, 2);
// Eyebrows
strokeWeight(0.5);
stroke(0);
push();
angleMode(DEGREES);
//translate(left_eye[0]-0.1, left_eye[1]-1);
//translate(0, -left_eb_move);
//rotate(eyebrows_rotate);
line(0.5, -2.5, 2.5, -2.5);
pop();
push();
angleMode(DEGREES);
//translate(right_eye[0]-0.2, right_eye[1]-1);
//translate(0, -right_eb_move);
//rotate(-eyebrows_rotate);
line(-3.5, -2.5, -1.5, -2.5);
pop();
// Glasses
if (glasses > 5 && glasses < 8){
stroke(0);
strokeWeight(0.35);
noFill();
ellipse(-2.3, -2.4, 2.6, 2.6);
ellipse(0.6, -2.4, 2.6, 2.6);
}
// Sunglasses
else if (glasses > 7 && glasses <= 10){
stroke(0);
strokeWeight(0.3);
fill('white');
ellipse(-2.6, -2.4, 3, 2.6);
ellipse(1, -2.4, 3, 2.6);
noStroke();
fill('black');
ellipse(-2.6, -2.37, 2.4, 2);
ellipse(1, -2.37, 2.4, 2);
stroke(0);
strokeWeight(0.3);
line(-1.1, -2.5, -0.65, -2.5);
}
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.face = int(map(settings[0], 0, 100, 1, 5));
this.spot = int(map(settings[1], 0, 100, 0, 10));
this.shape = map(settings[2],0,100,1,2);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(2);
settings[0] = map(this.face, 1, 5, 0, 100);
settings[1] = map(this.spot, 0, 10, 0, 100);
settings[82] = map(this.shape, 1, 2, 0, 100);
return settings;
}
}
// given an array of [x,y] points, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
0,
100,
50
],
"000002": [
0,
100
],
"000005": [
20,
100
],
"000006": [
50,
100,
50
],
"000007": [
25,
0
],
"000009": [
25,
100
],
"000010": [
25,
100,
50
],
"000013": [
25,
0
],
"000014": [
75,
100
],
"000015": [
25,
0,
50
],
"000016": [
25,
0
],
"000018": [
75,
100,
50
],
"000020": [
25,
0
],
"000023": [
55,
0
],
"000025": [
10,
0,
50
],
"000028": [
25,
100
],
"000029": [
75,
100,
50
],
"000030": [
25,
0
],
"000031": [
80,
100,
50
],
"000032": [
90,
0
],
"000035": [
40,
100
],
"000037": [
50,
0
],
"000038": [
0,
70,
50
],
"000040": [
0,
90
],
"000041": [
30,
50,
50
],
"000042": [
0,
100,
50
],
"000043": [
10,
100,
50
],
"000044": [
50,
100
],
"000045": [
20,
100
],
"000047": [
50,
100,
50
],
"000048": [
20,
0,
50
],
"000050": [
20,
0
],
"000051": [
0,
20
],
"000052": [
60,
50,
50
],
"000054": [
0,
100
],
"000055": [
90,
40
],
"000056": [
50,
100
],
"000058": [
20,
100,
50
],
"000060": [
100,
0
],
"000064": [
0,
0
],
"000065": [
50,
0
],
"000068": [
0,
30,
50
],
"000069": [
20,
0,
50
],
"000071": [
50,
100
],
"000073": [
40,
100,
50
],
"000076": [
50,
0,
50
],
"000077": [
0,
100
],
"000078": [
50,
100
],
"000079": [
0,
0
],
"000080": [
0,
0
],
"000081": [
0,
0
],
"000083": [
0,
100
],
"000085": [
0,
100
],
"000086": [
25,
100
],
"000088": [
0,
100
],
"000091": [
0,
0
],
"000092": [
0,
100
],
"000096": [
0,
100
],
"000097": [
0,
100
],
"000099": [
25,
100
],
"000100": [
0,
100
],
"000103": [
25,
100
],
"000104": [
25,
0
],
"000106": [
25,
0
],
"000108": [
25,
100
],
"000109": [
0,
0
],
"000110": [
25,
100
],
"000111": [
50,
100
],
"000114": [
0,
0
],
"000115": [
25,
0
],
"000116": [
0,
0
],
"000117": [
100,
100
],
"000118": [
25,
100
],
"000121": [
25,
100
],
"000122": [
0,
100
],
"000125": [
0,
0
],
"000126": [
0,
100
],
"000129": [
0,
0
],
"000131": [
25,
100
],
"000132": [
50,
100
],
"000133": [
0,
100
],
"000134": [
100,
0
],
"000135": [
75,
0
],
"000137": [
0,
0
],
"000140": [
0,
100
],
"000142": [
0,
100
],
"000143": [
0,
0
],
"000145": [
0,
100
],
"000146": [
0,
100
],
"000147": [
0,
100
],
"000148": [
0,
100
],
"000150": [
0,
0
],
"000151": [
50,
70
],
"000152": [
0,
0
],
"000153": [
0,
0
],
"000155": [
25,
100
],
"000156": [
0,
100
],
"000157": [
0,
100
],
"000160": [
0,
0
],
"000161": [
0,
90
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = false;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 9;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i = 0; i < s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len, sum_y / s_len];
}
// This where you define your own face object
function McKendryFace() {
//colours:
this.purple = color(210, 160, 200, 200);
this.pink = color(250, 225, 250, 200);
this.light_red = color(240, 180, 170, 200);
this.dark_red = color(185, 120, 115, 200);
this.orange = color(240, 190, 145, 200);
this.yellow = color(255, 250, 210, 200);
this.light_green = color(230, 250, 220, 200);
this.dark_green = color(150, 175, 135, 200);
this.dark_blue = color(135, 135, 180, 200);
this.light_blue = color(200, 230, 245, 200);
this.other_turq = color(195, 245, 225, 200);
//positions/states:
this.mouthX = 0;
this.mouthY = 0;
this.male_female = 1;
this.chinX = 0;
this.chinY = 0;
this.shapeScale = 1;
this.eye_height = .25;
this.faceColor = 1;
this.eyesX = 0;
this.mouth_OpenClose = 2
this.show_points = function(segment) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
var number = i.toString();
textAlign(CENTER, CENTER);
textSize(0.2);
fill(0);
text(number, px, py, 0.1);
}
}
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if (i < segment.length - 1) {
let nx = segment[i + 1][0];
let ny = segment[i + 1][1];
line(px, py, nx, ny);
} else if (do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
//this array takes the colours called in the variables above, then I get a random colour from the array to be the fill for the background shapes
this.colourFillArray = [this.purple, this.pink, this.light_red, this.dark_red, this.orange, this.yellow, this.light_green, this.dark_green, this.dark_blue, this.light_blue, this.other_turq];
this.colourFill = random(this.colourFillArray);
//If statement decides if the face is male or female, dictated by slider5.
if (this.male_female < 2) {
//FEMALE SHAPES
fill(this.colourFill);
noStroke();
push();
//scales shapes to size of the face
scale(this.shapeScale);
ellipse(0, 0, 2, 3);
ellipse(0, .5, 3.75, 3.25);
ellipse(-1.25, -1.5, 2, 4);
ellipse(.75, -2.5, 2.5, 2);
ellipse(-.5, 1.75, 2.5, 2);
ellipse(1, -1.5, 2, 2.5);
ellipse(-.75, -2.5, 2, 3);
//HAIRLINE
noFill();
stroke(0);
strokeWeight(0.035);
beginShape();
vertex(-.3, -2.9);
quadraticVertex(1.5, -4, 1.9, -2.5);
endShape();
pop();
//FEMALE MOUTH
//if-else statement decides if the mouth is closed (only a line, no fill) or open (area of mouth filled)
if (this.mouth_OpenClose == 1) {
stroke(0);
noFill();
strokeWeight(0.03);
beginShape();
vertex(positions.bottom_lip[7][0], positions.bottom_lip[7][1]);
quadraticVertex(positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
endShape();
} else {
stroke(0);
fill(200, 200, 200, 100);
strokeWeight(0.03);
beginShape();
vertex(positions.bottom_lip[7][0], positions.bottom_lip[7][1]);
quadraticVertex(positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
endShape();
strokeWeight(0.01);
line(positions.bottom_lip[7][0], positions.bottom_lip[7][1], positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
}
//FEMALE JAWLINE
stroke(0);
strokeWeight(0.035);
//if statement decides what side of the jaw the face is on, using the tip of the nose as a center point to figure out if the person is looking left or right
if (positions.nose_tip[2][0] < 0) {
beginShape();
noFill();
vertex(positions.chin[8][0], positions.chin[8][1])
quadraticVertex(positions.chin[12][0] + this.chinX, positions.chin[12][1] + this.chinY, positions.chin[16][0], positions.chin[16][1])
endShape();
} else {
beginShape();
noFill();
vertex(positions.chin[0][0], positions.chin[0][1])
quadraticVertex(positions.chin[4][0] + this.chinX, positions.chin[5][1] + this.chinY, positions.chin[8][0], positions.chin[8][1])
endShape();
}
//FEMALE EYEBROWS
noFill();
stroke(0);
strokeWeight(0.02);
beginShape();
vertex(positions.left_eyebrow[1][0], positions.left_eyebrow[1][1]);
quadraticVertex(positions.nose_bridge[1][0], positions.nose_bridge[1][1] - 1.2, positions.right_eyebrow[3][0], positions.right_eyebrow[3][1])
endShape();
//FEMALE NOSE
noFill();
stroke(0);
strokeWeight(0.03);
//same as the jawline if statement- decides which way the nose should be pointing
if (positions.nose_tip[2][0] < 0) {
beginShape();
vertex(positions.nose_bridge[1][0], positions.nose_bridge[1][1])
quadraticVertex(positions.nose_tip[1][0], positions.nose_tip[1][1] + .5, positions.nose_tip[4][0], positions.nose_tip[4][1])
endShape();
} else {
beginShape();
vertex(positions.nose_bridge[1][0], positions.nose_bridge[1][1])
quadraticVertex(positions.nose_tip[3][0], positions.nose_tip[3][1] + .5, positions.nose_tip[1][0], positions.nose_tip[1][1])
endShape();
}
} else {
////MALE FACE////
//MALE SHAPES
this.colourFillArray = [this.purple, this.pink, this.light_red, this.dark_red, this.orange, this.yellow, this.light_green, this.dark_green, this.dark_blue, this.light_blue, this.other_turq];
this.colourFill = random(this.colourFillArray);
noStroke();
fill(this.colourFill);
push();
//scales shapes to size of the face
scale(this.shapeScale);
rect(.75, -2.25, 2, 3.5);
rect(-2.25, -3.25, 2.5, 1.5);
rect(-.75, -2, 2, 2);
rect(-1.75, -1.25, 3, 3.5);
rect(-1.25, -2.75, 1, 5.5);
rect(0, -3.5, 1.5, 1.5);
//HAIRLINE
stroke(0);
strokeWeight(0.035);
line(-1.75, -1.75, -1.75, -2.9);
line(-1.9, -2.75, 1.5, -2.75);
noStroke();
pop();
//MALE MOUTH
if (this.mouth_OpenClose == 1) {
stroke(0);
noFill();
strokeWeight(0.03);
line(positions.bottom_lip[7][0], positions.bottom_lip[7][1], positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY);
line(positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
} else {
stroke(0);
fill(200, 200, 200, 100);
stroke(0);
strokeWeight(0.02);
triangle(positions.bottom_lip[7][0], positions.bottom_lip[7][1], positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
strokeWeight(0.03);
line(positions.bottom_lip[7][0], positions.bottom_lip[7][1], positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY);
line(positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
}
//MALE JAWLINE
stroke(0);
strokeWeight(0.035);
if (positions.nose_tip[2][0] < 0) {
line(positions.chin[8][0], positions.chin[8][1], positions.chin[12][0] + this.chinX, positions.chin[12][1] + this.chinY);
line(positions.chin[12][0] + this.chinX, positions.chin[12][1] + this.chinY, positions.chin[16][0], positions.chin[16][1]);
} else {
line(positions.chin[0][0], positions.chin[0][1], positions.chin[4][0] + this.chinX, positions.chin[4][1] + this.chinY);
line(positions.chin[4][0] + this.chinX, positions.chin[4][1] + this.chinY, positions.chin[8][0], positions.chin[8][1]);
}
//MALE EYEBROWS
stroke(0);
strokeWeight(0.02);
line(positions.left_eyebrow[1][0], positions.left_eyebrow[1][1], positions.right_eyebrow[3][0], positions.right_eyebrow[3][1]);
//MALE NOSE
noFill();
stroke(0);
strokeWeight(0.03);
if (positions.nose_tip[2][0] < 0) {
line(positions.nose_bridge[1][0], positions.nose_bridge[1][1], positions.nose_tip[1][0], positions.nose_tip[1][1]);
line(positions.nose_tip[1][0], positions.nose_tip[1][1], positions.nose_tip[3][0], positions.nose_tip[3][1])
} else {
line(positions.nose_bridge[1][0], positions.nose_bridge[1][1], positions.nose_tip[3][0], positions.nose_tip[3][1]);
line(positions.nose_tip[3][0], positions.nose_tip[3][1], positions.nose_tip[1][0], positions.nose_tip[1][1])
}
}
//EYES//
fill(240, 240, 240, 100);
stroke(0)
strokeWeight(0.025);
if (positions.nose_tip[2][0] < 0) {
rect(positions.left_eye[0][0] + this.eyesX, positions.left_eye[0][1], 1, this.eye_height)
ellipse(positions.right_eye[4][0] + this.eyesX, positions.right_eye[4][1], 1.25, .25 + this.eye_height);
} else {
rect(positions.left_eye[0][0] + this.eyesX, positions.left_eye[0][1], 1, this.eye_height)
ellipse(positions.right_eye[4][0] + this.eyesX, positions.right_eye[4][1], 1.25, .25 + this.eye_height);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.mouthX = map(settings[0], 0, 100, -1.25, 1.25);
this.mouthY = map(settings[1], 0, 100, -1.25, 1.25);
this.eyesX = map(settings[2], 0, 100, -1, 1);
this.eye_height = map(settings[3], 0, 100, 0, .75);
this.chinX = map(settings[4], 0, 100, -1.5, 1.5);
this.chinY = map(settings[5], 0, 100, -1.5, 1.5);
this.mouth_OpenClose = int(map(settings[6], 0, 100, 1, 3));
this.shapeScale = map(settings[7], 0, 100, .5, 1.25);
this.male_female = map(settings[8], 0, 100, 1, 3);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(3);
settings[0] = map(this.mouthX, -1.25, 1.25, 0, 100);
settings[1] = map(this.mouthY, -1.25, 1.25, 0, 100);
settings[2] = map(this.eyesX, -1, 1, 0, 100);
settings[3] = map(this.eye_height, 0, .75, 0, 100);
settings[4] = map(this.chinX, -1.5, 1.5, 0, 100);
settings[5] = map(this.chinY, -1.5, 1.5, 0, 100);
settings[6] = int(map(this.mouth_OpenClose, 1, 3, 0, 100));
settings[7] = map(this.shapeScale, .5, 1.25, 0, 100);
settings[8] = map(this.male_female, 1, 3, 0, 100);
return settings;
}
}
{
"000001": [
48,
40,
34,
22,
57,
50,
52,
49,
100
],
"000002": [
34,
66,
26,
50,
54,
68,
100,
34.99999999999999,
0
],
"000005": [
46.99999999999999,
33,
44,
28.999999999999996,
69,
82,
100,
38.99999999999999,
17.999999999999993
],
"000006": [
61,
40,
54,
34.99999999999999,
54,
69,
100,
30,
37.999999999999986
],
"000007": [
46.00000000000001,
43,
46,
51,
44,
69,
0,
54,
100
],
"000009": [
51,
52,
33,
47,
36.99999999999999,
51,
100,
66,
0
],
"000010": [
50,
57.99999999999999,
45,
22,
51,
66,
60,
40.00000000000001,
27
],
"000013": [
50,
44.00000000000001,
55.00000000000001,
23,
54,
62,
100,
73.99999999999999,
100
],
"000014": [
48,
53,
41,
40.00000000000001,
63,
68,
0,
52.99999999999999,
47
],
"000015": [
56.00000000000001,
34,
46,
7.000000000000001,
64,
71,
100,
62,
100
],
"000016": [
46.99999999999999,
45,
61,
27,
57.99999999999999,
53,
0,
56.99999999999999,
100
],
"000018": [
49.00000000000001,
53,
40,
25,
40.00000000000001,
56.99999999999999,
100,
38.00000000000001,
30.000000000000004
],
"000020": [
51,
32,
45,
9.000000000000002,
53,
47,
100,
46,
100
],
"000023": [
49.00000000000001,
45,
48,
16,
56.00000000000001,
53,
100,
51.000000000000014,
100
],
"000025": [
41,
41,
45,
23,
64,
47,
0,
62,
100
],
"000028": [
50,
64,
46,
23,
41,
87,
100,
51.000000000000014,
44.99999999999999
],
"000029": [
50,
49.00000000000001,
44,
31,
41,
48,
100,
54,
44.99999999999999
],
"000030": [
57.99999999999999,
38,
37,
34.99999999999999,
72.00000000000001,
72.00000000000001,
0,
61,
100
],
"000031": [
45,
56.99999999999999,
37,
16,
38.99999999999999,
60,
100,
54,
0
],
"000032": [
48,
27,
41,
36.99999999999999,
52,
62,
100,
61,
100
],
"000035": [
48,
42.00000000000001,
41,
38.99999999999999,
40.00000000000001,
46,
100,
47,
0
],
"000037": [
56.00000000000001,
34,
66,
28.000000000000004,
54,
52,
0,
61,
100
],
"000038": [
46.99999999999999,
44.00000000000001,
45,
23,
46,
47,
100,
69,
100
],
"000040": [
53,
55.00000000000001,
49,
30,
31,
59,
0,
62,
42.99999999999999
],
"000041": [
42.00000000000001,
41,
25,
21,
56.99999999999999,
48,
100,
65,
100
],
"000042": [
50,
60,
40,
36.00000000000001,
43,
57.99999999999999,
0,
46,
0
],
"000043": [
46.99999999999999,
63,
40,
33,
36.99999999999999,
53,
100,
46,
0
],
"000044": [
49.00000000000001,
51,
43,
25,
57.99999999999999,
50,
0,
36.99999999999999,
0
],
"000045": [
46.99999999999999,
63,
43,
17,
69.99999999999999,
52,
100,
36.99999999999999,
0
],
"000047": [
46.99999999999999,
56.99999999999999,
43,
12,
69.99999999999999,
64,
100,
45,
0
],
"000048": [
60,
40,
55.00000000000001,
10.000000000000002,
63,
72.00000000000001,
0,
38.99999999999999,
100
],
"000050": [
54,
43,
55.00000000000001,
21,
77.99999999999999,
77.99999999999999,
100,
47,
100
],
"000051": [
64,
46.99999999999999,
48,
41,
41,
72.00000000000001,
0,
82,
100
],
"000052": [
42.00000000000001,
45,
40,
30,
59,
57.99999999999999,
0,
64,
100
],
"000054": [
45,
64,
44,
16,
59,
67,
100,
44.000000000000014,
0
],
"000055": [
48,
42.00000000000001,
42,
18.000000000000004,
53,
55.00000000000001,
0,
60,
100
],
"000056": [
38,
48,
35,
14.000000000000002,
67,
77,
0,
36.99999999999999,
0
],
"000058": [
56.99999999999999,
51,
35,
26,
41,
53,
20,
36.99999999999999,
0
],
"000060": [
46.00000000000001,
45,
12,
16,
61,
34,
100,
34,
100
],
"000064": [
46.00000000000001,
48,
44,
14.000000000000002,
53,
60,
0,
47,
100
],
"000065": [
46.99999999999999,
45,
44,
21,
62,
56.99999999999999,
100,
55.000000000000014,
100
],
"000068": [
51,
49.00000000000001,
44,
24,
59,
53,
100,
46,
100
],
"000069": [
50,
37,
43,
36.00000000000001,
43,
54,
100,
56.99999999999999,
100
],
"000071": [
46.99999999999999,
53,
43,
36.00000000000001,
64,
73,
100,
43,
0
],
"000073": [
38,
46.99999999999999,
14.000000000000002,
21,
41,
85,
100,
48.99999999999999,
0
],
"000076": [
45,
49.00000000000001,
34,
14.000000000000002,
50,
61,
0,
48.99999999999999,
100
],
"000077": [
49.00000000000001,
46.00000000000001,
48,
28.999999999999996,
69.99999999999999,
64,
0,
38.00000000000001,
0
],
"000078": [
42.00000000000001,
44.00000000000001,
40,
30,
46,
60,
0,
44.000000000000014,
0
],
"000079": [
46.00000000000001,
45,
48,
30,
30,
84,
0,
56.99999999999999,
100
],
"000080": [
44.00000000000001,
43,
37,
22,
42,
28.999999999999996,
0,
56.00000000000001,
100
],
"000081": [
52,
48,
52,
22,
43,
54,
100,
61,
100
],
"000083": [
48,
56.00000000000001,
43,
21,
56.00000000000001,
82,
0,
50,
0
],
"000085": [
41,
55.00000000000001,
43,
46,
65,
73,
0,
50,
0
],
"000086": [
30,
33,
37,
40.00000000000001,
34.99999999999999,
52,
0,
55.000000000000014,
0
],
"000088": [
40,
42.00000000000001,
50,
41,
73,
61,
100,
44.000000000000014,
0
],
"000091": [
44.00000000000001,
41,
41,
13,
56.99999999999999,
66,
0,
55.000000000000014,
100
],
"000092": [
39,
53,
41,
22,
66,
69,
0,
45,
0
],
"000096": [
54,
32,
47,
28.000000000000004,
38.99999999999999,
66,
0,
30.99999999999999,
0
],
"000097": [
46.00000000000001,
31,
42,
25,
68,
51,
100,
36.99999999999999,
0
],
"000099": [
53,
55.00000000000001,
42,
16,
52,
79,
100,
46,
0
],
"000100": [
63,
48,
56.99999999999999,
21,
38.00000000000001,
46,
30,
43,
0
],
"000103": [
41,
38,
44,
23,
43,
69.99999999999999,
40,
34,
0
],
"000104": [
55.00000000000001,
46.00000000000001,
48,
16,
31,
80.00000000000001,
100,
46,
100
],
"000106": [
61,
55.00000000000001,
43,
26,
33,
42,
100,
47,
0
],
"000108": [
43,
55.00000000000001,
43,
36.99999999999999,
55.00000000000001,
63,
100,
40.00000000000001,
0
],
"000109": [
49.00000000000001,
38,
43,
24,
56.99999999999999,
56.99999999999999,
100,
55.000000000000014,
100
],
"000110": [
46.00000000000001,
50,
43,
23,
38.00000000000001,
55.00000000000001,
100,
54,
49
],
"000111": [
36,
54,
48,
13,
61,
57.99999999999999,
100,
48,
0
],
"000114": [
50,
44.00000000000001,
48,
46,
56.00000000000001,
56.99999999999999,
100,
55.000000000000014,
100
],
"000115": [
50,
42.00000000000001,
42,
31,
61,
53,
10,
51.000000000000014,
100
],
"000116": [
46.00000000000001,
44.00000000000001,
42,
27,
50,
53,
100,
50,
100
],
"000117": [
57.99999999999999,
46.00000000000001,
42,
34.99999999999999,
50,
77,
100,
50,
0
],
"000118": [
65,
46.99999999999999,
33,
38.99999999999999,
44,
60,
40,
51.000000000000014,
0
],
"000121": [
46.00000000000001,
48,
43,
34.99999999999999,
33,
64,
50,
48.99999999999999,
0
],
"000122": [
46.00000000000001,
53,
43,
36.99999999999999,
69,
69.99999999999999,
100,
40.00000000000001,
0
],
"000125": [
57.99999999999999,
41,
46,
28.000000000000004,
55.00000000000001,
53,
0,
61,
100
],
"000126": [
38,
46.00000000000001,
54,
28.000000000000004,
66,
69,
100,
48,
0
],
"000129": [
44.00000000000001,
46.00000000000001,
46,
18.000000000000004,
59,
55.00000000000001,
100,
48,
100
],
"000131": [
34,
50,
66,
25,
69.99999999999999,
75,
100,
36.99999999999999,
0
],
"000132": [
46.99999999999999,
56.00000000000001,
40,
17,
63,
48,
100,
36.99999999999999,
0
],
"000133": [
48,
55.00000000000001,
45,
25,
36.00000000000001,
54,
100,
46,
0
],
"000134": [
41,
39,
18,
14.000000000000002,
53,
64,
100,
51.000000000000014,
100
],
"000135": [
53,
42.00000000000001,
56.99999999999999,
17,
49,
46,
0,
50,
100
],
"000137": [
51,
36,
65,
10.000000000000002,
46,
54,
100,
33.00000000000001,
100
],
"000140": [
61,
37,
48,
38.99999999999999,
46,
60,
0,
34.99999999999999,
0
],
"000142": [
61,
31,
48,
19.000000000000004,
61,
72.00000000000001,
100,
43,
0
],
"000143": [
61,
41,
41,
21,
59,
63,
100,
55.000000000000014,
100
],
"000145": [
55.00000000000001,
59,
49,
10.000000000000002,
40.00000000000001,
61,
100,
46,
0
],
"000146": [
68,
46.99999999999999,
66,
24,
30,
71,
100,
41,
0
],
"000147": [
62,
49.00000000000001,
51,
36.99999999999999,
38.99999999999999,
61,
100,
47,
0
],
"000148": [
54,
43,
70,
18.000000000000004,
54,
71,
100,
40.00000000000001,
0
],
"000150": [
52,
43,
48,
24,
50,
38.00000000000001,
10,
48,
100
],
"000151": [
45,
56.00000000000001,
43,
12,
36.00000000000001,
52,
100,
40.00000000000001,
0
],
"000152": [
48,
44.00000000000001,
44,
16,
54,
50,
100,
51.000000000000014,
100
],
"000153": [
48,
40,
44,
21,
42,
36.99999999999999,
100,
48,
100
],
"000155": [
41,
56.99999999999999,
44,
32,
63,
63,
100,
46,
0
],
"000156": [
37,
51,
50,
26,
66,
68,
100,
46,
0
],
"000157": [
46.99999999999999,
42.00000000000001,
44,
27,
28.000000000000004,
62,
70,
45,
0
],
"000160": [
43,
42.00000000000001,
40,
34.99999999999999,
52,
50,
80,
56.99999999999999,
100
],
"000161": [
48,
52,
35,
17,
71,
56.99999999999999,
100,
38.00000000000001,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 4;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i = 0; i < s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len, sum_y / s_len];
}
// This where you define your own face object
function McSweeneyFace() {
//frameRate(1);
// these are state variables for a face
// (your variables should be different!)
this.num_eyes = 2; // can be either 1 (cyclops) or 2 (two eyes)
this.eye_shift = -1; // range is -10 to 10
this.mouth_value = 4; // range is 0.5 to 8
//variables between 0-100;
this.jaw = 50;
this.eyes = 50;
this.cheek1 = 50;
this.mouth = 50;
this.cheek2 = 50;
this.colour_picker = 80;
this.horn_size = 50;
this.jaw_ang = 50;
this.eye_evil = 50;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if (i < segment.length - 1) {
let nx = segment[i + 1][0];
let ny = segment[i + 1][1];
line(px, py, nx, ny);
} else if (do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
// fill(255);
// ellipse(0, 0, 4);
// return;
/*
// draw segments of face using points
fill(128);
stroke(128);
this.draw_segment(positions.chin);
fill(100, 0, 100);
stroke(100, 0, 100);
this.draw_segment(positions.nose_bridge);
this.draw_segment(positions.nose_tip);
strokeWeight(0.03);
fill(200, 0, 0);
stroke(200, 0, 0);
this.draw_segment(positions.top_lip);
this.draw_segment(positions.bottom_lip);
fill(255);
stroke(255);
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye); */
//---------------------------------------------------------------------------
//scale(4/10);
let colour_pic = int(map(this.colour_picker, 0, 100, 1, 3))
let colour = [];
let strokeCol = [];
if (colour_pic == 1) {
colour = [165, 146, 126];
strokeCol = [20];
} else if (colour_pic == 2) {
colour = [227, 218, 201];
strokeCol = [150];
} else if (colour_pic == 3) {
colour = [222, 202, 176];
strokeCol = [255];
}
// head
let cheek = 5;
let cheek_dist = 4;
let cheek_out = 5.5;
let cheek_height = map(this.cheek1, 0, 100, -1.5, -0.7, true);
let cheek_end_x = 4;
let cheek_end_y = 2;
var jaw_width = map(this.jaw, 0, 100, 3, 5);
var jaw_height = 3.5;
var chin_width = 1.5;
var chin_height = 6;
let mouthweight = 0.1;
let genstroke = 0.15;
let eyeposL = segment_average(positions.left_eye);
let eyeposR = segment_average(positions.right_eye);
let eyesizeL = (positions.left_eye[3][0] - positions.left_eye[0][0]);
let eyesizeR = (positions.right_eye[3][0] - positions.right_eye[0][0]);
let eyesizeRV = ((positions.right_eye[2][1] - positions.right_eye[4][1])) * 3;
let eyesizeLV = ((positions.right_eye[1][1] - positions.right_eye[5][1])) * 3;
//fill(colour);
stroke(strokeCol);
//stroke(145,136,116);
strokeCap(ROUND);
smooth();
strokeJoin(ROUND);
strokeWeight(genstroke);
//Crainium ------------------------------------------------------
//Horns ------------------------------------------------------
push();
noFill();
let nosl = positions.nose_bridge[0][1] - positions.nose_bridge[3][1];
let hornpos = ((eyeposR[1] + eyeposL[1])/2) + (nosl)
let horn_height =(map(this.horn_size, 0, 100, 0.75, 2));
//Fill -----
push();
fill(strokeCol);
stroke(strokeCol);
strokeWeight(genstroke/3)
triangle(positions.right_eyebrow[1][0],hornpos*1.1, positions.right_eyebrow[3][0],hornpos,
positions.chin[12][0]*0.95, hornpos + (nosl*horn_height ) );
triangle(positions.left_eyebrow[1][0],hornpos, positions.left_eyebrow[3][0],hornpos*1.1,
positions.chin[4][0]*0.95, (hornpos + (nosl*horn_height)) );
/*//if (horn_desc ==)
fill(255,0,0);
stroke(255,0,0);
triangle(positions.right_eyebrow[1][0]*1.4,hornpos*1.9, positions.right_eyebrow[3][0],hornpos*1.8,
positions.chin[12][0]*0.95, hornpos + (nosl*horn_height ) );
triangle(positions.left_eyebrow[1][0],hornpos*1.8, positions.left_eyebrow[3][0]*1.4,hornpos*1.9,
positions.chin[4][0]*0.95, (hornpos + (nosl*horn_height)) );
*/
pop();
//Top Horn --------
noFill();
beginShape();
curveVertex(positions.right_eyebrow[3][0]*0.8, eyeposR[1]); //
curveVertex(positions.right_eyebrow[3][0],hornpos);
curveVertex(positions.chin[12][0], hornpos + (nosl*horn_height ));
curveVertex(positions.chin[12][0]*1.5, hornpos + (nosl*horn_height)); //
endShape();
beginShape();
curveVertex(positions.right_eyebrow[1][0]*0.8, eyeposR[1]); //
curveVertex(positions.right_eyebrow[1][0],hornpos*1.1);
curveVertex(positions.chin[12][0], hornpos + (nosl*horn_height));
curveVertex(positions.chin[12][0]*2, hornpos + (nosl*horn_height)); //
endShape();
//Bottom horn ----
beginShape();
curveVertex(positions.right_eyebrow[1][0]*0.6,hornpos*1.5); //
curveVertex(positions.right_eyebrow[1][0],hornpos*1.1);
curveVertex(positions.right_eyebrow[3][0],hornpos);
curveVertex(positions.right_eyebrow[3][0]*1.4,hornpos*1.4); //
endShape();
//Left
beginShape();
curveVertex(positions.left_eyebrow[1][0]*0.8, eyeposL[1]); //
curveVertex(positions.left_eyebrow[1][0],hornpos);
curveVertex(positions.chin[4][0], hornpos + (nosl*horn_height));
curveVertex(positions.chin[4][0]*1.5, hornpos + (nosl*horn_height)); //
endShape();
beginShape();
curveVertex(positions.left_eyebrow[3][0]*0.8 , eyeposL[1]); //
curveVertex(positions.left_eyebrow[3][0],hornpos*1.1);
curveVertex(positions.chin[4][0], hornpos + (nosl*horn_height) );
curveVertex(positions.chin[4][0]*2, hornpos + (nosl*horn_height)); //
endShape();
//Bottom horn ----
beginShape();
curveVertex(positions.left_eyebrow[1][0]*1.4,hornpos*1.4); //
curveVertex(positions.left_eyebrow[1][0],hornpos);
curveVertex(positions.left_eyebrow[3][0],hornpos*1.1);
curveVertex(positions.left_eyebrow[3][0]*0.6,hornpos*1.5); //
endShape();
pop();
//Chin
//Chin
push();
let jaw_stroke = 0.3;
strokeWeight(genstroke);
noFill();
let jawrightx = (positions.chin[12][0] * 1.2)
let jawrighty = (positions.chin[12][1] * 1.1)
let jawleftx = (positions.chin[4][0] * 1.2)
let jawlefty = (positions.chin[4][1] * 1.1)
let jaw_angle = int(map(this.jaw_ang, 0, 100, 1, 2));
beginShape();
curveVertex(jawrightx + 1 * jaw_angle, jawrighty * jaw_angle);
curveVertex(jawrightx, jawrighty);
curveVertex(positions.chin[9][0], positions.chin[8][1]);
curveVertex(positions.chin[7][0], positions.chin[8][1]);
curveVertex(jawleftx, jawlefty);
curveVertex(jawleftx - 1* jaw_angle, jawlefty * jaw_angle);
endShape();
//Jaw Side Left ----
beginShape();
curveVertex(positions.chin[2][0] - 1, positions.chin[2][1] - 1);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(jawleftx, jawlefty);
curveVertex(jawleftx - 1, jawlefty + 1);
endShape();
//Jaw Side Right ----
beginShape();
curveVertex(positions.chin[14][0] + 1, positions.chin[14][1] - 1);
curveVertex(positions.chin[14][0], positions.chin[14][1]);
curveVertex(jawrightx, jawrighty);
curveVertex(jawrightx + 1, jawrighty + 1);
endShape();
pop();
//Cheeks-------------------------
strokeWeight(genstroke);
noFill();
let cheekinnerY = (positions.chin[14][1] - positions.chin[15][1]) + positions.chin[15][1]
let cheekinnerX = (positions.chin[14][0] - (positions.chin[14][0] - positions.chin[12][0]));
beginShape();
curveVertex(positions.chin[16][0] - 1, positions.chin[16][1] - 1);
curveVertex(positions.chin[16][0] * 0.9, positions.chin[16][1]);
curveVertex(positions.chin[15][0] * 1.1, positions.chin[15][1]);
curveVertex(positions.chin[14][0] * 1.05, positions.chin[14][1]);
curveVertex(cheekinnerX, cheekinnerY);
curveVertex(cheekinnerX - 1, cheekinnerY + 0.5);
endShape();
let cheekinnerLY = (positions.chin[14][1] - positions.chin[1][1]) + positions.chin[1][1]
let cheekinnerLX = (positions.chin[2][0] - (positions.chin[2][0] - positions.chin[4][0]));
beginShape();
curveVertex(positions.chin[0][0] + 1, positions.chin[0][1] - 1);
curveVertex(positions.chin[0][0] * 0.9, positions.chin[0][1]);
curveVertex(positions.chin[1][0] * 1.1, positions.chin[1][1]);
curveVertex(positions.chin[2][0] * 1.05, positions.chin[2][1]);
curveVertex(cheekinnerLX, cheekinnerLY);
curveVertex(cheekinnerLX + 1, cheekinnerLY + 0.5);
endShape();
//Eyes-----------------------------------------------
push();
let eye_evil2 = map(this.eye_evil,0,100,0,3);
let smalleyeS = 4;
fill(200/eye_evil2,0,0);
strokeWeight(genstroke);
stroke('black');
ellipse(eyeposR[0],eyeposR[1], eyesizeR, eyesizeRV);
ellipse(eyeposL[0],eyeposL[1], eyesizeL, eyesizeLV);
noStroke();
fill(255,33*eye_evil2);
ellipse(eyeposR[0],eyeposR[1], eyesizeR/smalleyeS, eyesizeRV/smalleyeS);
ellipse(eyeposL[0],eyeposL[1], eyesizeL/smalleyeS, eyesizeLV/smalleyeS);
pop();
//mouth ------------------------------
let mouthcurveRy = positions.bottom_lip[0][1] - (positions.bottom_lip[10][1] - positions.bottom_lip[0][1])*3
let mouthcurveLy = positions.bottom_lip[6][1] - (positions.bottom_lip[8][1] - positions.bottom_lip[6][1])*3
let mouthfracLX = (positions.bottom_lip[2][0] + positions.top_lip[4][0]) / 2;
let mouthfracRX = (positions.bottom_lip[4][0] + positions.top_lip[2][0]) / 2;
let mouthfracRX2 = (positions.bottom_lip[6][0] + mouthfracRX) / 2
let mouthfracLX2 = (positions.bottom_lip[0][0] + mouthfracLX) / 2
let mouthheight = (positions.bottom_lip[3][1] - positions.top_lip[3][1])/2;
let mouthcenterheight = positions.bottom_lip[9][1] - ((positions.bottom_lip[9][1] - positions.top_lip[9][1])/2);
push();
noFill();
let check = 6;
translate(0,mouthweight*1/3)
stroke(200,0,0)
strokeWeight(mouthweight)
beginShape();
curveVertex(positions.bottom_lip[0][0] + 0.5, mouthcurveRy);
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
curveVertex(positions.bottom_lip[6][0], positions.bottom_lip[6][1]);
curveVertex(positions.bottom_lip[6][0] - 0.5, mouthcurveLy);
endShape();
line(mouthfracRX,mouthcenterheight-mouthheight, mouthfracRX, mouthcenterheight+mouthheight);
line(mouthfracRX2,mouthcenterheight-mouthheight, mouthfracRX2, mouthcenterheight+mouthheight);
line(mouthfracLX,mouthcenterheight-mouthheight, mouthfracLX, mouthcenterheight+mouthheight);
line(mouthfracLX2,mouthcenterheight-mouthheight, mouthfracLX2, mouthcenterheight+mouthheight);
pop();
//inner -----
push();
strokeWeight(mouthweight);
stroke(0);
beginShape();
curveVertex(positions.bottom_lip[0][0]+0.5, mouthcurveRy);
curveVertex(positions.bottom_lip[0][0],positions.bottom_lip[0][1]);
curveVertex(positions.bottom_lip[6][0], positions.bottom_lip[6][1]);
curveVertex(positions.bottom_lip[6][0]-0.5, mouthcurveLy);
endShape();
line(mouthfracRX,mouthcenterheight-mouthheight, mouthfracRX, mouthcenterheight+mouthheight);
line(mouthfracRX2,mouthcenterheight-mouthheight, mouthfracRX2, mouthcenterheight+mouthheight);
line(mouthfracLX,mouthcenterheight-mouthheight, mouthfracLX, mouthcenterheight+mouthheight);
line(mouthfracLX2,mouthcenterheight-mouthheight, mouthfracLX2, mouthcenterheight+mouthheight);
pop();
//Nose -------------
push();
fill(colour);
//fill(strokeCol);
strokeWeight(genstroke);
let nose_width = map(jaw_width, 3, 5, 0.5, 1);
let nose_top = positions.nose_bridge[1][1] - positions.nose_bridge[0][1];
triangle(positions.nose_bridge[0][0], positions.nose_bridge[1][1] - nose_top / 2, positions.nose_tip[0][0], positions.nose_tip[0][1], positions.nose_tip[4][0], positions.nose_tip[4][1])
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.colour_picker = int(map(settings[0], 0, 100, 0, 100));
this.horn_size = map(settings[1], 0, 100, 0, 100);
this.jaw_ang = map(settings[2], 0, 100, 0, 100);
this.eye_evil = map(settings[3], 0, 100, 0, 100);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(0);
settings[0] = map(this.colour_picker, 0, 100, 0, 100);
settings[1] = map(this.horn_size, 0,100, 0, 100);
settings[2] = map(this.jaw_ang, 0, 100, 0, 100);
settings[3] = map(this.eye_evil, 0, 100, 0, 100);
return settings;
}
}
{
"000001": [
0,
0,
100,
0
],
"000002": [
0,
33,
100,
100
],
"000005": [
70,
53,
100,
54
],
"000006": [
78,
41,
100,
79
],
"000007": [
68,
77,
10,
79
],
"000009": [
0,
22,
100,
50
],
"000010": [
0,
0,
100,
0
],
"000013": [
0,
85,
0,
79
],
"000014": [
76,
19,
100,
32
],
"000015": [
0,
93,
0,
78
],
"000016": [
0,
77,
0,
30
],
"000018": [
0,
22,
100,
54
],
"000020": [
0,
62,
0,
22
],
"000023": [
0,
79,
0,
18
],
"000025": [
0,
67,
0,
100
],
"000028": [
56.99999999999999,
22,
100,
73
],
"000029": [
0,
0,
100,
16
],
"000030": [
0,
56.00000000000001,
0,
37
],
"000031": [
0,
37,
100,
18
],
"000032": [
0,
57.99999999999999,
0,
87
],
"000035": [
0,
57.99999999999999,
100,
65
],
"000037": [
77,
100,
0,
66
],
"000038": [
0,
76,
0,
33
],
"000040": [
54,
0,
100,
0
],
"000041": [
54,
73,
0,
24
],
"000042": [
0,
34,
100,
48
],
"000043": [
0,
13,
100,
30
],
"000044": [
94,
13,
100,
30
],
"000045": [
0,
10,
100,
7.000000000000001
],
"000047": [
0,
10,
100,
44
],
"000048": [
0,
69,
0,
71
],
"000050": [
53,
84,
0,
39
],
"000051": [
53,
69,
0,
100
],
"000052": [
0,
87,
0,
39
],
"000054": [
0,
87,
1,
54
],
"000055": [
56.00000000000001,
87,
0,
69
],
"000056": [
0,
56.99999999999999,
0,
84
],
"000058": [
0,
8,
100,
70
],
"000060": [
83,
68,
0,
62
],
"000064": [
0,
67,
0,
62
],
"000065": [
56.99999999999999,
78,
0,
91
],
"000068": [
0,
89,
0,
100
],
"000069": [
0,
75,
0,
100
],
"000071": [
0,
28.000000000000004,
100,
100
],
"000073": [
0,
0,
100,
0
],
"000076": [
0,
100,
0,
0
],
"000077": [
0,
0,
100,
0
],
"000078": [
0,
3,
100,
62
],
"000079": [
0,
81,
0,
62
],
"000080": [
0,
100,
0,
39
],
"000081": [
60,
90,
0,
60
],
"000083": [
0,
12,
100,
60
],
"000085": [
0,
0,
100,
0
],
"000086": [
0,
0,
100,
0
],
"000088": [
64,
0,
100,
12
],
"000091": [
0,
89,
0,
26
],
"000092": [
0,
12,
100,
14.000000000000002
],
"000096": [
0,
0,
100,
26
],
"000097": [
0,
0,
100,
0
],
"000099": [
0,
7.000000000000001,
100,
28.999999999999996
],
"000100": [
0,
31,
100,
37
],
"000103": [
0,
0,
100,
18
],
"000104": [
0,
71,
0,
32
],
"000106": [
0,
10,
100,
14.000000000000002
],
"000108": [
0,
10,
100,
14.000000000000002
],
"000109": [
0,
68,
0,
46
],
"000110": [
0,
4,
100,
16
],
"000111": [
75,
15,
100,
22
],
"000114": [
0,
75,
0,
52
],
"000115": [
0,
100,
0,
76
],
"000116": [
0,
84,
0,
25
],
"000117": [
80,
19,
100,
16
],
"000118": [
64,
0,
100,
0
],
"000121": [
64,
6,
100,
7.000000000000001
],
"000122": [
0,
13,
100,
100
],
"000125": [
0,
81,
0,
64
],
"000126": [
0,
0,
100,
0
],
"000129": [
0,
82,
0,
83
],
"000131": [
66,
10,
100,
31
],
"000132": [
79,
10,
100,
31
],
"000133": [
0,
4,
100,
14.000000000000002
],
"000134": [
84,
77,
0,
62
],
"000135": [
67,
63,
0,
35
],
"000137": [
0,
70,
0,
35
],
"000140": [
0,
0,
100,
13
],
"000142": [
0,
6,
100,
48
],
"000143": [
0,
81,
0,
79
],
"000145": [
0,
4,
100,
18
],
"000146": [
0,
0,
100,
0
],
"000147": [
0,
0,
100,
0
],
"000148": [
0,
9,
100,
38
],
"000150": [
0,
67,
0,
77
],
"000151": [
66,
8,
100,
22
],
"000152": [
0,
68,
0,
11
],
"000153": [
0,
85,
0,
25
],
"000155": [
0,
0,
100,
25
],
"000156": [
0,
8,
100,
41
],
"000157": [
0,
0,
100,
9
],
"000160": [
0,
83,
0,
60
],
"000161": [
0,
10,
100,
12
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 7;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
let cluster = new Cluster();
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i = 0; i < s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len, sum_y / s_len];
}
// This where you define your own face object
function NgFace() {
// these are state variables for a face
// (your variables should be different!)
this.numOfSq = 7;
this.numOfTri = focusedRandom(0, 15);
this.numOfEll = 7;
this.hairColorSelector = 5;
this.faceColorSelector = 5;
this.eyeColorSelector = 5;
this.eye_shift = -1;
this.makeUp = 0;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
//
this.draw_segment = function (segment, scaleX, scaleY) {
for (let i = 0; i < segment.length; i += 1) {
let px = segment[i][0];
let py = segment[i][1];
push()
translate(px, py);
scale(scaleX, scaleY);
rotate(focusedRandom(10, 350));
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function (positions) {
//Colour initialization
let faceColor = 0;
let faceShad = 0;
let hairColor = 0;
let eyeColor = 0;
let eyeBallColor = 255;
let mouthColor = 255;
//Hair colour range using lerpColor() function
let fromHair = color(0, 0, 0);
let toHair = color(252, 226, 91);
let interHair = lerpColor(fromHair, toHair, this.hairColorSelector);
//Face colour range using lerpColor() function
let fromFace = color(105, 64, 29);
let toFace = color(255, 219, 172);
let interFace = lerpColor(fromFace, toFace, this.faceColorSelector);
//FaceShad colour range using lerpColor() function
let fromFaceShad = color(64, 39, 17);
let toFaceShad = color(227, 195, 154);
let interFaceShad = lerpColor(fromFaceShad, toFaceShad, this.faceColorSelector);
//Eye colour range using lerpColor() function
let fromEye = color(0, 0, 0);
let toEye = color(0, 255, 247);
let interEye = lerpColor(fromEye, toEye, this.eyeColorSelector);
//Shared Variable
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
let top_mouth_pos = segment_average(positions.top_lip);
let bottom_mouth_pos = segment_average(positions.bottom_lip);
let avgBrowLine = (positions.left_eyebrow[2][1] + positions.right_eyebrow[2][1]) / 2
const makeupThreshold = 0.475;
noStroke()
//face
let faceback_midpt_x = ((positions.chin[16][0] - positions.chin[0][0]) / 2) + positions.chin[0][0];
let faceback_midpt_y = ((positions.chin[8][1] - avgBrowLine) / 2) + avgBrowLine;
let faceback_height = dist(positions.chin[8][0], avgBrowLine, positions.chin[8][0], positions.chin[8][1]);
let faceback_y_scale = map(faceback_height, 0.01, 3.78, 0.01, 1.85);
let faceback_width = dist(positions.chin[0][0], positions.chin[0][1], positions.chin[16][0], positions.chin[16][1]);
let faceback_x_scale = map(faceback_width, 0.01, 3.31, 0.1, 1.25);
//Cheeks to show face direction
push()
translate(faceback_midpt_x + 0, faceback_midpt_y - 0.55);
scale(faceback_x_scale, faceback_y_scale);
fill(interFaceShad);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop()
let faceMidPtX = ((right_eye_pos[0] - left_eye_pos[0]) / 2) + left_eye_pos[0];
let faceMidPtY = ((positions.chin[8][1] - avgBrowLine) / 2) + avgBrowLine;
let face_height = dist(positions.chin[8][0], avgBrowLine, positions.chin[8][0], positions.chin[8][1]);
let face_y_scale = map(face_height, 0.01, 3.5, 0.01, 1.3);
let face_width = dist(left_eye_pos[0], left_eye_pos[1], right_eye_pos[0], right_eye_pos[1]);
let face_x_scale = map(face_width, 0.01, 1.4, 0.1, 0.8);
push()
fill(interFace)
translate(faceMidPtX, faceMidPtY + 0.1);
scale(face_x_scale, face_y_scale);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);//Lower face
translate(0, -1);
scale(1.2, 1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);//Upper face
pop()
//eyeball
//Eye shadow
if (this.makeUp > makeupThreshold) {
fill(50, 50);
//Left Eye
push();
translate(left_eye_pos[0], left_eye_pos[1] - 0.1);
scale(0.2, 0.1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
//Right Eye
push();
translate(right_eye_pos[0], right_eye_pos[1] - 0.1);
scale(0.2, 0.1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
}
//Eyes
fill(255);
push();
translate(left_eye_pos[0], left_eye_pos[1]);
scale(0.2, 0.1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
push();
translate(right_eye_pos[0], right_eye_pos[1]);
scale(0.2, 0.1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
//eyebrow
fill(interHair);
//Left Eyebrow
for (let j = 0; j < positions.left_eyebrow.length - 1; j++) {
let v1 = createVector(positions.left_eyebrow[j][0], positions.left_eyebrow[j][1]);
let v2 = createVector(positions.left_eyebrow[j + 1][0], positions.left_eyebrow[j + 1][1]);
let angleBetweenL = v1.angleBetween(v2);
push();
translate(positions.left_eyebrow[j][0], positions.left_eyebrow[j][1]);
rotate(-angleBetweenL);
scale(0.15, 0.05);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
}
//Right Eyebrow
for (let k = 0; k < positions.right_eyebrow.length - 1; k++) {
let v3 = createVector(positions.right_eyebrow[k][0], positions.right_eyebrow[k][1]);
let v4 = createVector(positions.right_eyebrow[k + 1][0], positions.right_eyebrow[k + 1][1]);
let angleBetweenR = v3.angleBetween(v4);
push();
translate(positions.right_eyebrow[k][0], positions.right_eyebrow[k][1]);
rotate(angleBetweenR);
scale(0.15, 0.05);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop()
}
// pupils
let curEyeShift = 0.04 * this.eye_shift;
fill(interEye);
//Left pupil
push()
translate(left_eye_pos[0] + curEyeShift, left_eye_pos[1]);
scale(0.07);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
//Right pupil
push();
translate(right_eye_pos[0] + curEyeShift, right_eye_pos[1]);
scale(0.07);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
//mouth
let mouth_midpt_y = ((positions.bottom_lip[9][1] - positions.top_lip[9][1]) / 2) + positions.top_lip[9][1];
let mouth_midpt_x = ((positions.top_lip[6][0] - positions.top_lip[0][0]) / 2) + positions.top_lip[0][0];
let mouth_height = dist(positions.top_lip[9][0], positions.top_lip[9][1], positions.bottom_lip[9][0], positions.bottom_lip[9][1]);
let mouth_y_scale = map(mouth_height, 0.1, 0.35, 0.005, 0.1);
let mouth_width = dist(positions.top_lip[0][0], positions.top_lip[0][1], positions.top_lip[6][0], positions.top_lip[6][1]);
let mouth_x_scale = map(mouth_width, 0.01, 1.5, 0.01, 0.35);
//Turn mouth black when it is "closed"
if (mouth_height <= 0.1) {
mouthColor = 0;
}
//lipstick
if (this.makeUp > makeupThreshold) {
push()
translate(mouth_midpt_x, mouth_midpt_y);
scale(mouth_x_scale + 0.05, mouth_y_scale + 0.05);
fill(235, 64, 52);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop()
}
push()
translate(mouth_midpt_x, mouth_midpt_y);
scale(mouth_x_scale, mouth_y_scale);
fill(mouthColor);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop()
//nose
blendMode(MULTIPLY)
fill(100, 0, 100);
let noseq1 = color(150);
let noseq2 = color(50);
if (positions.nose_bridge[3][0] <= positions.nose_tip[2][0]) {
noseq1 = color(50);
noseq2 = color(150);
}
fill(noseq1);
beginShape();
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]);
vertex(positions.nose_tip[0][0], positions.nose_tip[0][1]);
vertex(positions.nose_tip[2][0], positions.nose_tip[2][1]);
vertex(positions.nose_bridge[3][0], positions.nose_bridge[3][1]);
endShape(CLOSE);
fill(noseq2);
beginShape();
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]);
vertex(positions.nose_bridge[3][0], positions.nose_bridge[3][1]);
vertex(positions.nose_tip[2][0], positions.nose_tip[2][1]);
vertex(positions.nose_tip[4][0], positions.nose_tip[4][1]);
endShape(CLOSE);
//Blush
if (this.makeUp > makeupThreshold) {
push();
fill(255, 233, 232, 20);
translate(left_eye_pos[0], positions.nose_bridge[3][1] + 0.2);
scale(0.3, 0.5);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
push();
fill(255, 233, 232, 15);
translate(right_eye_pos[0], positions.nose_bridge[3][1] + 0.2);
scale(0.3, 0.5);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function (settings) {
this.faceColorSelector = map(settings[0], 0, 100, 0, 1);
this.eye_shift = map(settings[1], 0, 100, -4, 4);
this.eyeColorSelector = map(settings[2], 0, 100, 0, 1);
this.hairColorSelector = map(settings[3], 0, 100, 0, 1);
this.makeUp = map(settings[4], 0, 100, 0, 1);
this.numOfSq = int(map(settings[5], 0, 100, 0, 15));
this.numOfEll = int(map(settings[6], 0, 100, 0, 15));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function () {
let settings = new Array(6)
settings[0] = map(this.faceColorSelector, 0, 1, 0, 100);
settings[1] = map(this.eye_shift, -4, 4, 0, 100);
settings[2] = map(this.eyeColorSelector, 0, 1, 0, 100);
settings[3] = map(this.hairColorSelector, 0, 1, 0, 100);
settings[4] = map(this.makeUp, 0, 1, 0, 100);
settings[5] = map(this.numOfSq, 0, 15, 0, 100);
settings[6] = map(this.numOfEll, 0, 15, 0, 100);
return settings;
}
}
function Cluster() {
this.arrayXSq = [];
this.arrayYSq = [];
this.arraySSq = [];
this.arrayXTri = [];
this.arrayYTri = [];
this.arraySTri = [];
this.arrayXEll = [];
this.arrayYEll = [];
this.arraySEll = [];
for (let i = 0; i < 20; i++) {
this.xPosSq = focusedRandom(-3, 3) * 0.4;
this.yPosSq = focusedRandom(-3, 3) * 0.4;
this.sSizeSq = focusedRandom(4, 7) * 0.3;
this.arrayXSq.push(this.xPosSq);
this.arrayYSq.push(this.yPosSq);
this.arraySSq.push(this.sSizeSq);
this.xPosTri = focusedRandom(-3, 3) * 0.4;
this.yPosTri = focusedRandom(-3, 3) * 0.4;
this.sSizeTri = focusedRandom(4, 7) * 0.2;
this.arrayXTri.push(this.xPosTri);
this.arrayYTri.push(this.yPosTri);
this.arraySTri.push(this.sSizeTri);
this.xPosEll = focusedRandom(-3, 3) * 0.4;
this.yPosEll = focusedRandom(-3, 3) * 0.4;
this.sSizeEll = focusedRandom(4, 7) * 0.3;
this.arrayXEll.push(this.xPosEll);
this.arrayYEll.push(this.yPosEll);
this.arraySEll.push(this.sSizeEll);
}
this.draw = function (testValue1, testValue2, testValue3) {
rectMode(CENTER);
noStroke();
beginShape();
for (let j = 0; j < testValue1; j++) {
let x = this.arrayXSq[j];
let y = this.arrayYSq[j];
if (x < 0 && y < 0) {
x += ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
} else if (x < 0 && y > 0) {
x += ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y > 0) {
x -= ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y < 0) {
x -= ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
}
push();
translate(x, y);
//vertex(x, y);
square(0, 0, this.arraySSq[j]);
pop();
}
endShape(CLOSE);
beginShape();
for (let k = 0; k < testValue2; k++) {
let x = this.arrayXTri[k];
let y = this.arrayYTri[k];
if (x < 0 && y < 0) {
x += ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
} else if (x < 0 && y > 0) {
x += ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y > 0) {
x -= ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y < 0) {
x -= ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
}
push();
translate(x, y);
//vertex(x, y);
cusTriangle(0, 0, this.arraySTri[k]);
pop();
}
endShape(CLOSE);
beginShape();
for (let l = 0; l < testValue3; l++) {
let x = this.arrayXEll[l];
let y = this.arrayYEll[l];
if (x < 0 && y < 0) {
x += ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
} else if (x < 0 && y > 0) {
x += ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y > 0) {
x -= ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y < 0) {
x -= ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
}
push();
translate(x, y);
//vertex(x, y);
ellipse(0, 0, this.arraySEll[l]);
pop();
}
endShape(CLOSE);
};
}
function cusTriangle(x, y, radius) {
let angle = 360 / 3;
beginShape();
for (let a = 0; a < 360; a += angle) {
let sx = x + cos(a) * radius;
let sy = y + sin(a) * radius;
vertex(sx, sy);
}
endShape(CLOSE);
}
{
"000001": [
98,
77,
0,
82,
100,
0,
100
],
"000002": [
100,
54,
0,
0,
100,
0,
100
],
"000005": [
100,
55.00000000000001,
0,
89,
100,
0,
100
],
"000006": [
72,
55.00000000000001,
0,
76,
100,
0,
100
],
"000007": [
48,
55.00000000000001,
0,
0,
0,
100,
0
],
"000009": [
94,
42,
0,
0,
100,
0,
100
],
"000010": [
94,
63,
60,
65,
100,
0,
100
],
"000013": [
94,
63,
74,
73,
0,
100,
0
],
"000014": [
39,
54,
0,
0,
100,
0,
100
],
"000015": [
94,
54,
30,
45,
0,
100,
0
],
"000016": [
94,
78,
0,
0,
0,
100,
0
],
"000018": [
100,
61,
64,
81,
100,
0,
100
],
"000020": [
95,
61,
0,
0,
0,
100,
0
],
"000023": [
95,
99,
96,
0,
0,
100,
0
],
"000025": [
95,
54,
0,
0,
0,
100,
0
],
"000028": [
57.99999999999999,
54,
0,
37,
100,
0,
100
],
"000029": [
91,
69,
100,
100,
100,
0,
100
],
"000030": [
100,
69,
35,
43,
0,
100,
0
],
"000031": [
93,
69,
93,
74,
100,
0,
100
],
"000032": [
93,
57.99999999999999,
0,
23,
0,
100,
0
],
"000035": [
100,
72,
0,
23,
100,
0,
100
],
"000037": [
44,
72,
0,
0,
0,
100,
0
],
"000038": [
100,
54,
62,
25,
0,
100,
0
],
"000040": [
77,
62,
0,
14.000000000000002,
100,
0,
100
],
"000041": [
85,
62,
0,
14.000000000000002,
0,
100,
0
],
"000042": [
100,
62,
80,
54,
100,
0,
100
],
"000043": [
100,
62,
0,
0,
100,
0,
100
],
"000044": [
42,
62,
0,
0,
100,
0,
100
],
"000045": [
74,
73,
0,
0,
100,
0,
100
],
"000047": [
44,
86,
0,
0,
100,
0,
100
],
"000048": [
100,
71,
0,
0,
0,
100,
0
],
"000050": [
87,
42,
0,
0,
0,
100,
0
],
"000051": [
87,
59,
0,
0,
0,
100,
0
],
"000052": [
92,
59,
78,
30,
0,
100,
0
],
"000054": [
100,
70,
55.00000000000001,
38,
100,
0,
100
],
"000055": [
100,
50,
0,
0,
0,
100,
0
],
"000056": [
100,
50,
0,
0,
0,
100,
0
],
"000058": [
100,
74,
76,
0,
100,
0,
100
],
"000060": [
17,
28.000000000000004,
0,
0,
0,
100,
0
],
"000064": [
79,
52,
41,
0,
0,
100,
0
],
"000065": [
80,
52,
0,
0,
0,
100,
0
],
"000068": [
100,
52,
37,
0,
0,
100,
0
],
"000069": [
100,
36,
0,
0,
0,
100,
0
],
"000071": [
100,
55.00000000000001,
38,
71,
100,
0,
100
],
"000073": [
74,
61,
6,
71,
100,
0,
100
],
"000076": [
90,
44,
0,
0,
0,
100,
0
],
"000077": [
72,
75,
0,
0,
100,
0,
100
],
"000078": [
96,
59,
65,
0,
100,
0,
100
],
"000079": [
96,
62,
0,
13,
0,
100,
0
],
"000080": [
100,
38,
61,
13,
0,
100,
0
],
"000081": [
60,
71,
0,
13,
0,
100,
0
],
"000083": [
100,
71,
33,
12,
100,
0,
100
],
"000085": [
100,
71,
46,
12,
100,
0,
100
],
"000086": [
100,
48,
0,
0,
100,
0,
100
],
"000088": [
97,
76,
20,
0,
100,
0,
100
],
"000091": [
100,
47,
1,
0,
0,
100,
0
],
"000092": [
100,
73,
46,
56.00000000000001,
100,
0,
100
],
"000096": [
84,
52,
0,
0,
100,
0,
100
],
"000097": [
84,
68,
57.99999999999999,
63,
100,
0,
100
],
"000099": [
84,
68,
57.99999999999999,
63,
100,
0,
100
],
"000100": [
100,
85,
3,
28.000000000000004,
100,
0,
100
],
"000103": [
100,
52,
71,
19,
100,
0,
100
],
"000104": [
100,
52,
71,
48,
0,
100,
0
],
"000106": [
100,
59,
0,
22,
100,
0,
100
],
"000108": [
100,
59,
84,
84,
100,
0,
100
],
"000109": [
94,
61,
56.00000000000001,
84,
0,
100,
0
],
"000110": [
94,
70,
45,
25,
100,
0,
100
],
"000111": [
48,
73,
12,
55.00000000000001,
100,
0,
100
],
"000114": [
100,
51,
0,
0,
0,
100,
0
],
"000115": [
100,
50,
53,
56.99999999999999,
0,
100,
0
],
"000116": [
100,
46,
4,
21,
0,
100,
0
],
"000117": [
42,
76,
4,
21,
100,
0,
100
],
"000118": [
73,
57.99999999999999,
4,
21,
100,
0,
100
],
"000121": [
64,
73,
4,
21,
100,
0,
100
],
"000122": [
100,
73,
36,
88,
100,
0,
100
],
"000125": [
100,
48,
57.99999999999999,
5,
0,
100,
0
],
"000126": [
81,
51,
92,
91,
100,
0,
100
],
"000129": [
100,
51,
25,
0,
0,
100,
0
],
"000131": [
67,
66,
0,
0,
100,
0,
100
],
"000132": [
50,
66,
0,
0,
100,
0,
100
],
"000133": [
100,
66,
100,
93,
100,
0,
100
],
"000134": [
8,
14.000000000000002,
0,
0,
0,
100,
0
],
"000135": [
37,
71,
0,
0,
0,
100,
0
],
"000137": [
100,
71,
56.00000000000001,
0,
0,
100,
0
],
"000140": [
97,
64,
94,
93,
100,
0,
100
],
"000142": [
84,
67,
0,
0,
100,
0,
100
],
"000143": [
98,
45,
56.99999999999999,
31,
0,
100,
0
],
"000145": [
89,
82,
11,
10,
100,
0,
100
],
"000146": [
60,
82,
11,
10,
100,
0,
100
],
"000147": [
100,
86,
85,
80,
100,
0,
100
],
"000148": [
100,
86,
77,
18,
100,
0,
100
],
"000150": [
100,
39,
63,
18,
0,
100,
0
],
"000151": [
80,
67,
0,
18,
100,
0,
100
],
"000152": [
80,
67,
53,
22,
0,
100,
0
],
"000153": [
80,
35,
0,
0,
0,
100,
0
],
"000155": [
84,
66,
0,
0,
100,
0,
100
],
"000156": [
100,
66,
62,
86,
100,
0,
100
],
"000157": [
100,
68,
87,
94,
100,
0,
100
],
"000160": [
54,
54,
0,
0,
0,
100,
0
],
"000161": [
100,
77,
86,
0,
100,
0,
100
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 6;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function NuescaFace() {
const female_col = color(189,125,106);
const male_col = color(80, 119, 122);
const light_col = color(247, 240, 244);
const med_col = color(221,148,192);
const dark_col = color(13, 32, 33);
const eye_light = color(153, 201, 196);
const eye_med = color(237, 185, 126);
const eye_dark = color(54, 29, 1);
// these are state variables for a face
this.nose_value = 1; // range is 0.8 to 1.5
this.lash_brow_value = 1; //range is 0 to 1
this.eye_size = 1; //range is 0.8 to 1
this.ear_color = 1; // range is 0 to 1
this.skin_color =1; //range is 0 to 2
this.eye_color =1; //range is 0 to 2
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for(let i=0; i<segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if(i < segment.length - 1) {
let nx = segment[i+1][0];
let ny = segment[i+1][1];
line(px, py, nx, ny);
}
else if(do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
//ears
if (this.ear_color == 0){
fill(female_col);
}
else{
fill(male_col);
}
strokeWeight(0.05);
triangle(-1.6, -1.6, -2.3, -3.2, -0.28, -2.2);
triangle(1.6, -1.6, 2.3, -3.2, 0.28, -2.2);
//inner ear
if (this.skin_color == 0){
fill(light_col);
}
else if (this.skin_color == 1){
fill(med_col);
}
else{
fill(dark_col);
}
triangle(-1.4, -1.7, -1.9, -2.8, -0.6, -2.1);
triangle(1.4, -1.7, 1.9, -2.8, 0.6, -2.1);
stroke(0);
strokeWeight(0.05);
if(this.lash_brow_value == 0){
//brows
let left_brow_pos = positions.left_eyebrow[0];
let left_brow_pos2 = positions.left_eyebrow[4];
let right_brow_pos = positions.right_eyebrow[0];
let right_brow_pos2 = positions.right_eyebrow[4];
stroke(0);
strokeWeight(0.2);
line(left_brow_pos[0], left_brow_pos[1] + 0.1, left_brow_pos2[0], left_brow_pos2[1] + 0.1);
line(right_brow_pos[0], right_brow_pos[1] + 0.1, right_brow_pos2[0], right_brow_pos2[1] + 0.1);
}
//eyes
let left_eye_pos = segment_average(positions.left_eye);
let left_eye_pos2 = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
let right_eye_pos2 = segment_average(positions.right_eye);
//eyelashes
stroke(0);
if(this.lash_brow_value == 0){
strokeWeight(0);
}
else if(this.lash_brow_value == 1){
strokeWeight(0.1);
}
//left
line(left_eye_pos[0]- 0.3, left_eye_pos[1] + 0.3, left_eye_pos2[0] -0.5, left_eye_pos2[1]- 0.3);
line(left_eye_pos[0], left_eye_pos[1] + 0.2, left_eye_pos2[0], left_eye_pos2[1]- 0.4);
line(left_eye_pos[0]+ 0.3, left_eye_pos[1] + 0.3, left_eye_pos2[0] +0.5, left_eye_pos2[1]- 0.3);
//right
line(right_eye_pos[0]- 0.3, right_eye_pos[1] + 0.3, right_eye_pos2[0] -0.5, right_eye_pos2[1]- 0.3);
line(right_eye_pos[0], right_eye_pos[1] + 0.2, right_eye_pos2[0], right_eye_pos2[1]- 0.4);
line(right_eye_pos[0]+ 0.3, right_eye_pos[1] + 0.3, right_eye_pos2[0] +0.5, right_eye_pos2[1]- 0.3);
//eye_shape
fill(255);
strokeWeight(0.05);
ellipse(left_eye_pos[0], left_eye_pos[1]+0.3, 1, this.eye_size);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.3, 1, this.eye_size);
//eyeColour
noStroke();
if (this.eye_color == 0){
fill(eye_light);
}
else if (this.eye_color == 1){
fill(eye_med);
}
else{
fill(eye_dark);
}
ellipse(left_eye_pos[0], left_eye_pos[1]+0.3, 0.5, this.eye_size);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.3, 0.5, this.eye_size);
//pupil
fill(0);
ellipse(left_eye_pos[0], left_eye_pos[1]+0.3, 0.2, this.eye_size - 0.2);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.3, 0.2, this.eye_size - 0.2);
// nose setup
let nose_center = positions.nose_tip[2];
//mouth setup
let inner_left_lip = positions.top_lip[2];
let outer_left_lip = positions.top_lip[0];
let inner_right_lip = positions.top_lip[4];
let outer_right_lip = positions.top_lip[7];
let right_bottom_lip = positions.bottom_lip[2];
let center_bottom_lip = positions.bottom_lip[4];
let left_bottom_lip = positions.bottom_lip[7];
//mouth draw
fill(0);
stroke(0);
beginShape();
vertex(outer_left_lip[0], outer_left_lip[1]);
vertex(inner_left_lip[0] - 0.1, inner_left_lip[1] + 0.2);
vertex(nose_center[0], nose_center[1] + 0.4);
vertex(nose_center[0], nose_center[1] + 0.1);
vertex(nose_center[0], nose_center[1] + 0.4);
vertex(inner_right_lip[0] + 0.1, inner_right_lip[1] +0.2);
vertex(outer_right_lip[0] - 0.1, outer_right_lip[1]);
vertex(right_bottom_lip[0], right_bottom_lip[1]);
vertex(center_bottom_lip[0], center_bottom_lip[1]);
vertex(left_bottom_lip[0], left_bottom_lip[1]);
endShape(CLOSE);
//teeth
fill(255);
noStroke();
ellipse(inner_left_lip[0], inner_left_lip[1] + 0.32, 0.1, 0.34);
ellipse(inner_right_lip[0], inner_right_lip[1] + 0.32, 0.1, 0.34);
//nose draw
stroke(0);
strokeWeight(0.05);
if (this.skin_color == 0){
fill(light_col);
}
else if (this.skin_color == 1){
fill(med_col);
}
else{
fill(dark_col);
}
ellipse(nose_center[0], nose_center[1], 0.5 * this.nose_value, 0.25 * this.nose_value);
//whiskers
noFill();
strokeWeight(0.04);
line(left_eye_pos[0] - 1.8, left_eye_pos[1] + 1, left_eye_pos2[0], nose_center[1] + 0.04);
line(left_eye_pos[0] - 1.8, left_eye_pos[1] + 1.4, left_eye_pos2[0], nose_center[1] + 0.04);
line(right_eye_pos[0] + 1.8, left_eye_pos[1] + 1, right_eye_pos2[0], nose_center[1] + 0.04);
line(right_eye_pos[0] + 1.8, left_eye_pos[1] + 1.4, right_eye_pos2[0], nose_center[1] + 0.04);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.nose_value = map(settings[0], 0, 100, 1, 1.5);
this.lash_brow_value=int(map(settings[1], 0, 100, 0, 1));
this.eye_size = map(settings[2], 0, 100, 0.6, 1);
this.ear_color=int(map(settings[3], 0, 100, 0, 1));
this.skin_color=int(map(settings[4], 0, 100, 0, 2));
this.eye_color=int(map(settings[5], 0, 100, 0, 2));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(6);
settings[0] = map(this.nose_value, 1, 1.5, 0, 100);
settings[1] = int(map(this.lash_brow_value, 0, 1, 0, 100));
settings[2] = map(this.eye_size, 0.6, 1, 0, 100);
settings[3] = int(map(this.ear_color, 0, 1, 0, 100));
settings[4] = int(map(this.skin_color, 0, 2, 0, 100));
settings[5] = int(map(this.eye_color, 0, 2, 0, 100));
return settings;
}
}
{
"000001": [
0,
100,
49.000000000000014,
0,
0,
0
],
"000002": [
0,
100,
100,
0,
0,
0
],
"000005": [
0,
100,
45.000000000000014,
0,
0,
0
],
"000006": [
0,
100,
0,
0,
50,
100
],
"000007": [
100,
0,
45.000000000000014,
100,
0,
50
],
"000009": [
0,
100,
45.000000000000014,
0,
0,
50
],
"000010": [
0,
100,
0,
0,
0,
0
],
"000013": [
100,
0,
0,
100,
0,
0
],
"000014": [
0,
100,
0,
0,
50,
100
],
"000015": [
100,
0,
0,
100,
0,
0
],
"000016": [
100,
0,
51.000000000000014,
100,
50,
50
],
"000018": [
0,
100,
0,
0,
0,
0
],
"000020": [
100,
0,
0,
100,
0,
50
],
"000023": [
100,
0,
47.000000000000014,
100,
0,
0
],
"000025": [
100,
0,
0,
100,
50,
50
],
"000028": [
0,
100,
0,
0,
50,
100
],
"000029": [
0,
100,
47.000000000000014,
0,
0,
0
],
"000030": [
100,
0,
100,
100,
50,
50
],
"000031": [
0,
100,
0,
0,
0,
0
],
"000032": [
100,
0,
45.000000000000014,
100,
50,
0
],
"000035": [
0,
100,
45.000000000000014,
0,
0,
50
],
"000037": [
100,
0,
45.000000000000014,
100,
50,
100
],
"000038": [
100,
0,
0,
100,
0,
0
],
"000040": [
0,
100,
46.000000000000014,
0,
0,
50
],
"000041": [
100,
0,
0,
100,
50,
50
],
"000042": [
0,
100,
50.000000000000014,
0,
0,
0
],
"000043": [
0,
100,
100,
0,
50,
50
],
"000044": [
0,
100,
52.000000000000014,
0,
100,
100
],
"000045": [
0,
100,
0,
0,
50,
100
],
"000047": [
0,
100,
0,
0,
50,
100
],
"000048": [
100,
0,
51.000000000000014,
100,
50,
50
],
"000050": [
100,
0,
51.000000000000014,
100,
0,
50
],
"000051": [
100,
0,
51.000000000000014,
100,
0,
50
],
"000052": [
100,
0,
88.99999999999999,
100,
50,
0
],
"000054": [
0,
100,
50.000000000000014,
0,
0,
0
],
"000055": [
100,
0,
50.000000000000014,
100,
0,
50
],
"000056": [
100,
0,
0,
100,
0,
0
],
"000058": [
0,
100,
52.000000000000014,
0,
0,
0
],
"000060": [
100,
0,
0,
100,
100,
100
],
"000064": [
100,
0,
0,
100,
0,
0
],
"000065": [
100,
0,
0,
100,
50,
100
],
"000068": [
100,
0,
47.000000000000014,
100,
0,
50
],
"000069": [
100,
0,
92,
100,
0,
50
],
"000071": [
0,
100,
100,
0,
0,
0
],
"000073": [
0,
100,
100,
0,
50,
50
],
"000076": [
100,
0,
48.000000000000014,
100,
50,
50
],
"000077": [
0,
100,
48.000000000000014,
0,
50,
100
],
"000078": [
0,
100,
48.000000000000014,
0,
50,
50
],
"000079": [
100,
0,
48.000000000000014,
100,
0,
50
],
"000080": [
100,
0,
0,
100,
0,
0
],
"000081": [
100,
0,
49.000000000000014,
100,
50,
50
],
"000083": [
0,
100,
0,
0,
0,
0
],
"000085": [
0,
100,
100,
0,
0,
0
],
"000086": [
0,
100,
53.000000000000014,
0,
0,
50
],
"000088": [
0,
100,
54.000000000000014,
0,
50,
50
],
"000091": [
100,
0,
0,
100,
0,
0
],
"000092": [
0,
100,
0,
0,
0,
0
],
"000096": [
0,
100,
79.00000000000001,
0,
50,
100
],
"000097": [
0,
100,
66,
0,
0,
0
],
"000099": [
0,
100,
0,
0,
0,
0
],
"000100": [
0,
100,
49.000000000000014,
0,
0,
50
],
"000103": [
0,
100,
89.99999999999999,
0,
0,
50
],
"000104": [
100,
0,
0,
100,
0,
0
],
"000106": [
0,
100,
0,
0,
0,
50
],
"000108": [
0,
100,
52.000000000000014,
0,
0,
0
],
"000109": [
100,
0,
52.000000000000014,
100,
50,
0
],
"000110": [
0,
100,
52.000000000000014,
0,
0,
0
],
"000111": [
0,
100,
0,
0,
100,
100
],
"000114": [
100,
0,
48.000000000000014,
100,
0,
50
],
"000115": [
100,
0,
0,
100,
0,
0
],
"000116": [
100,
0,
0,
100,
0,
50
],
"000117": [
0,
100,
84.99999999999999,
0,
100,
100
],
"000118": [
0,
100,
51.000000000000014,
0,
50,
50
],
"000121": [
0,
100,
51.000000000000014,
0,
0,
50
],
"000122": [
0,
100,
51.000000000000014,
0,
0,
0
],
"000125": [
100,
0,
0,
100,
0,
0
],
"000126": [
0,
100,
53.000000000000014,
0,
0,
0
],
"000129": [
100,
0,
0,
100,
0,
0
],
"000131": [
0,
100,
51.000000000000014,
0,
0,
50
],
"000132": [
0,
100,
0,
0,
50,
100
],
"000133": [
0,
100,
52.000000000000014,
0,
0,
0
],
"000134": [
100,
0,
52.000000000000014,
100,
100,
100
],
"000135": [
100,
0,
52.000000000000014,
100,
50,
100
],
"000137": [
100,
0,
0,
100,
0,
0
],
"000140": [
0,
100,
100,
0,
0,
0
],
"000142": [
0,
100,
0,
0,
0,
0
],
"000143": [
100,
0,
53.000000000000014,
100,
0,
0
],
"000145": [
0,
100,
0,
0,
50,
50
],
"000146": [
0,
100,
50.000000000000014,
0,
50,
50
],
"000147": [
0,
100,
50.000000000000014,
0,
0,
0
],
"000148": [
0,
100,
0,
0,
0,
0
],
"000150": [
100,
0,
45.000000000000014,
100,
0,
0
],
"000151": [
0,
100,
0,
0,
50,
100
],
"000152": [
100,
0,
0,
100,
0,
0
],
"000153": [
100,
0,
49.000000000000014,
100,
0,
50
],
"000155": [
0,
100,
45.000000000000014,
0,
50,
100
],
"000156": [
0,
100,
0,
0,
0,
0
],
"000157": [
0,
100,
0,
0,
0,
0
],
"000160": [
100,
0,
48.000000000000014,
100,
0,
50
],
"000161": [
0,
100,
0,
0,
0,
0
]
}
{
"000001": [
100,
100,
0,
13,
79
],
"000002": [
100,
100,
0,
0,
50
],
"000005": [
100,
0,
0,
0,
91
],
"000006": [
100,
100,
0,
54,
61
],
"000007": [
0,
50,
100,
13,
0
],
"000009": [
100,
50,
0,
17,
13
],
"000010": [
100,
50,
0,
2,
83
],
"000013": [
0,
50,
100,
0,
100
],
"000014": [
100,
100,
0,
60,
0
],
"000015": [
0,
100,
100,
10,
47
],
"000016": [
0,
100,
100,
34,
20
],
"000018": [
100,
0,
0,
0,
100
],
"000020": [
0,
100,
100,
11,
52
],
"000023": [
0,
50,
100,
18,
15
],
"000025": [
0,
100,
100,
42,
41
],
"000028": [
100,
100,
0,
30,
47
],
"000029": [
100,
0,
0,
15,
100
],
"000030": [
0,
100,
100,
15,
98.99999999999999
],
"000031": [
100,
0,
0,
26,
56.00000000000001
],
"000032": [
0,
100,
100,
14,
68
],
"000035": [
100,
0,
0,
5,
0
],
"000037": [
0,
100,
100,
68,
0
],
"000038": [
0,
0,
100,
10,
52
],
"000040": [
100,
50,
0,
1,
0
],
"000041": [
0,
100,
100,
25,
0
],
"000042": [
100,
0,
0,
0,
54
],
"000043": [
100,
0,
0,
15,
10
],
"000044": [
100,
100,
0,
76,
0
],
"000045": [
100,
100,
0,
5,
37
],
"000047": [
100,
100,
0,
57,
0
],
"000048": [
0,
100,
100,
0,
0
],
"000050": [
0,
50,
100,
18,
30
],
"000051": [
0,
100,
100,
27,
55.00000000000001
],
"000052": [
0,
0,
100,
29,
28.999999999999996
],
"000054": [
100,
50,
0,
2,
100
],
"000055": [
0,
50,
100,
1,
0
],
"000056": [
0,
50,
100,
0,
0
],
"000058": [
100,
0,
0,
0,
0
],
"000060": [
0,
100,
100,
81,
47
],
"000064": [
0,
50,
100,
0,
56.00000000000001
],
"000065": [
0,
100,
100,
34,
20
],
"000068": [
0,
50,
100,
3,
40
],
"000069": [
0,
100,
100,
28,
0
],
"000071": [
100,
50,
0,
19,
100
],
"000073": [
100,
50,
0,
13,
15
],
"000076": [
0,
100,
100,
22,
0
],
"000077": [
100,
100,
0,
8,
13
],
"000078": [
100,
50,
0,
0,
0
],
"000079": [
0,
100,
100,
19,
47
],
"000080": [
0,
0,
100,
22,
0
],
"000081": [
0,
100,
100,
25,
0
],
"000083": [
100,
50,
0,
1,
44
],
"000085": [
100,
50,
0,
0,
39
],
"000086": [
100,
100,
0,
0,
59
],
"000088": [
100,
100,
0,
0,
51
],
"000091": [
0,
50,
100,
15,
1
],
"000092": [
100,
0,
0,
4,
85
],
"000096": [
100,
100,
0,
41,
5
],
"000097": [
100,
0,
0,
10,
50
],
"000099": [
100,
50,
0,
3,
47
],
"000100": [
100,
100,
0,
10,
84
],
"000103": [
100,
0,
0,
20,
11
],
"000104": [
0,
0,
100,
3,
88
],
"000106": [
100,
50,
0,
28,
66
],
"000108": [
100,
0,
0,
13,
98
],
"000109": [
0,
0,
100,
14,
67
],
"000110": [
100,
50,
0,
15,
53
],
"000111": [
100,
100,
0,
76,
64
],
"000114": [
0,
100,
100,
19,
0
],
"000115": [
0,
0,
100,
0,
100
],
"000116": [
0,
100,
100,
8,
42
],
"000117": [
100,
100,
0,
72,
0
],
"000118": [
100,
100,
0,
30,
0
],
"000121": [
100,
100,
0,
15,
0
],
"000122": [
100,
0,
0,
0,
100
],
"000125": [
0,
0,
100,
19,
56.99999999999999
],
"000126": [
100,
0,
0,
27,
100
],
"000129": [
0,
50,
100,
13,
0
],
"000131": [
100,
100,
0,
28,
11
],
"000132": [
100,
100,
0,
51,
0
],
"000133": [
100,
0,
0,
13,
48
],
"000134": [
0,
100,
100,
86,
0
],
"000135": [
0,
100,
100,
71,
0
],
"000137": [
0,
50,
100,
23,
100
],
"000140": [
100,
50,
0,
39,
100
],
"000142": [
100,
0,
0,
6,
32
],
"000143": [
0,
0,
100,
17,
59
],
"000145": [
100,
100,
0,
25,
0
],
"000146": [
100,
100,
0,
47,
26
],
"000147": [
100,
50,
0,
27,
100
],
"000148": [
100,
0,
0,
0,
0
],
"000150": [
0,
50,
100,
16,
48
],
"000151": [
100,
100,
0,
27,
0
],
"000152": [
0,
50,
100,
41,
46
],
"000153": [
0,
50,
100,
10,
35
],
"000155": [
100,
100,
0,
10,
59
],
"000156": [
100,
0,
0,
0,
100
],
"000157": [
100,
0,
0,
14,
100
],
"000160": [
0,
100,
100,
3,
0
],
"000161": [
100,
0,
0,
0,
1
]
}
function PetrisFace() {
const bg_color = 0;
var fireMove = 1;
var lastFrameCount = 0;
this.hairOpacity = 50;
this.bodyColourR = 255;
this.bodyColourG = 50;
this.bodyColourB = 50;
this.skinOpacity = 50;
this.eyeHue = 0;
this.hairLength = 0;
this.eyeBrightness = 0;
this.skinSaturation = 50;
this.draw = function(positions) {
var nose_pos = average_point(positions.nose_bridge);
var eye1_pos = average_point(positions.left_eye);
var eye2_pos = average_point(positions.right_eye);
var eyebrow1_pos = average_point(positions.left_eyebrow);
var eyebrow2_pos = average_point(positions.right_eyebrow);
var half_height = positions.chin[7][1] - nose_pos[1];
var face_width = positions.chin[positions.chin.length-1][0] - positions.chin[0][0];
var fire_pos=[[positions.chin[0][0],positions.chin[0][1]],
[positions.chin[16][0],positions.chin[16][1]],
[positions.chin[3][0],positions.chin[3][1]],
[positions.chin[13][0],positions.chin[13][1]],
[positions.chin[6][0],positions.chin[6][1]],
[positions.chin[10][0],positions.chin[10][1]],
[positions.chin[8][0],positions.chin[8][1]]]
var fire_pos2=[[positions.chin[0][0],positions.chin[0][1]],
[positions.chin[16][0],positions.chin[16][1]],
[positions.chin[4][0],positions.chin[4][1]],
[positions.chin[12][0],positions.chin[12][1]],
[positions.chin[8][0],positions.chin[8][1]]]
var x = nose_pos[0];
var y = nose_pos[1];
var w = 2 * face_width;
var h = 2.5 * half_height;
noStroke();
//make fire animate
if(frameCount != lastFrameCount) {
fireMove = fireMove+0.05;
lastFrameCount = frameCount;
// print(fireMove);
}
function occilation(n){return Math.sin(fireMove+n)*0.1}
var extent = 0;
if(h < w) {
extent = h / 2;
}
else {
extent = w / 2;
}
var scale2 = extent / 220.0;
var curHairLength = map(this.hairLength, 0, 100, -0.5, 1.5);
//fire1 (back layer of fire it is like the hair)
var fh=[-2, -2.2, -3.2,-3.2,-3.9,-3.8,-4.5]
var fw=[-0.6, 0.6, -0.4,0.4, -0.2,0.2,0]
var curHairOpacity = map(this.hairOpacity, 0, 100, 180, 30);
var curRed = map(this.bodyColourR, 0, 100, 0, 255);
var curGreen = map(this.bodyColourG, 0, 100, 0, 180);
var curBlue = map(this.bodyColourB, 0, 100, 0, 180);
fill(curRed, curGreen, curBlue, curHairOpacity);
push();
scale(1.05,1);
translate(0,-0.3);
for(var n=0; n<fw.length;n++) {
beginShape();
for(var i=1; i<positions.chin.length-8;i++) {
vertex(positions.chin[i][0]-0.15, positions.chin[i][1]);
}
for(var i=8; i<positions.chin.length-1;i++) {
vertex(positions.chin[i][0]+0.15, positions.chin[i][1]);
}
vertex(fire_pos[n][0]+fw[n]+occilation(n), fh[n]+curHairLength);
endShape(CLOSE);
}
pop();
//fire2
var fh=[ -2,-2.2,-3,-3,-3.3]
var fw=[ -0.4,0.4, -0.2,0.2,0]
var curHairOpacity = map(this.hairOpacity, 0, 100, 180, 30);
var curRed = map(this.bodyColourR, 0, 100, 0, 255);
var curGreen = map(this.bodyColourG, 0, 100, 0, 230);
var curBlue = map(this.bodyColourB, 0, 100, 0, 230);
fill(curRed, curGreen, curBlue, curHairOpacity);
push();
translate(0,-0.3);
for(var n=0; n<fw.length;n++) {
beginShape();
for(var i=0; i<positions.chin.length-8;i++) {
vertex(positions.chin[i][0]-0.15, positions.chin[i][1]);
}
for(var i=8; i<positions.chin.length;i++) {
vertex(positions.chin[i][0]+0.15, positions.chin[i][1]);
}
vertex(fire_pos2[n][0]+fw[n]+occilation(n), fh[n]+curHairLength/2);
endShape(CLOSE);
}
pop();
//face
push();
translate(0,-0.4);
var curSkinOpacity = map(this.skinOpacity, 0, 100, 1, 0);
var curSkinSaturation = map(this.skinSaturation, 0, 100, 0,100);
colorMode(HSB);
fill(34, curSkinSaturation, 100, curSkinOpacity);
beginShape();
for(var i=1; i<positions.chin.length-1;i++) {
vertex(positions.chin[i][0], positions.chin[i][1]);
}
vertex(positions.chin[16][0]-0.2, -0.8);
vertex(positions.chin[16][0]-0.5, -1.3);
vertex(positions.chin[16][0]-1, -1.8);
vertex(0+occilation(n), -2.3);
vertex(positions.chin[0][0]+1, -1.8);
vertex(positions.chin[0][0]+0.5, -1.3);
vertex(positions.chin[0][0]+0.2, -0.8);
endShape(CLOSE);
pop();
// mouth
noStroke();
fill(34, curSkinSaturation,100,curSkinOpacity);
beginShape();
for(var i=0; i<positions.top_lip.length;i++) {
vertex(positions.top_lip[i][0], positions.top_lip[i][1]);
}
endShape(CLOSE);
beginShape();
for(var i=0; i<positions.bottom_lip.length;i++) {
vertex(positions.bottom_lip[i][0], positions.bottom_lip[i][1]);
}
endShape(CLOSE);
colorMode(RGB);
// inside of mouth
fill(bg_color);
beginShape();
for(var i=6; i<positions.bottom_lip.length;i++) {
vertex(positions.bottom_lip[i][0], positions.bottom_lip[i][1]);
}
for(var i=6; i<positions.top_lip.length;i++) {
vertex(positions.top_lip[i][0], positions.top_lip[i][1]);
}
endShape(CLOSE);
fill(bg_color);
// nose
beginShape();
for(var i=0; i<positions.nose_tip.length;i++) {
vertex(positions.nose_tip[i][0], positions.nose_tip[i][1]);
}
endShape(CLOSE);
// eyes
fill(255);
ellipse(eye1_pos[0], eye1_pos[1]+0.6, 0.8, 0.8);
ellipse(eye2_pos[0], eye2_pos[1]+0.6, 0.8, 0.8);
//pupil
colorMode(HSB);
var curEyeHue = map(this.eyeHue, 0, 100, 0, 360);
var curEyeBrightness = map(this.eyeBrightness, 0, 100, 0, 100);
fill(curEyeHue,50,curEyeBrightness);
ellipse(eye1_pos[0], eye1_pos[1]+0.6, 0.6, 0.6);
ellipse(eye2_pos[0], eye2_pos[1]+0.6, 0.6, 0.6);
colorMode(RGB);
fill(0);
ellipse(eye1_pos[0], eye1_pos[1]+0.6, 0.4, 0.4);
ellipse(eye2_pos[0], eye2_pos[1]+0.6, 0.4, 0.4);
fill(255);
ellipse(eye1_pos[0]+0.17, eye1_pos[1]+0.53, 0.15, 0.14);
ellipse(eye2_pos[0]+0.17, eye2_pos[1]+0.53, 0.15, 0.14);
//eyebrows
colorMode(HSB);
fill(34, curSkinSaturation, 100, curSkinOpacity);
push();
translate(0,0.5);
beginShape();
for(var i=0; i<positions.right_eyebrow.length; i++) {
vertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1]+0.08);
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1]+0.1); vertex(positions.right_eyebrow[1][0], positions.right_eyebrow[1][1]+0.11);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[0][1]+0.12);
endShape(CLOSE);
beginShape();
for(var i=0; i<positions.left_eyebrow.length; i++) {
vertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
vertex(positions.left_eyebrow[4][0], positions.left_eyebrow[4][1]+0.12);
vertex(positions.left_eyebrow[3][0], positions.left_eyebrow[3][1]+0.11);
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]+0.1);
vertex(positions.left_eyebrow[1][0], positions.left_eyebrow[1][1]+0.08);
endShape(CLOSE);
pop();
colorMode(RGB);
var curHairOpacity = map(this.hairOpacity, 0, 100, 0, 255);
fill(0, curHairOpacity);
push();
translate(0,0.5);
beginShape();
for(var i=0; i<positions.right_eyebrow.length; i++) {
vertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1]+0.08);
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1]+0.1); vertex(positions.right_eyebrow[1][0], positions.right_eyebrow[1][1]+0.11);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[0][1]+0.12);
endShape(CLOSE);
beginShape();
for(var i=0; i<positions.left_eyebrow.length; i++) {
vertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
vertex(positions.left_eyebrow[4][0], positions.left_eyebrow[4][1]+0.12);
vertex(positions.left_eyebrow[3][0], positions.left_eyebrow[3][1]+0.11);
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]+0.1);
vertex(positions.left_eyebrow[1][0], positions.left_eyebrow[1][1]+0.08);
endShape(CLOSE);
pop();
strokeWeight(1);
// pop();
}
this.randomize = function(values, size) {
this.fireOpacity = focusedRandom(0, 250, 5);
this.flameSpread=focusedRandom(0,0);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.hairOpacity = settings[0];
this.bodyColourR = settings[1];
this.bodyColourG = settings[2];
this.bodyColourB = settings[3];
this.skinOpacity = settings[4];
this.eyeHue = settings[5];
this.eyeBrightness = settings[6];
this.hairLength = settings[7];
this.skinSaturation = settings[8];
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
properties = new Array(8);
properties[0] = this.hairOpacity;
properties[1] = this.bodyColourR;
properties[2] = this.bodyColourG;
properties[3] = this.bodyColourB;
properties[4] = this.skinOpacity;
properties[5] = this.eyeHue;
properties[6]= this.eyeBrightness;
properties[7]= this.hairLength;
properties[8]= this.skinSaturation;
return properties;
}
}
// given a point, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
40,
97,
81,
48,
15,
0,
30,
0,
30
],
"000002": [
43,
100,
60,
51,
6,
10,
50,
6,
25
],
"000005": [
24,
81,
72,
50,
7,
11,
39,
56,
23
],
"000006": [
53,
100,
79,
43,
23,
0,
41,
0,
43
],
"000007": [
100,
89,
55,
25,
13,
6,
60,
64,
34
],
"000009": [
100,
100,
77,
51,
3,
10,
50,
0,
37
],
"000016": [
94,
97,
76,
52,
34,
5,
34,
88,
50
],
"000018": [
10,
100,
93,
77,
7,
15,
37,
27,
22
],
"000020": [
100,
84,
60,
34,
20,
10,
35,
42,
39
],
"000025": [
51,
83,
76,
55,
17,
13,
28,
94,
46
],
"000030": [
6,
100,
86,
72,
67,
10,
35,
82,
60
],
"000031": [
35,
97,
77,
50,
27,
51,
64,
68,
41
],
"000013": [
6,
100,
82,
55,
22,
59,
48,
80,
32
],
"000014": [
100,
100,
61,
28,
50,
0,
33,
35,
76
],
"000032": [
25,
91,
77,
58,
30,
5,
20,
71,
41
],
"000038": [
100,
90,
67,
39,
20,
50,
55,
67,
36
],
"000041": [
100,
100,
71,
40,
29,
3,
28,
67,
57
],
"000043": [
74,
100,
72,
41,
7,
9,
39,
14,
41
],
"000044": [
100,
100,
57,
24,
83,
0,
24,
0,
81
],
"000047": [
100,
97,
67,
32,
41,
5,
20,
0,
63
],
"000048": [
77,
100,
69,
46,
0,
10,
23,
82,
25
],
"000050": [
94,
95,
65,
39,
15,
2,
41,
71,
41
],
"000051": [
15,
85,
90,
100,
22,
0,
26,
50,
43
],
"000052": [
81,
95,
67,
38,
13,
48,
56,
74,
41
],
"000054": [
9,
100,
91,
77,
10,
46,
40,
0,
29
],
"000055": [
95,
100,
58,
30,
6,
13,
49,
68,
36
],
"000056": [
100,
98,
70,
44,
0,
50,
58,
11,
30
],
"000058": [
84,
100,
71,
39,
0,
43,
55,
0,
32
],
"000064": [
62,
89,
70,
41,
3,
19,
40,
68,
37
],
"000065": [
94,
98,
66,
38,
32,
9,
27,
63,
67
],
"000068": [
19,
94,
78,
64,
30,
15,
46,
61,
30
],
"000069": [
100,
94,
68,
40,
15,
13,
54,
84,
36
],
"000071": [
11,
97,
84,
50,
7,
14,
53,
27,
32
],
"000073": [
100,
97,
79,
50,
7,
5,
41,
0,
43
],
"000076": [
100,
89,
63,
34,
36,
13,
27,
68,
43
],
"000077": [
100,
100,
73,
39,
0,
5,
21,
0,
32
],
"000079": [
29,
83,
65,
45,
17,
5,
48,
100,
44
],
"000080": [
100,
89,
55,
34,
2,
19,
51,
64,
43
],
"000081": [
97,
89,
51,
27,
20,
1,
42,
66,
46
],
"000083": [
52,
97,
69,
51,
13,
13,
38,
0,
18
],
"000085": [
75,
100,
82,
59,
3,
28,
45,
0,
20
],
"000015": [
73,
89,
66,
35,
3,
43,
44,
68,
48
],
"000035": [
100,
97,
79,
50,
0,
10,
59,
0,
27
],
"000037": [
95,
93,
62,
32,
51,
5,
34,
64,
70
],
"000010": [
19,
100,
93,
67,
6,
53,
47,
0,
22
],
"000023": [
90,
100,
65,
46,
18,
54,
44,
64,
41
],
"000028": [
28,
100,
70,
41,
9,
7,
33,
0,
41
],
"000029": [
6,
100,
93,
76,
23,
53,
62,
0,
41
],
"000040": [
100,
100,
74,
32,
0,
5,
55,
30,
34
],
"000042": [
15,
98,
83,
72,
3,
47,
55,
9,
20
],
"000045": [
67,
90,
66,
46,
8,
7,
33,
0,
44
],
"000060": [
97,
91,
62,
33,
58,
9,
30,
75,
74
],
"000078": [
100,
100,
74,
55,
20,
3,
33,
0,
13
],
"000086": [
54,
100,
76,
46,
29,
9,
33,
63,
25
],
"000088": [
54,
100,
73,
47,
0,
10,
44,
21,
25
],
"000091": [
90,
93,
64,
41,
15,
18,
40,
71,
43
],
"000092": [
31,
97,
81,
47,
6,
15,
58,
15,
39
],
"000096": [
78,
97,
60,
37,
11,
8,
30,
0,
23
],
"000097": [
59,
98,
76,
44,
0,
57,
71,
0,
23
],
"000099": [
86,
97,
68,
38,
4,
12,
39,
0,
36
],
"000100": [
39,
99,
77,
51,
1,
11,
36,
57,
27
],
"000103": [
100,
99,
86,
54,
6,
24,
43,
0,
39
],
"000104": [
9,
100,
81,
41,
9,
54,
47,
80,
27
],
"000106": [
72,
98,
75,
46,
0,
0,
36,
20,
39
],
"000108": [
11,
98,
91,
65,
14,
45,
51,
12,
46
],
"000109": [
57,
93,
76,
50,
15,
44,
61,
70,
55
],
"000110": [
47,
98,
76,
45,
12,
19,
55,
40,
39
],
"000111": [
16,
95,
81,
53,
32,
7,
38,
13,
60
],
"000114": [
82,
96,
64,
39,
15,
9,
37,
84,
39
],
"000115": [
0,
88,
84,
68,
0,
17,
60,
100,
29
],
"000116": [
50,
98,
76,
49,
20,
9,
31,
72,
27
],
"000117": [
100,
95,
63,
33,
40,
2,
34,
0
],
"000118": [
90,
100,
63,
47,
17,
7,
44,
18,
44
],
"000121": [
100,
95,
62,
39,
15,
10,
43,
0,
29
],
"000122": [
6,
90,
84,
55,
0,
8,
41,
44,
6
],
"000125": [
55,
90,
85,
71,
22,
51,
63,
90,
44
],
"000126": [
10,
97,
93,
77,
16,
31,
43,
1,
46
],
"000129": [
37,
94,
76,
57,
10,
19,
53,
65,
44
],
"000131": [
83,
95,
67,
42,
3,
6,
27,
0,
29
],
"000132": [
76,
100,
74,
36,
26,
6,
36,
0
],
"000133": [
51,
97,
72,
43,
4,
26,
70,
20
],
"000134": [
100,
93,
56,
30,
44,
13,
28,
100,
100
],
"000135": [
85,
97,
71,
42,
34,
3,
30,
56,
67
],
"000137": [
70,
87,
66,
40,
30,
29,
40,
64,
34
],
"000140": [
9,
98,
90,
63,
27,
32,
43,
10,
60
],
"000142": [
49,
98,
75,
47,
7,
13,
38,
24,
25
],
"000143": [
54,
90,
70,
48,
23,
43,
50,
79,
32
],
"000145": [
100,
98,
73,
43,
15,
8,
33,
0,
36
],
"000146": [
94,
97,
68,
41,
4,
6,
27,
0,
50
],
"000147": [
24,
97,
79,
53,
15,
38,
55,
3,
37
],
"000148": [
80,
97,
75,
48,
13,
24,
51,
17,
30
],
"000150": [
52,
100,
66,
61,
8,
43,
48,
71,
22
],
"000151": [
100,
98,
78,
36,
0,
9,
33,
31,
43
],
"000152": [
31,
94,
74,
50,
7,
13,
39,
63,
34
],
"000153": [
94,
87,
65,
40,
18,
13,
48,
75,
36
],
"000155": [
81,
98,
51,
41,
15,
0,
36,
0,
32
],
"000156": [
38,
97,
88,
57,
13,
51,
45,
57,
27
],
"000157": [
48,
99,
90,
70,
6,
47,
53,
0,
30
],
"000160": [
100,
95,
63,
35,
2,
5,
41,
71,
43
],
"000161": [
96,
100,
67,
45,
0,
51,
59,
25,
32
]
}
{
"commits": [
{
"sha": "502f42ec801ef07ae1b930482eab8f509ce51251",
"name": "final_version"
},
{
"sha": "29bfd23eeed1ada1a17c10cf1b37839f278b5d41",
"name": "trained_initial"
},
{
"sha": "14b4830ee2813c21c3acf008b7118574e6e753c3",
"name": "shaded_face"
},
{
"sha": "db168de3cc1d70728b6b89af9edb49168602f021",
"name": "basic_face"
},
{
"sha": "f2f17cda73d71285aaa2649095b115cfbe5a292e",
"name": "sketch"
}
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 3;
// other variables can be in here too
// these control the colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
function RuanFace() {
// these are state variables for a face
// (your variables may be different)
this.skin = 3; // 1-5
this.ear = 1; // 1-3
this.blushType = 1; // Can be either 1 or 2
// * Draw a face with position lists that include:
this.draw = function(positions) {
let skin = this.skin;
let ear = this.ear;
let mouth = 5;
let blush = 5;
let eyebrows_rotate=10;
let glasses = 5;
let pupil = 5;
// Colour Sets
let skin1 = '#fffaf5';
let skin2 = '#fff1e4';
let skin3 = '#fde3cb';
let skin4 = '#dfb791';
let skin5 = '#7a5540';
// let ear1 = '#fffef2';//white
let ear1 = '#f5deb4';//yellow
let ear2 = '#4a2e21';//brown
let ear3 = 'black';//black
// let ear4 = '#b83835';//red
let skinColour;
let earColour;
let left_eye = average_point(positions.left_eye);
let right_eye = average_point(positions.right_eye);
let left_eyebrow = average_point(positions.left_eyebrow);
let right_eyebrow = average_point(positions.right_eyebrow);
let left_d = dist(left_eye[0], left_eye[1], left_eyebrow[0], left_eyebrow[1]);
let right_d = dist(right_eye[0], right_eye[1], right_eyebrow[0], right_eyebrow[1]);
let left_eb_move = map(left_d, 0.4, 0.7, 0, 2, true);
let right_eb_move = map(right_d, 0.4, 0.7, 0, 2, true);
left_eye[0] *= 3;
left_eye[1] *= 3;
right_eye[0] *= 3;
right_eye[1] *= 3;
push();
scale(0.33);
// head
noStroke();
fill('#f2a8b9');//babypink
beginShape();
curveVertex(0, -3);
curveVertex(0, -3);
curveVertex(- 6.3, -3);
curveVertex(-6.7, 3.5);
curveVertex(0,5.7);
curveVertex(6.7, 3.5);
curveVertex(6.3, -3);
curveVertex(0, 0);
curveVertex(0, 0);
ellipse(0, -1, 14,10);
endShape();
bezier(-5, -3, -14, -8, -7, -12, -4, -4);
bezier(5, -3, 14, -8, 7, -12, 4, -4);
// Skin Colour
if(skin == 1){
skinColour = skin1; //***ALMOST WHITE***//
}else if (skin == 2){
skinColour = skin2; //***Light***//
}else if (skin == 3){
skinColour = skin3; //***Light2***//
}else if (skin == 4){
skinColour = skin4; //***Mild***//
}else{
skinColour = skin5; //***Dark***//
}
fill(skinColour);
noStroke();
beginShape();
curveVertex(0, -2);
curveVertex(0, -2);
curveVertex(- 5.1, -1.2);
curveVertex(-5.2, 3.2);
curveVertex(0,5);
curveVertex(5.2, 3.2);
curveVertex(5.1, -1.2);
curveVertex(0, 0);
curveVertex(0, 0);
ellipse(0, 0, 11,8);
endShape();
// ear Colour
if(ear == 1){
earColour = ear1; //***white***//
}else if (ear == 2){
earColour = ear2; //***yellow***//
}else{
earColour = ear3; //***dark brown***//
}
//ear
fill(earColour);
noStroke();
bezier(-5.2, -3.7, -10.5, -7, -8, -10, -4.7, -4.25);
bezier(5.2, -3.7, 10.5, -7, 8, -10, 4.7, -4.25);
// Mouth
stroke('#ce8483');
let top_lip_point = positions.top_lip[9];
let bottom_lip_point = positions.bottom_lip[9];
let d = dist(top_lip_point[0], top_lip_point[1], bottom_lip_point[0], bottom_lip_point[1])
// Mouth Open
if(d < 0.1) {
d = 0;
}
mouth = map(d, 0, 0.5, 0, 10);
let mouth_size = map(mouth, 0, 10, 0, 3);
strokeWeight(0.2);
fill('#ee9b90');
rect(-1, 1.8, 1.6, mouth_size, 2);
// Eyes
noStroke();
fill(0);
ellipse(left_eye[0], left_eye[1]+3, 0.8, 1.2);
ellipse(right_eye[0], right_eye[1]+3, 0.8, 1.2);
// Pupil
fill('white');
ellipse(left_eye[0]-0.1, left_eye[1]-0.1+3, 0.3, 0.3); //***LEFT TOP***//
ellipse(left_eye[0]+0.15, left_eye[1]+0.1+3, 0.2, 0.2); //***LEFT BOTTOM***//
ellipse(right_eye[0]-0.1, right_eye[1]-0.1+3, 0.3, 0.3); //***RIGHT TOP***//
ellipse(right_eye[0]+0.15, right_eye[1]+0.1+3, 0.2, 0.2); //***RIGHT BOTTOM***//
// Eyebrows
strokeWeight(0.4);
stroke(90,59,32);//brown
push();
angleMode(DEGREES);
translate(left_eye[0]-0.1, left_eye[1]+2.5);
translate(0, -left_eb_move);
rotate(eyebrows_rotate);
line(-0.3, 0, 0.5, 0);
pop();
push();
angleMode(DEGREES);
translate(right_eye[0]-0.2, right_eye[1]+2.5);
translate(0, -right_eb_move);
rotate(-eyebrows_rotate);
line(-0.3, 0, 0.5, 0);
pop();
// Glasses
if (glasses > 5 && glasses < 8){
noStroke();
}
// Sunglasses
else if (glasses > 7 && glasses <= 10){
noStroke();
}
pop();
if (this.blushType == 1) { // Female blush
stroke('#f8c2b6');
strokeWeight(0.08);
line(left_eye[0]+0.8, left_eye[1]+3.7, left_eye[0]+1, left_eye[1]+3.4);
line(left_eye[0]+1, left_eye[1]+3.7, left_eye[0]+1.2, left_eye[1]+3.4);
line(left_eye[0]+1.2, left_eye[1]+3.7, left_eye[0]+1.4, left_eye[1]+3.4);//left
line(right_eye[0]-1.4, right_eye[1]+3.7, right_eye[0]-1.2, right_eye[1]+3.4);
line(right_eye[0]-1.2, right_eye[1]+3.7, right_eye[0]-1, right_eye[1]+3.4);
line(right_eye[0]-1, right_eye[1]+3.7, right_eye[0]-0.8, right_eye[1]+3.4);//right
} else if (this.blushType == 2) { // Male blush
noStroke();
fill(255, 176, 120,98);
ellipse(left_eye[0]+1.2, left_eye[1]+3.7, 0.7);
ellipse(right_eye[0]-1, right_eye[1]+3.7, 0.7);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.skin = int(map(settings[0], 0, 100, 1, 5));
this.blushType = int(map(settings[1], 0, 100, 1, 2));
this.ear = int(map(settings[2], 0, 100, 1, 3));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(2);
settings[0] = map(this.skin, 1, 5, 0, 100);
settings[1] = map(this.blushType, 1, 2, 0, 100);
settings[2] = map(this.ear, 1, 3, 0, 100);
return settings;
}
}
// given an array of [x,y] points, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
50,
100,
50
],
"000002": [
25,
0,
0
],
"000005": [
50,
0,
0
],
"000006": [
75,
0,
50
],
"000007": [
50,
100,
50
],
"000009": [
50,
0,
50
],
"000010": [
25,
0,
0
],
"000013": [
75,
100,
0
],
"000014": [
100,
0,
100
],
"000015": [
50,
100,
50
],
"000018": [
25,
0,
0
],
"000020": [
50,
100,
50
],
"000023": [
50,
100,
50
],
"000025": [
50,
100,
50
],
"000028": [
50,
0,
0
],
"000029": [
50,
0,
0
],
"000030": [
75,
100,
0
],
"000031": [
75,
0,
50
],
"000032": [
50,
100,
0
],
"000035": [
25,
0,
50
],
"000037": [
75,
100,
50
],
"000038": [
25,
100,
50
],
"000040": [
50,
0,
0
],
"000041": [
75,
100,
50
],
"000042": [
50,
0,
0
],
"000043": [
50,
0,
50
],
"000044": [
100,
0,
100
],
"000045": [
50,
0,
0
],
"000047": [
100,
0,
100
],
"000048": [
25,
100,
50
],
"000050": [
50,
100,
50
],
"000051": [
50,
100,
50
],
"000052": [
75,
100,
50
],
"000054": [
25,
0,
0
],
"000055": [
50,
100,
50
],
"000056": [
25,
100,
50
],
"000058": [
25,
0,
50
],
"000060": [
75,
0,
50
],
"000064": [
25,
100,
50
],
"000065": [
75,
100,
50
],
"000068": [
50,
100,
50
],
"000069": [
75,
100,
50
],
"000071": [
50,
0,
0
],
"000073": [
50,
0,
50
],
"000076": [
75,
100,
50
],
"000077": [
25,
0,
50
],
"000078": [
75,
0,
50
],
"000079": [
75,
100,
50
],
"000080": [
50,
100,
50
],
"000081": [
50,
100,
100
],
"000083": [
50,
0,
50
],
"000085": [
50,
0,
50
],
"000086": [
50,
0,
0
],
"000088": [
25,
0,
50
],
"000091": [
25,
100,
50
],
"000092": [
50,
0,
0
],
"000096": [
100,
0,
50
],
"000097": [
25,
0,
0
],
"000099": [
50,
0,
0
],
"000100": [
25,
0,
0
],
"000103": [
50,
0,
50
],
"000104": [
25,
0,
0
],
"000106": [
50,
0,
0
],
"000108": [
50,
0,
0
],
"000109": [
75,
100,
50
],
"000110": [
50,
0,
0
],
"000111": [
75,
0,
0
],
"000114": [
50,
100,
50
],
"000115": [
50,
100,
0
],
"000116": [
50,
100,
50
],
"000117": [
100,
0,
100
],
"000118": [
75,
0,
50
],
"000121": [
50,
0,
50
],
"000122": [
25,
0,
0
],
"000125": [
50,
100,
0
],
"000126": [
75,
0,
0
],
"000129": [
50,
100,
50
],
"000131": [
75,
0,
50
],
"000132": [
75,
0,
50
],
"000133": [
75,
0,
0
],
"000134": [
100,
100,
100
],
"000135": [
75,
100,
100
],
"000137": [
50,
100,
50
],
"000140": [
75,
0,
0
],
"000142": [
25,
0,
50
],
"000143": [
50,
100,
50
],
"000145": [
50,
0,
50
],
"000146": [
75,
0,
50
],
"000147": [
75,
0,
0
],
"000148": [
50,
0,
50
],
"000150": [
25,
100,
50
],
"000151": [
50,
0,
50
],
"000152": [
75,
100,
0
],
"000153": [
75,
100,
50
],
"000155": [
50,
0,
50
],
"000156": [
25,
0,
0
],
"000157": [
50,
0,
0
],
"000160": [
25,
100,
50
],
"000161": [
25,
0,
50
],
"000016": [
75,
100,
50
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// other variables can be in here too
// these control the colors used
function SalazarFace() {
const bg_color = [225, 206, 187];
const fg_color = "#A19588";
const stroke_color = [95, 52, 8];
// these are state variables for a face
// (your variables may be different)
this.eye_value = 0;
this.mouth_value = 0;
this.eyebrow_value = 0;
this.nose_value = 0;
this.outline_value = 0;
this.skin_tone = [
"#FDEFD6", "#F7DABD", "#EDBC9B", "#D6A37E", "#BD836D","#87563F"
]
this.hair_tone = [
"#edbc9b", "#edbc9b", "#e9858f", "#ed9ba3", "#f1b1b7", "#f5c6cb"
]
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
let pos_leftcheek = positions.chin[2];
let pos_rightcheek = positions.chin[15];
let pos_bottomcheek = positions.chin[7];
let pos_bottomcheek2 = positions.chin[9];
let pos_lefteye = average_point(positions.left_eye);
let pos_righteye = average_point(positions.right_eye);
let pos_lefteyeline = positions.left_eye[0];
let pos_lefteyeline2 = positions.left_eye[2];
let pos_lefteyeline3 = positions.left_eye[3];
let pos_righteyeline = positions.right_eye[0];
let pos_righteyeline2 = positions.right_eye[2];
let pos_righteyeline3 = positions.right_eye[3];
let pos_rightbrow = positions.right_eyebrow[1];
let pos_rightbrow2 = positions.right_eyebrow[4];
let pos_rightbrow3 = positions.right_eyebrow[2];
let pos_leftbrow = positions.left_eyebrow[2];
let pos_leftbrow2 = positions.left_eyebrow[4];
// let pos_bottomlip = average_point(positions.bottom_lip)
// let pos_toplip = average_point(positions.top_lip)
let pos_bottomleftlip = positions.bottom_lip[6];
let pos_bottomleftlip2 = positions.bottom_lip[6];
let pos_bottommidlip = positions.bottom_lip[3];
let pos_bottomrightlip = positions.bottom_lip[0];
let pos_bottomrightlip2 = positions.bottom_lip[11];
let pos_topleftlip = positions.top_lip[0];
let pos_topleftlip2 = positions.top_lip[0];
let pos_topmidlip = positions.top_lip[4];
let pos_topmidlip2 = positions.top_lip[2];
let pos_topmidlip3 = positions.top_lip[3];
let pos_toprightlip = positions.top_lip[6];
let pos_toprightlip2 = positions.top_lip[7];
let pos_nosetip = positions.nose_tip[0];
let pos_nosetip2 = positions.nose_tip[3];
let pos_nosebridge = positions.nose_bridge[4];
//FACE
push();
fill(this.skin_tone[this.skin_tone_value]);
noStroke()
beginShape();
vertex(0, -3)
quadraticVertex(2, -3, 2, 0);
quadraticVertex(2, 2, 0, 2);
quadraticVertex(-2, 2, -2,0);
quadraticVertex(-2, -3, 0, -3);
endShape();
pop();
//FACE OUTLINE
push();
scale(1.1);
noFill();
translate(0.2,0.1);
strokeWeight(this.outline_value);
stroke(this.hair_tone[this.hair_tone_value]);
beginShape();
vertex(0, -3)
quadraticVertex(2, -3, 2, 0);
quadraticVertex(2, 2, 0, 2);
quadraticVertex(-2, 2, -2,0);
quadraticVertex(-2, -3, 0, -3);
endShape();
pop();
//NOSE
push();
noFill();
stroke(0);
strokeWeight(0.1);
//EYEBROW
beginShape();
vertex(pos_nosetip[0],pos_nosetip[1]);
bezierVertex(pos_nosetip2[0],0.7+this.nose_value,pos_nosetip2[1]-0.5, pos_rightbrow3[1]-this.eyebrow_value-1,pos_rightbrow2[0], pos_rightbrow2[1]);
endShape();
pop();
//MOUTH
beginShape();
fill(0);
vertex(pos_topleftlip[0], pos_topleftlip[1]);
quadraticVertex(pos_topmidlip[0], pos_topmidlip[1]+0.3, pos_toprightlip[0], pos_toprightlip[1]);
quadraticVertex(pos_topmidlip[0], pos_topmidlip[1], pos_topmidlip3[0], pos_topmidlip3[1]);
quadraticVertex(pos_topmidlip2[0], pos_topmidlip2[1], pos_topleftlip[0], pos_topleftlip[1]);
endShape();
beginShape();
fill(0);
vertex(pos_bottomleftlip[0], pos_bottomleftlip[1] );
quadraticVertex(pos_bottommidlip[0], pos_bottommidlip[1] +0.5 + this.mouth_value, pos_bottomrightlip[0], pos_bottomrightlip[1]);
quadraticVertex(pos_bottommidlip[0], pos_bottommidlip[1] -0.2 + this.mouth_value, pos_bottomleftlip2[0], pos_bottomleftlip2[1]);
endShape();
//EYES
push();
fill(0);
noStroke();
arc(pos_lefteye[0], pos_lefteye[1]-0.02, 0.5+this.eye_value, 0.5+this.eye_value, 360, 180);
arc(pos_righteye[0],pos_righteye[1]-0.02, 0.5+this.eye_value, 0.5+this.eye_value, 360, 180);
pop();
push();
noFill();
stroke(0);
strokeWeight(0.1);
beginShape();
vertex(pos_lefteyeline[0],pos_lefteyeline[1]);
quadraticVertex(pos_lefteyeline2[0],pos_lefteyeline2[1],pos_lefteyeline3[0],pos_lefteyeline3[1]);
endShape();
beginShape();
vertex(pos_righteyeline[0],pos_righteyeline[1]);
quadraticVertex(pos_righteyeline2[0],pos_righteyeline2[1],pos_righteyeline3[0],pos_righteyeline3[1]);
endShape();
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
// print(settings);
this.eye_value = map(settings[0], 0, 100, -0.3, 0.3);
this.eyebrow_value = map(settings[1],0,100,-0.7, 0.7);
this.mouth_value = map(settings[2], 0, 100, -0.5, 0.5);
this.nose_value = map(settings[3],0,100,-0.5,0.5);
this.outline_value = map(settings[4],0,100,0,0.3);
this.skin_tone_value = int(map(settings[5], 0, 100, 0, 5));
this.hair_tone_value = int(map(settings[6], 0, 100,0, 5));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(5);
settings[0] = map( this.eye_value, -0.3, 0.3, 0, 100);
settings[1] = map( this.eyebrow_value, -0.7, 0.7, 0, 100);
settings[2] = map( this.mouth_value, -0.5, 0.5, 0, 100);
settings[3] = map( this.nose_value, -0.5,0.5, 0, 100);
settings[4] = map( this.outline_value, 0,0.3, 0, 100);
settings[5] = map(this.skin_tone_value, 0,5,0,100);
settings[6] = map(this.hair_tone_value, 0, 5, 0, 100);
return settings;
}
}
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
54,
28,
64,
30,
100,
70,
45
],
"000161": [
50,
50,
50,
50,
100,
0,
40
],
"000160": [
50,
50,
50,
50,
13,
20,
40
],
"000157": [
50,
50,
50,
50,
100,
20,
40
],
"000156": [
50,
50,
50,
50,
100,
0,
40
],
"000155": [
68,
20,
74,
41,
100,
40,
40
],
"000153": [
50,
50,
50,
50,
15,
40,
40
],
"000152": [
50,
50,
50,
50,
3,
20,
40
],
"000151": [
50,
50,
50,
50,
100,
40,
40
],
"000150": [
50,
50,
50,
50,
10,
0,
40
],
"000148": [
50,
50,
50,
50,
100,
20,
40
],
"000147": [
50,
50,
50,
50,
100,
40,
40
],
"000146": [
50,
50,
50,
50,
100,
60,
40
],
"000145": [
50,
50,
50,
50,
100,
40,
40
],
"000143": [
50,
50,
50,
50,
8,
40,
40
],
"000142": [
50,
50,
50,
50,
100,
20,
40
],
"000140": [
50,
50,
50,
50,
100,
40,
40
],
"000137": [
50,
50,
50,
50,
10,
0,
40
],
"000135": [
50,
50,
50,
50,
1,
80,
40
],
"000134": [
50,
50,
50,
50,
5,
100,
40
],
"000133": [
50,
50,
50,
50,
100,
40,
40
],
"000132": [
50,
50,
50,
50,
100,
60,
40
],
"000131": [
50,
50,
50,
50,
100,
60,
60
],
"000129": [
26,
30,
77,
50,
7.000000000000001,
20,
40
],
"000126": [
50,
50,
50,
50,
100,
40,
40
],
"000125": [
50,
50,
50,
50,
5,
40,
40
],
"000122": [
50,
50,
50,
50,
100,
0,
40
],
"000121": [
50,
50,
50,
50,
100,
60,
40
],
"000118": [
60,
32,
31,
91,
100,
40,
40
],
"000117": [
71,
42,
68,
0,
100,
100,
40
],
"000116": [
28.999999999999996,
4.0000000000000036,
86,
16.000000000000004,
18,
20,
40
],
"000002": [
63,
15,
64,
63,
100,
0,
40
],
"000005": [
63,
8,
64,
50,
100,
20,
20
],
"000006": [
65,
44,
69,
2.0000000000000018,
100,
80,
60
],
"000007": [
16,
50,
30,
50,
11.000000000000002,
40,
40
],
"000009": [
37,
0,
72,
50,
99,
40,
60
],
"000010": [
70,
30,
50,
52,
100,
20,
0
],
"000013": [
19,
0,
74,
0,
6,
0,
0
],
"000014": [
70,
26,
59,
69,
100,
60,
40
],
"000015": [
17,
4.0000000000000036,
61,
30,
13,
0,
40
],
"000016": [
16,
20,
50,
9.999999999999998,
10,
40,
40
],
"000018": [
23.000000000000004,
0,
67,
57.99999999999999,
100,
20,
100
],
"000020": [
47,
20,
90,
0,
6,
40,
60
],
"000023": [
35,
0,
76,
100,
9,
40,
40
],
"000025": [
63,
23,
13,
18,
6,
20,
60
],
"000028": [
40,
0,
77,
50,
100,
60,
40
],
"000029": [
65,
43,
50,
96,
100,
20,
60
],
"000030": [
88.00000000000001,
22,
26,
0,
21.000000000000004,
40,
100
],
"000031": [
32,
26,
77,
17.000000000000004,
100,
20,
80
],
"000032": [
35,
24,
71,
21.999999999999996,
19,
20,
100
],
"000035": [
56.99999999999999,
24,
65,
14.000000000000002,
100,
20,
40
],
"000037": [
64,
0,
42,
0,
10,
60,
40
],
"000038": [
40,
0,
79,
0,
6,
20,
80
],
"000040": [
56.99999999999999,
0,
37,
33,
100,
40,
60
],
"000041": [
43.00000000000001,
15,
50,
0,
9,
80,
40
],
"000042": [
56.99999999999999,
9.000000000000002,
34,
35,
98,
20,
100
],
"000043": [
63,
17,
50,
28.000000000000004,
100,
40,
40
],
"000044": [
64,
31,
53,
100,
100,
100,
40
],
"000045": [
38,
0,
67,
28.999999999999996,
100,
60,
80
],
"000047": [
25,
60,
68,
20.999999999999996,
100,
80,
40
],
"000048": [
36,
100,
28.000000000000004,
0,
22.000000000000004,
0,
80
],
"000050": [
61,
11.999999999999995,
73,
35,
6,
40,
60
],
"000051": [
63,
0,
23,
14.000000000000002,
2,
20,
0
],
"000052": [
33,
0,
17.000000000000004,
16.000000000000004,
7.000000000000001,
40,
60
],
"000054": [
56.00000000000001,
20,
63,
59,
99,
20,
100
],
"000055": [
60,
26,
45,
17.000000000000004,
13,
40,
40
],
"000056": [
71,
100,
26,
34,
6,
20,
100
],
"000058": [
24,
3.000000000000003,
50,
25,
100,
0,
60
],
"000060": [
26,
50,
62,
50,
13,
100,
80
],
"000064": [
27,
0,
77,
7.000000000000001,
5,
20,
80
],
"000065": [
61,
24,
54,
50,
8,
40,
40
],
"000068": [
78,
45,
66,
13,
11.000000000000002,
40,
100
],
"000069": [
50,
50,
50,
50,
17,
20,
40
],
"000077": [
65,
0,
50,
20,
99,
80,
40
],
"000091": [
17,
17,
50,
73,
15,
20,
40
],
"000092": [
37,
15,
24,
18,
100,
0,
0
],
"000096": [
50,
50,
50,
50,
50,
60,
40
],
"000097": [
50,
50,
50,
50,
50,
0,
40
],
"000099": [
50,
50,
50,
50,
50,
0,
40
],
"000100": [
39,
1.0000000000000009,
32,
50,
100,
80,
0
],
"000103": [
50,
50,
50,
71,
100,
60,
40
],
"000104": [
50,
50,
50,
50,
9,
0,
20
],
"000080": [
50,
50,
50,
50,
18,
60,
0
],
"000115": [
37,
2.0000000000000018,
50,
13,
0,
0,
0
],
"000114": [
73,
0,
79,
23,
4,
20,
40
],
"000111": [
37,
23,
50,
68,
100,
80,
60
],
"000110": [
62,
21,
80,
0,
100,
20,
60
],
"000109": [
47,
18.999999999999996,
73,
54,
14.000000000000002,
40,
60
],
"000106": [
62,
50,
50,
50,
100,
60,
40
],
"000108": [
66,
36.00000000000001,
73,
18,
100,
20,
0
],
"000088": [
53,
4.0000000000000036,
50,
30,
100,
60,
60
],
"000086": [
59,
28.000000000000004,
74,
6,
100,
0,
80
],
"000085": [
70,
32,
36,
100,
100,
0,
60
],
"000083": [
41,
18.999999999999996,
49,
20.999999999999996,
100,
20,
60
],
"000081": [
72,
13.999999999999998,
79,
28.000000000000004,
4,
60,
40
],
"000079": [
69,
28.999999999999996,
26,
57.99999999999999,
0,
40,
40
],
"000078": [
49,
0,
44,
0,
100,
40,
60
],
"000076": [
51,
42,
23,
50,
2,
40,
40
],
"000073": [
63,
33,
57.99999999999999,
0,
100,
20,
80
],
"000071": [
46.00000000000001,
3.000000000000003,
72,
53,
100,
20,
20
]
}
[
"oscar_selfie.jpg",
"z_group_pic.jpg",
"z_group_pic2.jpg",
"z_single1.jpg",
"z_single2.jpg",
"z_single3.jpg",
"williams.jpg"
]
!function(a,b){function c(c,j,k){var n=[];j=1==j?{entropy:!0}:j||{};var s=g(f(j.entropy?[c,i(a)]:null==c?h():c,3),n),t=new d(n),u=function(){for(var a=t.g(m),b=p,c=0;a<q;)a=(a+c)*l,b*=l,c=t.g(1);for(;a>=r;)a/=2,b/=2,c>>>=1;return(a+c)/b};return u.int32=function(){return 0|t.g(4)},u.quick=function(){return t.g(4)/4294967296},u.double=u,g(i(t.S),a),(j.pass||k||function(a,c,d,f){return f&&(f.S&&e(f,t),a.state=function(){return e(t,{})}),d?(b[o]=a,c):a})(u,s,"global"in j?j.global:this==b,j.state)}function d(a){var b,c=a.length,d=this,e=0,f=d.i=d.j=0,g=d.S=[];for(c||(a=[c++]);e<l;)g[e]=e++;for(e=0;e<l;e++)g[e]=g[f=s&f+a[e%c]+(b=g[e])],g[f]=b;(d.g=function(a){for(var b,c=0,e=d.i,f=d.j,g=d.S;a--;)b=g[e=s&e+1],c=c*l+g[s&(g[e]=g[f=s&f+b])+(g[f]=b)];return d.i=e,d.j=f,c})(l)}function e(a,b){return b.i=a.i,b.j=a.j,b.S=a.S.slice(),b}function f(a,b){var c,d=[],e=typeof a;if(b&&"object"==e)for(c in a)try{d.push(f(a[c],b-1))}catch(a){}return d.length?d:"string"==e?a:a+"\0"}function g(a,b){for(var c,d=a+"",e=0;e<d.length;)b[s&e]=s&(c^=19*b[s&e])+d.charCodeAt(e++);return i(b)}function h(){try{var b;return j&&(b=j.randomBytes)?b=b(l):(b=new Uint8Array(l),(k.crypto||k.msCrypto).getRandomValues(b)),i(b)}catch(b){var c=k.navigator,d=c&&c.plugins;return[+new Date,k,d,k.screen,i(a)]}}function i(a){return String.fromCharCode.apply(0,a)}var j,k=this,l=256,m=6,n=52,o="random",p=b.pow(l,m),q=b.pow(2,n),r=2*q,s=l-1;if(b["seed"+o]=c,g(b.random(),a),"object"==typeof module&&module.exports){module.exports=c;try{j=require("crypto")}catch(a){}}else"function"==typeof define&&define.amd&&define(function(){return c})}([],Math);
<head>
<style> body {padding: 0; margin: 0;} </style>
</head>
<body style="background-color:white">
<img src="same_pose.jpg" width="960" height="500"/><br>
Same Pose
<hr>
<img src="same_subject.jpg" width="960" height="500"/><br>
Same Subject
<p>
<a href="index.html">program</a>
</body>
// Remove or set to false to enable full program
//var DEBUG_MODE = true;
// Set the number of sliders to show
// var NUM_SLIDERS = 7;
// Given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i = 0; i < s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len, sum_y / s_len];
}
function ToFace() {
// State variables
const purpleEyes = color(222, 181, 255);
const pinkEyes = color(255, 181, 227);
const blueEyes = color(158, 196, 255);
const aquaEyes = color(161, 224, 230);
// Set default slider values
this.bubbleSize = 4.6; // Range is from 4 - 5
this.faceTone = 50; // Range is from 0 - 100
this.browType = 1; // Can be either 1 or 2
this.browTilt = 5; // Range is from 0 - 10
this.eyeColor = 1; // Can be either 1, 2, 3 or 4
this.blushType = 1; // Can be either 1 or 2
this.cheekPos = 21; // Range is from 0 - 100
// Draws a segment, do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if (i < segment.length - 1) {
let nx = segment[i + 1][0];
let ny = segment[i + 1][1];
line(px, py, nx, ny);
} else if (do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
this.draw = function(positions) {
let redValue = map(this.faceTone, 0, 100, 227, 196);
let greenValue = map(this.faceTone, 0, 100, 238, 219);
let facePos = segment_average(positions.chin);
// Draw bubble
stroke(196, 219, 255);
strokeWeight(0.3);
fill(redValue, greenValue, 255);
ellipse(facePos[0], facePos[0], -this.bubbleSize, this.bubbleSize);
// Draw upper bubble shine
noStroke();
strokeWeight(0.05);
fill(255);
beginShape();
vertex(facePos[0] + 0.1 * this.bubbleSize, facePos[0] - 0.4 * this.bubbleSize);
bezierVertex(facePos[0] + 0.15 * this.bubbleSize, facePos[0] - 0.45 * this.bubbleSize, facePos[0] + 0.35 * this.bubbleSize, facePos[0] - 0.3 * this.bubbleSize, facePos[0] + 0.4 * this.bubbleSize, facePos[0] - 0.15 * this.bubbleSize);
bezierVertex(facePos[0] + 0.27 * this.bubbleSize, facePos[0] - 0.3 * this.bubbleSize, facePos[0] + 0.24 * this.bubbleSize, facePos[0] - 0.28 * this.bubbleSize, facePos[0] + 0.2 * this.bubbleSize, facePos[0] - 0.3 * this.bubbleSize);
bezierVertex(facePos[0] + 0.2 * this.bubbleSize, facePos[0] - 0.3 * this.bubbleSize, facePos[0] + 0.02 * this.bubbleSize, facePos[0] - 0.35 * this.bubbleSize, facePos[0] + 0.1 * this.bubbleSize, facePos[0] - 0.4 * this.bubbleSize);
endShape();
// Draw lower bubble shine
push();
translate(-0.45, 0.45)
scale(0.7);
beginShape();
vertex(facePos[0] - 0.1 * this.bubbleSize, facePos[0] + 0.4 * this.bubbleSize);
bezierVertex(facePos[0] - 0.15 * this.bubbleSize, facePos[0] + 0.45 * this.bubbleSize, facePos[0] - 0.35 * this.bubbleSize, facePos[0] + 0.3 * this.bubbleSize, facePos[0] - 0.4 * this.bubbleSize, facePos[0] + 0.15 * this.bubbleSize);
bezierVertex(facePos[0] - 0.27 * this.bubbleSize, facePos[0] + 0.3 * this.bubbleSize, facePos[0] - 0.24 * this.bubbleSize, facePos[0] + 0.28 * this.bubbleSize, facePos[0] - 0.2 * this.bubbleSize, facePos[0] + 0.3 * this.bubbleSize);
bezierVertex(facePos[0] - 0.2 * this.bubbleSize, facePos[0] + 0.3 * this.bubbleSize, facePos[0] - 0.02 * this.bubbleSize, facePos[0] + 0.35 * this.bubbleSize, facePos[0] - 0.1 * this.bubbleSize, facePos[0] + 0.4 * this.bubbleSize);
endShape();
pop();
// Draw brows
let leftBrowLeft = positions.left_eyebrow[0];
let leftBrowTop = positions.left_eyebrow[2];
let leftBrowRight = positions.left_eyebrow[4];
let rightBrowLeft = positions.right_eyebrow[0];
let rightBrowTop = positions.right_eyebrow[2];
let rightBrowRight = positions.right_eyebrow[4];
stroke(162, 191, 235);
strokeWeight(0.15);
if (this.browType == 1) { // Feminine brows
push();
rotate(-this.browTilt);
line(leftBrowLeft[0], leftBrowLeft[1] + 0.3, leftBrowTop[0], leftBrowTop[1]); // Left pointed brow
line(leftBrowTop[0], leftBrowTop[1], leftBrowRight[0], leftBrowRight[1] + 0.3);
rotate(this.browTilt * 2);
line(rightBrowLeft[0], rightBrowLeft[1] + 0.3, rightBrowTop[0], rightBrowTop[1]); // Right pointed brow
line(rightBrowTop[0], rightBrowTop[1], rightBrowRight[0], rightBrowRight[1] + 0.3);
pop();
} else if (this.browType == 2) { // Masculine brows
push();
strokeWeight(0.4);
rotate(-this.browTilt); // Left brow
line(leftBrowLeft[0], leftBrowLeft[0] + 0.3, leftBrowRight[0], leftBrowRight[1] + 0.3);
rotate(this.browTilt * 2); // Right brow
line(rightBrowLeft[0], rightBrowLeft[1] + 0.3, rightBrowRight[0], rightBrowRight[1] + 0.3);
pop();
}
// Draw eyes
let leftEyePos = segment_average(positions.left_eye);
let rightEyePos = segment_average(positions.right_eye);
let leftEyeShine = positions.left_eye[4];
let rightEyeShine = positions.right_eye[4];
if (this.eyeColor == 1) { // 1 = purple eyes (feminine brown eyes)
fill(purpleEyes);
} else if (this.eyeColor == 2) { // 2 = pink eyes (feminine other colour)
fill(pinkEyes);
} else if (this.eyeColor == 3) { // 3 = blue eyes (masculine brown eyes)
fill(blueEyes);
} else if (this.eyeColor == 4) { // 4 = aqua eyes (masculine other colour)
fill(aquaEyes);
}
stroke(255); // Eyes
strokeWeight(0.2)
ellipse(leftEyePos[0], leftEyePos[0] + 0.8, 1);
ellipse(rightEyePos[0], leftEyePos[0] + 0.8, 1);
fill(255); // Eye shine
ellipse(leftEyeShine[0], leftEyeShine[0] + 0.5, 0.15);
ellipse(rightEyeShine[0], leftEyeShine[0] + 0.5, 0.15);
// Draw blush
let blushShift = map(this.cheekPos, 0, 100, -1, 1);
let leftBlush = positions.chin[4];
let rightBlush = positions.chin[12];
if (this.blushType == 1) { // Feminine blush
noStroke();
fill(255, 181, 227);
ellipse(leftBlush[0] + blushShift, leftBlush[1] - 0.1, 0.6, 0.25);
ellipse(rightBlush[0] + blushShift, rightBlush[1] - 0.1, 0.6, 0.25);
} else if (this.blushType == 2) { // Masculine blush
stroke(162, 191, 235);
strokeWeight(0.1);
noFill();
beginShape(); // Left cheek squiggle blush
curveVertex(-1.7 + blushShift, 0.8);
curveVertex(-1.7 + blushShift, 0.8);
curveVertex(-1 + blushShift, 0.8);
curveVertex(-1.4 + blushShift, 1);
curveVertex(-1 + blushShift, 1);
curveVertex(-1 + blushShift, 1);
endShape();
beginShape(); // Right cheek squiggle blush
curveVertex(1.7 + blushShift, 0.8);
curveVertex(1.7 + blushShift, 0.8);
curveVertex(1 + blushShift, 0.8);
curveVertex(1.4 + blushShift, 1);
curveVertex(1 + blushShift, 1);
curveVertex(1 + blushShift, 1);
endShape();
}
// Draw mouth
let mouthPos = segment_average(positions.bottom_lip);
noFill(); // Mouth
stroke(162, 191, 235);
strokeWeight(0.2);
arc(mouthPos[0] - 0.4, mouthPos[1] + 0.2, 0.6, 0.6, 0, 180);
arc(mouthPos[0] + 0.2, mouthPos[1] + 0.2, 0.6, 0.6, 0, 180);
}
// Set internal properties based on list numbers 0-100
this.setProperties = function(settings) {
this.bubbleSize = map(settings[0], 0, 100, 4.2, 5);
this.faceTone = map(settings[1], 0, 100, 0, 100);
this.browType = int(map(settings[2], 0, 100, 1, 2));
this.browTilt = map(settings[3], 0, 100, 0, 10);
this.eyeColor = int(map(settings[4], 0, 100, 1, 4));
this.blushType = int(map(settings[5], 0, 100, 1, 2));
this.cheekPos = map(settings[6], 0, 100, 0, 100);
}
// Get internal properties as list of numbers 0-100
this.getProperties = function() {
let settings = new Array(7);
settings[0] = map(this.bubbleSize, 4.2, 5, 0, 100);
settings[1] = map(this.faceTone, 0, 100, 0, 100);
settings[2] = map(this.browType, 1, 2, 0, 100);
settings[3] = map(this.browTilt, 0, 10, 0, 100);
settings[4] = map(this.eyeColor, 1, 4, 0, 100);
settings[5] = map(this.blushType, 1, 2, 0, 100);
settings[6] = map(this.cheekPos, 0, 100, 0, 100);
return settings;
}
}
{
"000001": [
43,
43,
25,
39,
16,
25,
50
],
"000002": [
14.000000000000016,
0,
0,
71,
0,
0,
28.999999999999996
],
"000005": [
22.000000000000025,
7.000000000000001,
0,
100,
40,
0,
48
],
"000006": [
24.00000000000003,
62,
0,
51,
0,
0,
65
],
"000007": [
67.99999999999996,
30,
100,
100,
70,
100,
45
],
"000009": [
47.00000000000005,
6,
0,
66,
0,
0,
66
],
"000010": [
39.00000000000004,
7.000000000000001,
0,
64,
40,
0,
50
],
"000013": [
67.99999999999996,
27,
100,
100,
100,
100,
47
],
"000014": [
25.00000000000003,
82,
0,
32,
0,
0,
66
],
"000015": [
71.99999999999996,
0,
100,
82,
100,
100,
49
],
"000016": [
76.99999999999999,
39,
100,
28.000000000000004,
70,
100,
45
],
"000018": [
35.000000000000036,
0,
0,
50,
40,
0,
53
],
"000020": [
57.99999999999995,
11,
100,
100,
70,
100,
48
],
"000023": [
80.99999999999999,
3,
100,
61,
100,
100,
48
],
"000025": [
70.99999999999996,
0,
100,
54,
70,
100,
47
],
"000028": [
74.99999999999997,
51,
0,
30,
0,
0,
48
],
"000029": [
38.00000000000004,
10,
0,
34,
40,
0,
53
],
"000030": [
49.00000000000006,
27,
100,
65,
70,
100,
45
],
"000031": [
49.00000000000006,
3,
0,
86.99999999999999,
40,
0,
51
],
"000032": [
70.99999999999996,
9,
100,
67,
70,
100,
50
],
"000035": [
37.000000000000036,
0,
0,
100,
0,
0,
51
],
"000037": [
62.99999999999996,
73,
100,
0,
70,
100,
47
],
"000038": [
82.99999999999999,
0,
100,
41,
100,
100,
51
],
"000040": [
61.99999999999996,
0,
0,
100,
0,
0,
56.99999999999999
],
"000041": [
75.99999999999997,
30,
100,
0,
70,
100,
47
],
"000042": [
49.00000000000006,
0,
0,
15,
40,
0,
56.00000000000001
],
"000043": [
37.000000000000036,
0,
0,
76,
0,
0,
54
],
"000044": [
24.00000000000003,
92,
0,
75,
0,
0,
46
],
"000045": [
37.000000000000036,
35,
0,
88.00000000000001,
0,
0,
47
],
"000047": [
39.00000000000004,
60,
0,
76,
0,
0,
46
],
"000048": [
72.99999999999997,
0,
100,
37,
70,
100,
46
],
"000050": [
84.99999999999999,
20,
100,
55.00000000000001,
70,
100,
47
],
"000051": [
84.99999999999999,
28.999999999999996,
100,
45,
70,
100,
46
],
"000052": [
86.99999999999999,
51,
100,
20,
100,
100,
47
],
"000054": [
51.00000000000006,
0,
0,
52,
40,
0,
47
],
"000055": [
70.99999999999996,
0,
100,
64,
70,
100,
44
],
"000056": [
51.00000000000006,
0,
0,
0,
40,
0,
66
],
"000058": [
53.00000000000006,
0,
0,
55.00000000000001,
40,
0,
52
],
"000060": [
62.99999999999996,
85,
100,
30,
70,
100,
44
],
"000064": [
71.99999999999996,
0,
100,
46.99999999999999,
100,
100,
47
],
"000065": [
71.99999999999996,
37,
100,
24,
70,
100,
47
],
"000068": [
56.99999999999995,
14.000000000000002,
100,
95,
70,
100,
47
],
"000069": [
80.99999999999999,
7.000000000000001,
100,
100,
70,
100,
47
],
"000071": [
65.99999999999996,
15,
0,
23.000000000000004,
40,
0,
45
],
"000073": [
55.00000000000006,
8,
0,
86,
0,
0,
25
],
"000076": [
70.99999999999996,
22,
100,
39,
70,
100,
45
],
"000077": [
70.99999999999996,
0,
0,
56.00000000000001,
0,
0,
39
],
"000161": [
22.000000000000025,
0,
0,
66,
40,
0,
44
],
"000160": [
82.99999999999999,
20,
100,
32,
70,
100,
47
],
"000157": [
51.99999999999994,
11,
0,
3,
40,
0,
53
],
"000156": [
35.000000000000036,
0,
0,
82.99999999999999,
40,
0,
41
],
"000155": [
9.000000000000009,
18,
0,
71,
0,
0,
43
],
"000153": [
63.99999999999996,
1,
100,
73,
70,
100,
48
],
"000152": [
71.99999999999996,
13,
100,
45,
100,
100,
48
],
"000151": [
47.00000000000005,
48,
0,
0,
0,
0,
54
],
"000150": [
78.99999999999999,
0,
100,
100,
70,
100,
50
],
"000148": [
40.00000000000005,
0,
0,
21.000000000000004,
40,
0,
76
],
"000147": [
37.000000000000036,
22,
0,
82.99999999999999,
40,
0,
51
],
"000146": [
33.000000000000036,
41,
0,
52,
0,
0,
92
],
"000145": [
21.000000000000025,
13,
0,
23.000000000000004,
0,
0,
61
],
"000143": [
73.99999999999997,
8,
100,
46.99999999999999,
100,
100,
49
],
"000142": [
32.000000000000036,
0,
0,
41,
40,
0,
56.00000000000001
],
"000140": [
35.000000000000036,
25,
0,
100,
40,
0,
56.99999999999999
],
"000137": [
67.99999999999996,
0,
100,
24,
100,
100,
53
],
"000135": [
75.99999999999997,
59,
100,
35,
70,
100,
48
],
"000134": [
62.99999999999996,
100,
100,
38,
70,
100,
46
],
"000133": [
35.000000000000036,
6,
0,
54,
40,
0,
56.99999999999999
],
"000132": [
9.000000000000009,
45,
0,
68,
0,
0,
37
],
"000131": [
27.00000000000003,
62,
0,
77,
0,
0,
32
],
"000129": [
70.99999999999996,
2,
100,
49.00000000000001,
70,
100,
47
],
"000126": [
39.00000000000004,
49,
0,
61,
40,
0,
39
],
"000125": [
77.99999999999999,
14.000000000000002,
100,
59,
100,
100,
47
],
"000122": [
21.000000000000025,
0,
0,
55.00000000000001,
0,
0,
48
],
"000121": [
20.000000000000025,
32,
0,
49.00000000000001,
0,
0,
49
],
"000118": [
19.00000000000002,
37,
0,
20,
0,
0,
74
],
"000117": [
23.000000000000025,
79,
0,
31,
0,
0,
37
],
"000116": [
83.99999999999999,
0,
100,
27,
70,
100,
47
],
"000115": [
63.99999999999996,
0,
100,
0,
100,
100,
49
],
"000114": [
82.99999999999999,
0,
100,
0,
70,
100,
47
],
"000111": [
20.000000000000025,
62,
0,
62,
0,
0,
35
],
"000110": [
18.000000000000018,
5,
0,
65,
40,
0,
52
],
"000078": [
8.000000000000009,
25,
0,
82.99999999999999,
40,
0,
56.00000000000001
],
"000079": [
78.99999999999999,
40,
100,
10,
70,
100,
49
],
"000080": [
75.99999999999997,
12,
100,
31,
100,
100,
47
],
"000081": [
75.99999999999997,
26,
100,
1,
70,
100,
46
],
"000083": [
25.00000000000003,
0,
0,
59,
40,
0,
48
],
"000085": [
31.000000000000032,
0,
0,
60,
40,
0,
48
],
"000086": [
8.000000000000009,
0,
0,
100,
40,
0,
67
],
"000088": [
31.000000000000032,
6,
0,
100,
0,
0,
33
],
"000091": [
87.99999999999999,
0,
100,
56.00000000000001,
70,
100,
48
],
"000092": [
28.000000000000032,
3,
0,
100,
40,
0,
62
],
"000096": [
22.000000000000025,
15,
0,
100,
0,
0,
55.00000000000001
],
"000097": [
33.000000000000036,
0,
0,
100,
40,
0,
47
],
"000099": [
27.00000000000003,
0,
0,
66,
40,
0,
51
],
"000100": [
23.000000000000025,
0,
0,
100,
0,
0,
62
],
"000103": [
27.00000000000003,
0,
0,
76,
40,
0,
62
],
"000104": [
80.99999999999999,
0,
100,
46.99999999999999,
100,
100,
48
],
"000106": [
27.00000000000003,
22,
0,
88.00000000000001,
0,
0,
67
],
"000108": [
17.000000000000018,
3,
0,
100,
40,
0,
56.00000000000001
],
"000109": [
73.99999999999997,
17,
100,
72,
100,
100,
48
]
}
/*
* FaceMap class - holds all information about one mapped
* face and is able to draw itself.
*/
// other variables can be in here too
// these control the colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
function TrewavasFace() {
// these are state variables for a face
// (your variables may be different)
this.eye_value = 2; // can be either 2 (eyes) or 3 (no eyes)
this.mouth_value = 1; // range is 0.5 to 8
this.tilt_value = 0; // range is -30 to 30
this.chin_val = 5; //1, 5
this.head_width = 5; //5, 10
this.eye_pos = 3; // 3, 6
this.mouthEmo = 1; // 0.5, 1.5
this.noseX = 1; // 0.5, 2
this.eyebrow_y = -3; // -4, -2.5
this.eyebrow_emo = 1; // 0.8, 1.2
this.skin_val = 0; // 0, 5
this.age = 0; // 0, 6
this.face_size = 1; // 0.5, 1
this.eyebrow_thick = 0.5;
this.eyebrowTween = 0.5;
this.skinColor = [];
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
push();
scale(0.45);
angleMode(DEGREES);
rectMode(CENTER);
ellipseMode(CENTER);
strokeCap(ROUND);
colorMode(RGB);
noStroke();
noFill();
//Skin Colours
this.light_light_tone = color(244, 212, 187);
this.light_tone = color(248, 196, 161);
this.light_mid_tone = color(229, 202, 155);
this.mid_tone = color(219, 169, 116);
this.mid_dark_tone = color(145, 96, 56);
this.dark_tone = color(110,64,28);
this.dark_dark_tone = color(87, 69, 57);
this.skinColor = [this.light_light_tone, this.light_tone, this.light_mid_tone, this.mid_tone, this.mid_dark_tone, this.dark_tone, this.dark_dark_tone];
fill(this.skinColor[this.skin_val])
push();
strokeWeight(0.2);
stroke(50);
//Ears
ellipse(-this.eye_pos - 2, -1, 2, 2)
ellipse(this.eye_pos + 2, -1, 2, 2)
//Inner Ear
push();
strokeWeight(0.1)
ellipse(-this.eye_pos - 1.8, -1 , 1, 1 )
ellipse(this.eye_pos + 1.8, -1 , 1, 1 )
pop();
//Head
rect(0,0, 5 + this.head_width,12,5,5,this.chin_val,this.chin_val);
pop();
//eyes
fill(50);
strokeWeight(2);
translate(0,-1);
ellipse(this.eye_pos,-1,0.7,0.9);
ellipse(-this.eye_pos,-1,0.7,0.9);
noFill();
stroke(50);
strokeWeight(0.08);
if (this.age >= 1) {
push();
beginShape();
curveVertex(-this.eye_pos + 0.5, -3);
curveVertex(-this.eye_pos + 0.5, -0.5);
curveVertex(-this.eye_pos - 0.5, -0.3);
curveVertex(-this.eye_pos - 0.5, -3);
endShape();
pop();
//Right
push();
beginShape();
curveVertex(this.eye_pos - 0.5, -2);
curveVertex(this.eye_pos - 0.5, -0.5);
curveVertex(this.eye_pos + 0.5, -0.3);
curveVertex(this.eye_pos + 0.5, -2);
endShape();
pop();
push();
translate(0.2, 0.4)
beginShape();
curveVertex(-this.eye_pos + 0.5, -2);
curveVertex(-this.eye_pos + 0.5, -0.5);
curveVertex(-this.eye_pos - 0.8, -0.4);
curveVertex(-this.eye_pos - 0.8, -4);
endShape();
push();
translate(-0.2, 0)
beginShape();
curveVertex(this.eye_pos - 0.5, -2);
curveVertex(this.eye_pos - 0.5, -0.5);
curveVertex(this.eye_pos + 0.8, -0.4);
curveVertex(this.eye_pos + 0.8, -4);
endShape();
pop();
pop();
} else {
//Eye Details
//Left
push();
beginShape();
curveVertex(-this.eye_pos + 0.5, -3);
curveVertex(-this.eye_pos + 0.5, -0.5);
curveVertex(-this.eye_pos - 0.5, -0.3);
curveVertex(-this.eye_pos - 0.5, -3);
endShape();
pop();
//Right
push();
beginShape();
curveVertex(this.eye_pos - 0.5, -3);
curveVertex(this.eye_pos - 0.5, -0.5);
curveVertex(this.eye_pos + 0.5, -0.3);
curveVertex(this.eye_pos + 0.5, -3);
endShape();
pop();
}
//If Female Add Eyelashes
if(this.gender >= 1){
push();
strokeWeight(0.1);
translate(0, -0.7)
push();
line(this.eye_pos, -1, this.eye_pos, -0.1)
pop();
push();
line(this.eye_pos + 0.4, -1, this.eye_pos, -0.1)
pop();
push();
line(this.eye_pos - 0.4, -1, this.eye_pos, -0.1)
pop();
push();
line(-this.eye_pos, -1, -this.eye_pos, -0.1)
pop();
push();
line(-this.eye_pos + 0.4, -1, -this.eye_pos, -0.1)
pop();
push();
line(-this.eye_pos - 0.4, -1, -this.eye_pos, -0.1)
pop();
pop();
}
//Eyebrows
push();
if(this.age >= 3) {
//If Elderly add grey eyebrows
translate(this.eye_pos,this.eyebrow_y);
stroke(200);
} else {
translate(this.eye_pos,this.eyebrow_y);
stroke(50);
}
strokeWeight(this.eyebrow_thick);
beginShape();
curveVertex(-this.eye_pos /4, 1);
curveVertex(-this.eye_pos/4, 1);
curveVertex(-this.eye_pos/4 + this.eyebrowTween, this.eyebrow_emo);
curveVertex(this.eye_pos/4 - this.eyebrowTween, this.eyebrow_emo);
curveVertex(this.eye_pos/4, 1);
curveVertex(this.eye_pos/4, 1);
endShape();
pop();
push();
if(this.age >= 3) {
translate(-this.eye_pos,this.eyebrow_y);
stroke(200);
} else {
translate(-this.eye_pos,this.eyebrow_y);
stroke(50);
}
//stroke(233,130,114);
noFill();
strokeWeight(this.eyebrow_thick);
beginShape();
curveVertex(-this.eye_pos/4, 1);
curveVertex(-this.eye_pos/4, 1);
curveVertex(-this.eye_pos/4 + this.eyebrowTween, this.eyebrow_emo);
curveVertex(this.eye_pos/4 - this.eyebrowTween, this.eyebrow_emo);
curveVertex(this.eye_pos/4, 1);
curveVertex(this.eye_pos/4, 1);
endShape();
pop();
//Mouth Region
//Correcting mouth location to target
translate(0,1);
//If female, add lipstick(1 colour)
if(this.gender >= 1) {
//Feminine Lips/Lipstick
push();
translate(0.5,1);
stroke(255,20,20);
noFill();
strokeWeight(0.9);
beginShape();
curveVertex(-this.eye_pos + 1.1 , 1);
curveVertex(-this.eye_pos + 1.1, 1);
curveVertex(-this.eye_pos + 2.1, this.mouthEmo);
curveVertex(this.eye_pos - 3.1 ,this.mouthEmo);
curveVertex(this.eye_pos - 2.1, 1);
curveVertex(this.eye_pos - 2.1, 1);
endShape();
pop();
}
//Default Mouth
push();
translate(0.5,1);
strokeWeight(0.5);
beginShape();
curveVertex(-this.eye_pos + 0.1 , 1);
curveVertex(-this.eye_pos + 0.1, 1);
curveVertex(-this.eye_pos + 1.1, this.mouthEmo);
curveVertex(this.eye_pos - 2.1 ,this.mouthEmo);
curveVertex(this.eye_pos - 1.1, 1);
curveVertex(this.eye_pos - 1.1, 1);
endShape();
pop();
//Mouth detail
push();
scale(0.3);
translate(0.5, 7 + this.mouthEmo * 2);
stroke(50);
strokeWeight(0.3);
beginShape();
curveVertex(-this.eye_pos + 1.1 , 1);
curveVertex(-this.eye_pos + 1.1, 1);
curveVertex(-this.eye_pos + 0.1, 1);
curveVertex(this.eye_pos - 1.1 ,1);
curveVertex(this.eye_pos - 2.1, 1);
curveVertex(this.eye_pos - 2.1, 1);
endShape();
pop();
//Head wrinkles
if(this.age >= 2){
push();
scale(0.9);
strokeWeight(0.1);
stroke(50);
line(-this.eye_pos + 1.5, -3.5, this.eye_pos - 1.5, -3.5);
line(-this.eye_pos + 1.7, -3.2, this.eye_pos -1.7, -3.2);
pop();
}
pop();
//Create nose based on target image landmarks of nose
push();
noFill();
scale(0.9)
strokeWeight(0.08);
beginShape();
curveVertex(positions.nose_tip[0][0], -1)
curveVertex(positions.nose_tip[0][0] + -this.noseX, -1)
curveVertex(positions.nose_tip[0][0], positions.nose_tip[0][1])
curveVertex(positions.nose_tip[1][0], positions.nose_tip[1][1])
curveVertex(positions.nose_tip[2][0], positions.nose_tip[2][1])
curveVertex(positions.nose_tip[3][0], positions.nose_tip[3][1])
curveVertex(positions.nose_tip[4][0], positions.nose_tip[4][1])
curveVertex(positions.nose_tip[4][0] + this.noseX, -1)
curveVertex(positions.nose_tip[4][0], -1)
endShape();
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.chin_val = map(settings[0], 0, 100, 1, 5);
this.head_width = map(settings[1], 0, 100, 3, 6);
this.eye_pos = map(settings[1], 0, 100, 2, 4);
this.eyebrowTween = map(settings[1], 0, 100, 0.2, 0.5);
this.mouthEmo = map(settings[2], 0, 100, 0.8, 1.2);
this.noseX = map(settings[3], 0, 100, -0.3, -0.1)
this.eyebrow_y = map(settings[4], 0, 100, -4, -2.5);
this.eyebrow_thick = map(settings[5], 0, 100, 0.1, 0.8);
this.eyebrow_emo = map(settings[6], 0, 100, 0.8, 1.2);
this.skin_val = floor(map(settings[7], 0, 100, 0, 5));
this.age = floor(map(settings[8], 0, 100, 0, 6));
this.gender = floor(map(settings[9], 0, 100, 0, 2));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(3);
settings[0] = map(this.chin_val, 1, 5, 0, 100);
settings[1] = map(this.head_width, 3, 6, 0, 100);
settings[1] = map(this.eye_pos, 2, 4, 0, 100);
settings[1] = map(this.eyebrowTween, 0.2, 0.5, 0, 100);
settings[2] = map(this.mouthEmo, 0.8, 1.2, 0, 100);
settings[3] = map(this.noseX, -0.3, -0.1, 0, 100);
settings[4] = map(this.eyebrow_y, -4, -2.5, 0, 100);
settings[5] = map(this.eyebrow_thick, 0.1, 0.8, 0, 100);
settings[6] = map(this.eyebrow_emo, 0.8, 1.2, 0, 100);
settings[7] = floor(map(this.skin_val, 0, 5, 0, 100));
settings[8] = floor(map(this.age, 0, 6, 0, 100));
settings[9] = floor(map(this.gender, 0, 2, 0, 100));
return settings;
}
}
{
"000001": [
87.00000000000001,
0,
92,
53.99999999999999,
5.999999999999991,
20,
23,
20,
16,
100
],
"000002": [
100,
0,
100,
38.000000000000014,
11.000000000000004,
0,
0,
0,
0,
100
],
"000005": [
48,
0,
0,
100,
68,
50.000000000000014,
50,
20,
0,
100
],
"000006": [
100,
0,
0,
49.99999999999999,
0,
21.999999999999996,
50,
60,
0,
100
],
"000007": [
0,
100,
16.99999999999999,
100,
82,
82,
70.00000000000001,
60,
0,
0
],
"000009": [
59,
0,
100,
21.999999999999993,
0,
17,
27,
0,
0,
100
],
"000010": [
100,
0,
75.00000000000003,
32,
34.99999999999999,
13.999999999999998,
34.99999999999998,
20,
0,
100
],
"000013": [
34.00000000000001,
100,
100,
49.99999999999999,
77.00000000000001,
62,
0,
0,
50,
0
],
"000014": [
100,
0,
72.00000000000001,
83,
72.00000000000001,
30.000000000000004,
33.00000000000001,
80,
0,
100
],
"000015": [
65,
100,
70.00000000000001,
85,
82,
50.000000000000014,
50,
40,
0,
0
],
"000016": [
62,
100,
79.00000000000004,
100,
77.00000000000001,
69,
19.999999999999996,
40,
0,
0
],
"000018": [
77,
0,
90.99999999999999,
70,
0,
37,
19.999999999999996,
0,
50,
100
],
"000020": [
77,
100,
0,
76,
19.999999999999986,
62,
70.00000000000001,
20,
50,
0
],
"000023": [
100,
100,
95,
49.99999999999999,
72.00000000000001,
50.000000000000014,
27,
20,
50,
0
],
"000025": [
50,
100,
64.00000000000001,
87,
88.00000000000003,
50.000000000000014,
33.00000000000001,
40,
50,
0
],
"000028": [
100,
0,
100,
49.99999999999999,
0,
18,
0,
60,
0,
100
],
"000029": [
74,
0,
74.00000000000003,
49.99999999999999,
0,
16,
32.00000000000001,
20,
0,
100
],
"000030": [
83,
100,
49,
80,
52.99999999999999,
21.999999999999996,
49,
20,
50,
0
],
"000031": [
74,
0,
100,
72,
50,
21.000000000000004,
0,
20,
50,
100
],
"000032": [
100,
100,
29.000000000000004,
75,
72.99999999999999,
0,
66.00000000000001,
20,
50,
0
],
"000035": [
100,
0,
50,
47.99999999999999,
0,
50.000000000000014,
50,
40,
0,
100
],
"000037": [
18,
100,
21.999999999999996,
100,
100,
50.000000000000014,
60.00000000000001,
60,
0,
0
],
"000038": [
13,
100,
100,
100,
76.00000000000001,
50.000000000000014,
0,
0,
50,
0
],
"000040": [
100,
0,
68.00000000000001,
49.99999999999999,
4.0000000000000036,
24,
50,
40,
0,
100
],
"000041": [
1.0000000000000009,
100,
100,
100,
73.99999999999999,
66,
0,
60,
50,
0
],
"000042": [
100,
0,
76.00000000000003,
49.99999999999999,
26.000000000000007,
20,
18.999999999999993,
0,
0,
100
],
"000043": [
78,
0,
100,
49.99999999999999,
0,
50.000000000000014,
0,
20,
0,
100
],
"000044": [
60,
0,
77.00000000000003,
49.99999999999999,
0,
55.000000000000014,
19.999999999999996,
80,
0,
100
],
"000045": [
81,
0,
100,
49.99999999999999,
0,
27,
21.999999999999996,
40,
16,
100
],
"000047": [
100,
0,
73.00000000000001,
100,
0,
34.99999999999999,
14.000000000000016,
60,
33,
100
],
"000048": [
10.999999999999998,
100,
0,
48.99999999999999,
76.00000000000001,
65,
50,
0,
0,
0
],
"000050": [
100,
100,
100,
100,
91.00000000000001,
87.00000000000001,
0,
20,
50,
0
],
"000051": [
0,
100,
100,
49.99999999999999,
100,
75,
0,
60,
100,
0
],
"000052": [
0,
100,
62.000000000000014,
49.99999999999999,
83,
100,
50,
60,
100,
0
],
"000054": [
100,
0,
100,
69,
50,
21.000000000000004,
0,
40,
16,
100
],
"000055": [
0,
100,
66.00000000000001,
100,
82,
84.00000000000001,
50,
20,
50,
0
],
"000056": [
43.99999999999999,
0,
73.00000000000001,
49.99999999999999,
18.000000000000004,
31.000000000000007,
24,
0,
0,
100
],
"000058": [
73,
0,
65.00000000000001,
49.99999999999999,
0,
9,
14.000000000000016,
0,
0,
100
],
"000060": [
0,
100,
99,
49.99999999999999,
100,
10,
0,
100,
50,
0
],
"000064": [
30.000000000000004,
100,
80.00000000000004,
49.99999999999999,
83,
38,
26,
0,
50,
0
],
"000065": [
10.999999999999998,
100,
100,
100,
38.99999999999999,
75,
18.999999999999993,
60,
0,
0
],
"000068": [
18,
100,
100,
49.99999999999999,
83,
3.0000000000000004,
49,
20,
100,
0
],
"000069": [
0,
100,
50,
90,
77.00000000000001,
59,
50,
20,
50,
0
],
"000071": [
100,
0,
77.00000000000003,
49.99999999999999,
25,
11.999999999999998,
32.00000000000001,
40,
16,
100
],
"000073": [
100,
0,
64.00000000000001,
49.99999999999999,
0,
13.999999999999998,
50,
40,
0,
100
],
"000076": [
0,
100,
81.99999999999999,
96,
47,
19,
50,
20,
16,
0
],
"000077": [
100,
0,
81.99999999999999,
49.99999999999999,
0,
12.999999999999998,
20.999999999999996,
40,
0,
100
],
"000078": [
68,
0,
74.00000000000003,
65,
0,
18,
24,
20,
16,
100
],
"000079": [
0,
100,
76.00000000000003,
98,
100,
21.999999999999996,
19.999999999999996,
60,
50,
0
],
"000080": [
0,
100,
80.00000000000004,
49.99999999999999,
69.99999999999999,
46,
18.999999999999993,
40,
0,
0
],
"000081": [
0,
100,
100,
100,
67,
67,
0,
60,
16,
0
],
"000083": [
60,
0,
81.99999999999999,
49.99999999999999,
0,
9,
11.000000000000012,
0,
33,
100
],
"000085": [
75,
0,
76.00000000000003,
49.99999999999999,
0,
28.000000000000004,
32.00000000000001,
40,
16,
100
],
"000086": [
67,
0,
50,
49.99999999999999,
86,
50.000000000000014,
50,
0,
0,
100
],
"000088": [
100,
0,
65.00000000000001,
49.99999999999999,
0,
8.000000000000004,
50,
40,
0,
100
],
"000091": [
50,
100,
38.99999999999999,
49.99999999999999,
80.00000000000001,
37,
100,
0,
0,
0
],
"000092": [
77,
0,
76.00000000000003,
49.99999999999999,
16.999999999999993,
19,
33.00000000000001,
20,
33,
100
],
"000096": [
50,
0,
13.000000000000014,
49.99999999999999,
0,
26,
50,
20,
0,
100
],
"000097": [
40.99999999999999,
0,
38.99999999999999,
49.99999999999999,
0,
13.999999999999998,
50,
20,
0,
100
],
"000099": [
80,
0,
100,
49.99999999999999,
0,
12.999999999999998,
0,
0,
16,
100
],
"000100": [
94,
0,
69.00000000000001,
49.99999999999999,
81,
17,
31.000000000000007,
0,
16,
100
],
"000103": [
69,
0,
50,
49.99999999999999,
15.000000000000005,
25,
58.00000000000001,
20,
0,
100
],
"000104": [
3.0000000000000027,
100,
100,
100,
83.99999999999999,
50.000000000000014,
8.000000000000009,
0,
16,
0
],
"000106": [
100,
0,
100,
61,
73.99999999999999,
11.999999999999998,
17.99999999999999,
40,
16,
100
],
"000108": [
73,
0,
100,
49.99999999999999,
27.000000000000018,
6.000000000000001,
24,
20,
16,
100
],
"000109": [
0,
100,
81.99999999999999,
49.99999999999999,
81,
50.000000000000014,
50,
60,
50,
0
],
"000110": [
100,
0,
100,
49.99999999999999,
64,
21.999999999999996,
2.000000000000002,
40,
16,
100
],
"000111": [
100,
0,
100,
49.99999999999999,
67,
21.999999999999996,
20.999999999999996,
80,
16,
100
],
"000114": [
0,
100,
100,
100,
73.99999999999999,
79,
21.999999999999996,
40,
16,
0
],
"000115": [
0,
100,
59.00000000000001,
50.99999999999999,
100,
50.000000000000014,
50,
40,
0,
0
],
"000116": [
35,
100,
100,
49.99999999999999,
50,
100,
16.99999999999999,
20,
16,
0
],
"000117": [
100,
0,
100,
78,
0,
21.999999999999996,
50,
80,
0,
100
],
"000118": [
100,
0,
78.00000000000004,
49.99999999999999,
69,
24,
26,
60,
16,
100
],
"000121": [
100,
0,
83.99999999999999,
49.99999999999999,
0,
0,
34.00000000000001,
40,
16,
100
],
"000122": [
65,
0,
100,
49.99999999999999,
67,
29.000000000000004,
14.000000000000016,
40,
100,
100
],
"000125": [
0,
100,
63.000000000000014,
49.99999999999999,
100,
50.000000000000014,
30.000000000000004,
60,
100,
0
],
"000126": [
100,
0,
79.00000000000004,
49.99999999999999,
0,
21.000000000000004,
50,
60,
16,
100
],
"000129": [
0,
100,
100,
49.99999999999999,
76.00000000000001,
62,
13.000000000000014,
20,
50,
0
],
"000131": [
96,
0,
100,
69,
0,
23,
18.999999999999993,
80,
0,
100
],
"000132": [
100,
0,
100,
75,
50,
24,
12.000000000000014,
80,
16,
100
],
"000133": [
100,
0,
100,
57.99999999999999,
69.99999999999999,
50.000000000000014,
13.000000000000014,
60,
16,
100
],
"000134": [
14.000000000000002,
100,
100,
100,
93,
50.000000000000014,
10.000000000000012,
100,
16,
0
],
"000135": [
15.000000000000002,
100,
100,
79,
77.00000000000001,
100,
50,
80,
16,
0
],
"000137": [
4.999999999999999,
100,
100,
99,
100,
56.000000000000014,
5.000000000000006,
0,
50,
0
],
"000140": [
100,
0,
13.000000000000014,
49.99999999999999,
0,
13.999999999999998,
75.00000000000003,
60,
16,
100
],
"000142": [
100,
0,
33.00000000000001,
70,
0,
23,
35.99999999999998,
0,
16,
100
],
"000143": [
0,
100,
81.99999999999999,
77,
80.00000000000001,
50.000000000000014,
50,
20,
66,
0
],
"000145": [
68,
0,
100,
49.99999999999999,
0,
18,
15.99999999999999,
20,
16,
100
],
"000146": [
77,
0,
100,
49.99999999999999,
0,
0,
0,
60,
16,
100
],
"000147": [
83.99999999999999,
0,
65.00000000000001,
49.99999999999999,
9.999999999999993,
20,
27,
60,
0,
100
],
"000148": [
71,
0,
71.00000000000001,
49.99999999999999,
77.00000000000001,
3.9999999999999996,
50,
0,
50,
100
],
"000150": [
2.0000000000000018,
100,
50,
49.99999999999999,
75,
24,
50,
0,
16,
0
],
"000151": [
91.00000000000001,
0,
100,
49.99999999999999,
0,
20,
0,
60,
16,
100
],
"000156": [
75,
0,
100,
49.99999999999999,
76.00000000000001,
12.999999999999998,
14.999999999999988,
0,
0,
100
],
"000157": [
69,
0,
50,
49.99999999999999,
50,
19,
37.999999999999986,
20,
0,
100
],
"000160": [
20,
100,
68.00000000000001,
74,
83,
50.000000000000014,
38.99999999999999,
0,
50,
0
],
"000161": [
100,
0,
100,
49.99999999999999,
0,
18,
30.000000000000004,
0,
16,
100
],
"000152": [
10.999999999999998,
100,
100,
82,
73.99999999999999,
19,
13.000000000000014,
20,
16,
0
],
"000153": [
6,
100,
100,
49.99999999999999,
79,
61,
8.000000000000009,
20,
33,
0
],
"000155": [
100,
0,
100,
49.99999999999999,
0,
49.00000000000001,
0,
20,
0,
100
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 7;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function TruongFace() {
// these are state variables for a face
// (your variables should be different!)
/*
* earSize can vary from 0 to 4
* earDist is the distance between ears and varies from 0 to 4
* faceColor is 1,2,3,4 for yellow,blue,red, or violet respectively
*/
this.faceColor = 1;
this.eyeColor = 1;
this.hairColor = 1;
this.blush = 1;
this.mouth_type = 1;
this.brow_tilt = 5;
this.browsColor = 1;
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
noStroke();
//hair
let facePos = segment_average(positions.chin);
push();
if (this.hairColor == 1) { //light blonde
fill("#d6ad5a");
} else if (this.hairColor == 2) { //mid blonde
fill("#ad8c49");
} else if (this.hairColor == 3) { //dark blonde
fill("#997b46");
} else if (this.hairColor == 4) { //brown
fill("#3b2f19");
} else if (this.hairColor == 5) { //black
fill("#1a140a");
}
ellipse(facePos[0],facePos[0]-0.5,4);
ellipse(facePos[0],facePos[0]-3,0.5);
ellipse(facePos[0],facePos[0]-2.55,0.5);
ellipse(facePos[0],facePos[0]-3.5,1);
pop();
// head
push();
if (this.faceColor == 1) {
fill("#f7ebe4"); //white tone
} else if (this.faceColor == 2) {
fill("#cfb4a5"); //tan tone
} else if (this.faceColor == 3) {
fill("#997560"); //dark tone
}
ellipse(facePos[0],facePos[0],3.5);
pop();
//eyes
let leftEyePos = segment_average(positions.left_eye);
let rightEyePos = segment_average(positions.right_eye);
let leftPupil = positions.left_eye[4];
let rightPupil = positions.right_eye[4];
push();
if (this.eyeColor == 1) {
fill("#855740"); //brow
} else if (this.eyeColor == 2) {
fill("#331b0e"); //dark brow
} else if (this.eyeColor == 3) {
fill("#3a85ba"); //blue
}
stroke(255);
strokeWeight(0.05)
ellipse(leftEyePos[0],0,0.5);
ellipse(rightEyePos[0],0,0.5);
fill(255);
ellipse(leftPupil[0],-0.1,0.1);
ellipse(rightPupil[0],-0.1,0.1);
pop();
//blush
let leftBlush = positions.right_eye[0];
let rightBlush = positions.left_eye[0];
if (this.blush == 1){
noStroke();
fill("#f7a6a6");
ellipse(leftBlush[0]+0.4,leftBlush[1]+1.6,0.5,0.25);
ellipse(rightBlush[0]+0.1,rightBlush[1]+1.6,0.5,0.25);
stroke("#e38f8f");
strokeWeight(0.03);
line(leftBlush[0]+0.5,leftBlush[1]+1.65,leftBlush[0]+0.45,leftBlush[1]+1.55);
line(leftBlush[0]+0.35,leftBlush[1]+1.65,leftBlush[0]+0.3,leftBlush[1]+1.55);
line(rightBlush[0]+0.05,rightBlush[1]+1.65,rightBlush[0],rightBlush[1]+1.55);
line(rightBlush[0]+0.2,rightBlush[1]+1.65,rightBlush[0]+0.15,rightBlush[1]+1.55);
}
//nose
noStroke();
let nose = color("#d6b4a1")
let nose_shadow = color("#c2a391")
if (positions.nose_bridge[3][0] <= positions.nose_tip[2][0]) {
nose = color("#d6b4a1")
nose_shadow = color("#c2a391")
}
fill(nose);
triangle(positions.nose_bridge[0][0],positions.nose_bridge[0][1]+0.5,positions.nose_tip[0][0]-0.1,positions.nose_tip[0][1]+0.4,positions.nose_tip[2][0]+0.3,positions.nose_tip[2][1]+0.4);
fill(nose_shadow);
triangle(positions.nose_bridge[0][0],positions.nose_bridge[0][1]+0.5,positions.nose_tip[0][0]+0.1,positions.nose_tip[0][1]+0.35,positions.nose_tip[2][0]+0.3,positions.nose_tip[2][1]+0.4);
//mouth
noStroke();
let mouthPos = segment_average(positions.top_lip);
let mouthPos2 = segment_average(positions.bottom_lip);
if (this.mouth_type == 1){ //smile
fill("#edb4b4");
rect(mouthPos[0]-0.3,mouthPos2[1],0.8,0.4,0,0,40,40);
}
else if (this.mouth_type == 2){ //little smile
fill("#edb4b4");
rect(mouthPos[0]-0.3,mouthPos2[1],0.8,0.2,0,0,40,40);
}
else if (this.mouth_type == 3){ //lips
fill("#000000");
stroke("#9c5454");
strokeWeight(0.05);
rect(mouthPos[0]-0.3,mouthPos2[1],0.8,0.1,0,0,40,40);
}
//brows
let leftBrowLeft = positions.left_eyebrow[0];
let leftBrowArc = positions.left_eyebrow[2];
let leftBrowRight = positions.left_eyebrow[4];
let rightBrowLeft = positions.right_eyebrow[0];
let rightBrowArc = positions.right_eyebrow[2];
let rightBrowRight = positions.right_eyebrow[4];
strokeWeight(0.08);
push();
if (this.browsColor == 1) {
stroke("#d6ad5a");
} else if (this.browsColor == 2) {
stroke("#ad8c49");
} else if (this.browsColor == 3) {
stroke("#997b46");
} else if (this.browsColor == 4) {
stroke("#3b2f19");
} else if (this.browsColor == 5) {
stroke("#1a140a");
}
rotate(-this.brow_tilt);
line(leftBrowLeft[0]+0.25,leftBrowLeft[1]+1,leftBrowArc[0],leftBrowArc[1]+1);
line(leftBrowArc[0],leftBrowArc[1]+1,leftBrowRight[0],leftBrowRight[1]+1);
rotate(this.brow_tilt*2);
line(rightBrowLeft[0],rightBrowLeft[1]+1,rightBrowArc[0],rightBrowArc[1]+1);
line(rightBrowArc[0],rightBrowArc[1]+1,rightBrowRight[0]-0.4,rightBrowRight[1]+1);
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.faceColor = int(map(settings[0],0,100,1,3));
this.hairColor = int(map(settings[1],0,100,1,5));
this.eyeColor = int(map(settings[2],0,100,1,3));
this.blush = (map(settings[3],0,100,0,1));
this.mouth_type = int(map(settings[4],0,100,1,3));
this.brow_tilt = map(settings[5],0,100,0,8);
this.browsColor = int(map(settings[6],0,100,1,5));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(3);
settings[0] = map(this.faceColor,1,3,0,100);
settings[1] = map(this.hairColor,1,5,0,100);
settings[2] = map(this.eyeColor,1,3,0,100);
settings[3] = map(this.blush,0,1,0,100);
settings[4] = map(this.mouth_type,1,3,0,100);
settings[5] = map(this.brow_tilt,0,8,0,100);
settings[6] = map(this.browsColor,1,5,0,100);
return settings;
}
}
{
"000001": [
0,
0,
50,
100,
0,
72,
0
],
"000002": [
0,
50,
50,
100,
0,
81,
50
],
"000005": [
0,
0,
0,
100,
50,
25,
0
],
"000006": [
50,
50,
50,
100,
50,
0,
50
],
"000007": [
0,
100,
50,
0,
100,
100,
100
],
"000009": [
0,
75,
0,
100,
50,
25,
75
],
"000010": [
0,
25,
100,
100,
100,
64,
25
],
"000013": [
0,
0,
100,
0,
50,
92,
25
],
"000014": [
50,
100,
50,
100,
100,
100,
100
],
"000015": [
0,
75,
0,
0,
100,
100,
75
],
"000044": [
100,
100,
50,
100,
100,
45,
100
],
"000016": [
0,
75,
0,
0,
100,
100,
75
],
"000018": [
0,
0,
0,
100,
50,
46,
0
],
"000020": [
0,
75,
50,
0,
100,
87,
75
],
"000023": [
0,
100,
100,
0,
100,
87,
75
],
"000025": [
0,
75,
50,
0,
100,
87,
75
],
"000028": [
0,
50,
0,
100,
0,
6,
50
],
"000029": [
0,
0,
100,
100,
50,
0,
0
],
"000030": [
0,
0,
50,
55.00000000000001,
100,
0,
0
],
"000031": [
0,
75,
100,
100,
0,
43,
50
],
"000032": [
0,
50,
50,
46,
100,
79,
25
],
"000035": [
0,
100,
0,
100,
100,
85,
100
],
"000037": [
100,
100,
50,
61,
100,
6,
100
],
"000038": [
0,
75,
100,
38,
50,
57.99999999999999,
75
],
"000040": [
0,
100,
0,
100,
100,
55.00000000000001,
100
],
"000041": [
0,
100,
0,
82,
0,
55.00000000000001,
100
],
"000042": [
0,
75,
100,
100,
100,
47,
75
],
"000043": [
0,
75,
0,
100,
0,
54,
75
],
"000045": [
0,
50,
0,
100,
0,
56.99999999999999,
50
],
"000047": [
50,
100,
50,
100,
50,
45,
75
],
"000048": [
0,
100,
50,
87,
100,
28.000000000000004,
75
],
"000050": [
0,
100,
50,
87,
50,
28.000000000000004,
100
],
"000051": [
0,
0,
50,
57.99999999999999,
100,
62,
75
],
"000052": [
50,
75,
100,
57.99999999999999,
100,
62,
75
],
"000054": [
0,
0,
100,
100,
50,
57.99999999999999,
0
],
"000055": [
0,
100,
0,
80,
100,
100,
100
],
"000056": [
0,
100,
0,
82,
100,
100,
100
],
"000058": [
0,
100,
100,
100,
100,
100,
100
],
"000060": [
100,
100,
50,
81,
50,
100,
100
],
"000064": [
0,
75,
100,
79,
100,
100,
75
],
"000065": [
50,
100,
50,
79,
50,
66,
75
],
"000068": [
0,
0,
0,
48,
50,
73,
0
],
"000069": [
0,
100,
0,
28.999999999999996,
100,
100,
100
],
"000071": [
0,
0,
0,
100,
50,
100,
0
],
"000073": [
0,
100,
0,
100,
50,
100,
100
],
"000076": [
0,
100,
50,
72,
100,
100,
100
],
"000077": [
0,
100,
50,
100,
100,
100,
100
],
"000078": [
0,
100,
0,
100,
100,
100,
100
],
"000079": [
0,
100,
0,
70,
100,
100,
100
],
"000080": [
0,
100,
50,
70,
100,
100,
100
],
"000081": [
0,
100,
50,
70,
50,
100,
100
],
"000083": [
0,
75,
100,
100,
100,
100,
50
],
"000085": [
0,
75,
0,
100,
100,
100,
50
],
"000086": [
0,
75,
0,
100,
100,
100,
50
],
"000088": [
0,
75,
50,
100,
100,
100,
50
],
"000091": [
0,
100,
50,
86,
100,
100,
100
],
"000092": [
0,
0,
0,
100,
100,
100,
0
],
"000096": [
0,
75,
50,
100,
100,
100,
50
],
"000097": [
0,
75,
100,
100,
100,
100,
50
],
"000099": [
0,
75,
100,
100,
50,
100,
50
],
"000100": [
0,
25,
50,
100,
100,
100,
25
],
"000103": [
0,
100,
0,
100,
100,
100,
100
],
"000104": [
0,
25,
100,
86,
50,
68,
25
],
"000106": [
0,
25,
50,
100,
50,
68,
25
],
"000108": [
0,
25,
100,
100,
50,
68,
25
],
"000109": [
0,
25,
100,
84,
50,
68,
25
],
"000110": [
0,
25,
0,
100,
50,
68,
25
],
"000111": [
50,
0,
0,
100,
50,
68,
25
],
"000114": [
0,
100,
50,
83,
50,
68,
75
],
"000115": [
0,
100,
0,
83,
100,
100,
100
],
"000116": [
0,
75,
0,
83,
50,
97,
75
],
"000117": [
50,
100,
50,
100,
50,
97,
75
],
"000118": [
50,
100,
0,
100,
100,
97,
75
],
"000121": [
0,
100,
0,
100,
100,
97,
75
],
"000122": [
0,
0,
0,
100,
50,
28.000000000000004,
0
],
"000125": [
0,
100,
100,
85,
50,
28.000000000000004,
100
],
"000126": [
0,
0,
100,
100,
50,
65,
0
],
"000129": [
0,
100,
100,
81,
50,
65,
75
],
"000131": [
0,
100,
50,
100,
50,
65,
75
],
"000132": [
0,
100,
50,
100,
50,
65,
75
],
"000133": [
0,
50,
100,
100,
50,
25,
25
],
"000134": [
100,
100,
50,
69,
50,
0,
100
],
"000135": [
50,
100,
50,
69,
100,
0,
100
],
"000137": [
0,
75,
100,
69,
50,
44,
75
],
"000140": [
0,
0,
100,
100,
100,
100,
75
],
"000142": [
0,
75,
100,
100,
100,
100,
75
],
"000143": [
0,
75,
100,
86,
50,
88,
75
],
"000145": [
0,
100,
50,
100,
0,
51,
75
],
"000146": [
0,
50,
50,
100,
50,
100,
50
],
"000147": [
0,
50,
100,
100,
50,
100,
50
],
"000148": [
0,
100,
100,
100,
50,
100,
75
],
"000150": [
0,
50,
100,
64,
100,
47,
50
],
"000151": [
0,
100,
50,
100,
0,
54,
100
],
"000152": [
0,
75,
100,
86,
50,
65,
75
],
"000153": [
0,
75,
50,
86,
50,
65,
75
],
"000155": [
0,
75,
50,
100,
50,
65,
75
],
"000156": [
0,
25,
100,
100,
50,
100,
50
],
"000157": [
0,
25,
100,
100,
100,
100,
50
],
"000160": [
0,
100,
50,
86,
100,
100,
100
],
"000161": [
0,
100,
100,
100,
50,
42,
100
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 6;
// other variables can be in here too
// here's some examples for colors used
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
function TualaFace() {
// faceColor values
const light_shade = color(232,198,153);
const medium_shade = color(241,194,125);
const tan_shade = color(198,134,66);
const dark_shade = color(141,85,36);
// eyeColor values
const light_blue = color(161,202,241);
const green_eye = color(108,165,128);
// hairColor values
const dark_tone = color(69,24,0);
const light_tone = color(235,215,141);
const medium_tone = color(132,97,39);
// lip_color values
const neutral_lip = color(227,158,116);
const pink_lip = color(240,157,151);
const dark_lip = color(148,82,80);
const red_lip = color(255,0,0);
/* THE RANGE OF MY VALUES BELOW:
*faceColor,eyeColor,hairColor,lip_color = 0-3
*headShape = eyeSize = 0-10
*mouth_open1 = 0-5
*/
this.faceColor = 0;
this.eyeColor = 0;
this.hair_change = 0;
this.hairColor = 0;
this.eyeSize = 10;
this.lip_color = 0;
this.mouth_open1 = 0;
this.nose_shade = 0;
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
/*--------------------------------------------------------------
//HAIR
* HAIR SHADES MAPPED TO SLIDER 5
* HAIR STYLE CHANGE MAPPED TO SLIDER 4
* Hair changes style based on gender; female = longer hair, male = shorter hair.
-------------------------------------------------------------- */
noStroke();
if(this.hairColor == 0) {
fill(0);
}
else if (this.hairColor==1) {
fill(dark_tone);
}
else if (this.hairColor==2) {
fill(medium_tone);
}
else {
fill(light_tone);
}
//longer hair
if (this.hair_change == 0) {
beginShape();
curveVertex(positions.chin[0][0]+1, positions.chin[0][1]);
curveVertex(positions.chin[16][0]+0.5, positions.chin[16][1]);
curveVertex(2.5, -2);
curveVertex(1, -3);
curveVertex(0, -3);
curveVertex(-0.5, -3);
curveVertex(-2, -2.2);
curveVertex(positions.chin[0][0]-0.8, positions.chin[0][1]+2);
curveVertex(positions.left_eyebrow[2][0]-1.5,positions.left_eyebrow[2][0]+3.5);
curveVertex(0,2);
curveVertex(positions.right_eyebrow[2][0]+2.2,positions.right_eyebrow[2][1]+3.5);
curveVertex(positions.chin[16][0]+0.6, positions.chin[16][1]-0.5);
curveVertex(positions.chin[16][0], positions.chin[16][1]);
endShape();
}
else { //shorter hair
beginShape();
curveVertex(positions.chin[0][0]+1, positions.chin[0][1]);
curveVertex(positions.chin[16][0]+0.5, positions.chin[16][1]);
curveVertex(+2.2, -2);
curveVertex(+1, -3);
curveVertex(0, -3);
curveVertex(-1, -3);
curveVertex(-1.5, -2);
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.left_eyebrow[2][0],positions.left_eyebrow[2][0]+1);
curveVertex(0,1);
curveVertex(positions.right_eyebrow[2][0],positions.right_eyebrow[2][1]+1);
curveVertex(positions.chin[11][5], positions.chin[16][1]);
curveVertex(positions.chin[11][5], positions.chin[16][1]);
endShape();
}
//--------------------------------------------------------------
// FACE - SKIN TONE MAPPED TO SLIDER 2
//--------------------------------------------------------------
//stroke(235,177,92);
//strokeWeight(0.03);
noStroke();
if(this.faceColor == 0) {
fill(light_shade);
}
else if (this.faceColor==1) {
fill(medium_shade);
}
else if (this.faceColor==2) {
fill(tan_shade);
}
else {
fill(dark_shade);
}
beginShape();
for(let i = 0; i < positions.chin.length; i++) {
curveVertex(positions.chin[i][0], positions.chin[i][1]);
curveVertex(positions.chin[i][0], positions.chin[i][1]);
}
for(let i = 4; i >= 0; i--) {
curveVertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]-0.4);
}
for(let i = 4; i >= 0; i--) {
curveVertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]-0.4);
}
curveVertex(positions.chin[1][0], positions.chin[0][1]);
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.chin[0][0], positions.chin[0][1]);
endShape();
//--------------------------------------------------------------
//MOUTH - this.mouth_open1 MAPPED TO SLIDER 1 - DOES NOT WORK YET
// I copied this code from a student but I have adjusted it to suit my own face.
//--------------------------------------------------------------
//white back (teeth) inside mouth
noStroke();
fill(255);
beginShape();
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]);
curveVertex(positions.top_lip[1][0], positions.top_lip[1][1]);
curveVertex(positions.top_lip[2][0], positions.top_lip[2][1]);
curveVertex(positions.top_lip[3][0], positions.top_lip[3][1]);
curveVertex(positions.top_lip[4][0], positions.top_lip[4][1]);
curveVertex(positions.top_lip[5][0], positions.top_lip[5][1]);
curveVertex(positions.top_lip[6][0], positions.top_lip[6][1]);
curveVertex(positions.bottom_lip[7][0], positions.bottom_lip[6][1]);
curveVertex(positions.bottom_lip[8][0], positions.bottom_lip[8][1]);
curveVertex(positions.bottom_lip[9][0], positions.bottom_lip[9][1]);
curveVertex(positions.bottom_lip[10][0], positions.bottom_lip[10][1]);
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]);
curveVertex(positions.bottom_lip[7][0], positions.bottom_lip[7][1]);
endShape();
//LIPS - MAPPED TO SLIDER 6
if (this.lip_color == 0){
fill(neutral_lip);
}
else if (this.lip_color == 1) {
fill(pink_lip);
}
else if (this.lip_color == 2) {
fill(dark_lip);
}
else {
fill(red_lip);
}
beginShape();
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]+0.05);
curveVertex(positions.top_lip[2][0], positions.top_lip[2][1]-0.03);
curveVertex(positions.top_lip[3][0], positions.top_lip[3][1]);
curveVertex(positions.top_lip[4][0], positions.top_lip[4][1]);
curveVertex(positions.top_lip[6][0], positions.top_lip[6][1]+0.05);
curveVertex(positions.top_lip[8][0], positions.top_lip[8][1]+0.05);
curveVertex(positions.top_lip[10][0], positions.top_lip[10][1]+0.05);
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]+0.05);
curveVertex(positions.top_lip[2][0], positions.top_lip[2][1]-0.03);
curveVertex(positions.top_lip[3][0], positions.top_lip[3][1]);
endShape();
beginShape();
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
curveVertex(positions.bottom_lip[1][0], positions.bottom_lip[1][1]);
curveVertex(positions.bottom_lip[2][0], positions.bottom_lip[2][1]);
curveVertex(positions.bottom_lip[3][0], positions.bottom_lip[3][1]);
curveVertex(positions.bottom_lip[5][0], positions.bottom_lip[5][1]);
curveVertex(positions.bottom_lip[6][0], positions.bottom_lip[6][1]);
curveVertex(positions.bottom_lip[8][0], positions.bottom_lip[8][1]);
curveVertex(positions.bottom_lip[9][0], positions.bottom_lip[9][1]);
curveVertex(positions.bottom_lip[10][0], positions.bottom_lip[10][1]);
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
curveVertex(positions.bottom_lip[1][0], positions.bottom_lip[1][1]);
curveVertex(positions.bottom_lip[3][0], positions.bottom_lip[3][1]);
endShape();
//--------------------------------------------------------------
//EYES
//--------------------------------------------------------------
//EYE POSITIONS
noStroke();
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
//EYE BACKGROUND
fill(255);
noStroke();
ellipse(left_eye_pos[0], left_eye_pos[1], 0.58, 0.37);
ellipse(right_eye_pos[0], right_eye_pos[1], 0.58, 0.37);
//EYE COLOR - COLORS MAPPED TO SLIDER 3
noStroke();
if(this.eyeColor == 0) {
fill('#A87A51');
}
else if (this.eyeColor==1) {
fill(light_blue);
}
else {
fill(green_eye);
}
ellipse(left_eye_pos[0], left_eye_pos[1], this.eyeSize/30);
ellipse(right_eye_pos[0], right_eye_pos[1],this.eyeSize/30);
//EYE PUPILS
fill(50);
ellipse(left_eye_pos[0], left_eye_pos[1], 0.18);
ellipse(right_eye_pos[0], right_eye_pos[1],0.18);
//EYE REFLECTION
fill(255);
ellipse(left_eye_pos[0]+0.1, left_eye_pos[1]-0.1, 0.1);
ellipse(right_eye_pos[0]+0.1, right_eye_pos[1]-0.1,0.1);
//--------------------------------------------------------------
//EYEBROWS
//--------------------------------------------------------------
fill(50);
stroke(50);
strokeWeight(0.07);
// LEFT EYEBROW
beginShape();
for(let i = 1; i < positions.left_eyebrow.length; i++) {
curveVertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
curveVertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
endShape();
// RIGHT EYEBROW
beginShape();
for(let i = 0; i < 4; i++) {
curveVertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
curveVertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
endShape();
//--------------------------------------------------------------
//NOSE
//--------------------------------------------------------------
let nose_top = positions.nose_bridge[0];
let nose_bottom = positions.nose_bridge[3];
noFill();
stroke(145,97,60);
strokeWeight(0.07);
//NOSE ARROW
beginShape();
vertex(positions.nose_tip[0][0], positions.nose_tip[0][1])
vertex(positions.nose_tip[1][0], positions.nose_tip[1][1])
vertex(positions.nose_tip[1][0], positions.nose_tip[1][1])
vertex(positions.nose_tip[2][0], positions.nose_tip[2][1])
vertex(positions.nose_tip[2][0], positions.nose_tip[2][1])
vertex(positions.nose_tip[3][0], positions.nose_tip[3][1])
vertex(positions.nose_tip[3][0], positions.nose_tip[3][1])
vertex(positions.nose_tip[4][0], positions.nose_tip[4][1])
endShape();
//NOSE LINE
stroke(145,97,60);
beginShape();
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1])
vertex(positions.nose_bridge[1][0], positions.nose_bridge[1][1])
vertex(positions.nose_bridge[1][0], positions.nose_bridge[1][1])
vertex(positions.nose_bridge[2][0], positions.nose_bridge[2][1])
vertex(positions.nose_bridge[2][0], positions.nose_bridge[2][1])
vertex(positions.nose_bridge[3][0], positions.nose_bridge[3][1])
vertex(positions.nose_bridge[3][0], positions.nose_bridge[3][1])
vertex(positions.nose_tip[2][0], positions.nose_tip[2][1])
endShape();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
//this.mouthRadius = map(settings[0], 0, 100, 0.7, 2);
this.mouth_open1 = map(settings[0], 0, 100, 0, 5);
this.faceColor = int(map(settings[1], 0, 100, 0,3));
this.eyeColor = int(map(settings[2], 0, 100, 0, 2));
this.hair_change = int(map(settings[3], 0, 100, 0, 2));
this.hairColor = int(map(settings[4], 0, 100, 0, 3));
this.lip_color = int(map(settings[5], 0, 100, 0, 3));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(6);
//settings[0] = map(this.mouthRadius, 0.7, 2, 0, 100);
settings[0] = map(this.mouth_open1, 0, 5, 0, 100);
settings[1] = map(this.faceColor, 0, 3, 0, 100);
settings[2] = map(this.eyeColor, 0, 2, 0, 100);
settings[3] = map(this.hair_change, 0, 2, 0, 100);
settings[4] = map(this.hairColor, 0, 3, 0, 100);
settings[5] = map(this.lip_color, 0, 3, 0, 100);
return settings;
}
}
{
"000001": [
0,
0,
0,
0,
66.66666666666666,
0
],
"000002": [
0,
0,
0,
0,
33.33333333333333,
0
],
"000005": [
0,
0,
50,
0,
100,
0
],
"000006": [
0,
66.66666666666666,
0,
0,
66.66666666666666,
66.66666666666666
],
"000007": [
0,
0,
0,
100,
0,
0
],
"000009": [
0,
0,
0,
0,
66.66666666666666,
66.66666666666666
],
"000010": [
0,
0,
50,
0,
100,
33.33333333333333
],
"000013": [
0,
0,
50,
100,
100,
0
],
"000014": [
0,
66.66666666666666,
0,
0,
0,
0
],
"000015": [
0,
0,
50,
100,
0,
0
],
"000016": [
0,
0,
0,
100,
66.66666666666666,
0
],
"000018": [
0,
0,
50,
0,
100,
33.33333333333333
],
"000020": [
0,
0,
50,
100,
0,
0
],
"000023": [
0,
0,
50,
100,
0,
0
],
"000025": [
0,
0,
0,
100,
66.66666666666666,
0
],
"000028": [
0,
0,
0,
0,
66.66666666666666,
0
],
"000029": [
0,
0,
50,
0,
100,
0
],
"000030": [
0,
0,
0,
100,
100,
0
],
"000031": [
0,
0,
50,
0,
66.66666666666666,
0
],
"000032": [
0,
0,
0,
100,
66.66666666666666,
0
],
"000035": [
0,
0,
100,
0,
0,
66.66666666666666
],
"000037": [
0,
66.66666666666666,
0,
100,
0,
0
],
"000038": [
0,
0,
100,
100,
66.66666666666666,
0
],
"000040": [
0,
0,
0,
0,
0,
0
],
"000041": [
0,
0,
0,
100,
0,
0
],
"000042": [
0,
0,
100,
0,
66.66666666666666,
100
],
"000043": [
0,
0,
100,
0,
66.66666666666666,
0
],
"000044": [
0,
100,
0,
0,
0,
33.33333333333333
],
"000045": [
0,
33.33333333333333,
0,
0,
33.33333333333333,
0
],
"000047": [
0,
0,
0,
0,
0,
33.33333333333333
],
"000048": [
0,
0,
0,
100,
0,
0
],
"000050": [
0,
0,
0,
100,
0,
0
],
"000051": [
0,
0,
0,
100,
100,
0
],
"000052": [
0,
0,
100,
100,
66.66666666666666,
0
],
"000054": [
0,
0,
50,
0,
100,
0
],
"000055": [
0,
0,
0,
100,
0,
0
],
"000056": [
0,
0,
50,
100,
0,
0
],
"000058": [
0,
0,
50,
0,
0,
66.66666666666666
],
"000060": [
0,
100,
0,
100,
0,
0
],
"000064": [
0,
0,
100,
100,
66.66666666666666,
0
],
"000065": [
0,
0,
0,
100,
0,
0
],
"000068": [
0,
0,
0,
100,
0,
0
],
"000069": [
0,
0,
0,
100,
0,
0
],
"000071": [
0,
0,
50,
0,
100,
33.33333333333333
],
"000073": [
0,
0,
0,
0,
33.33333333333333,
33.33333333333333
],
"000076": [
0,
0,
0,
100,
0,
0
],
"000077": [
0,
0,
0,
0,
0,
33.33333333333333
],
"000078": [
0,
0,
50,
0,
0,
100
],
"000079": [
0,
0,
0,
100,
100,
0
],
"000080": [
0,
0,
50,
100,
0,
0
],
"000081": [
0,
33.33333333333333,
0,
100,
0,
0
],
"000083": [
0,
0,
100,
0,
33.33333333333333,
100
],
"000085": [
0,
0,
100,
0,
33.33333333333333,
33.33333333333333
],
"000086": [
0,
0,
50,
0,
66.66666666666666,
0
],
"000088": [
0,
0,
0,
0,
33.33333333333333,
33.33333333333333
],
"000091": [
0,
0,
0,
100,
0,
0
],
"000092": [
0,
0,
50,
0,
100,
66.66666666666666
],
"000096": [
0,
0,
0,
0,
33.33333333333333,
66.66666666666666
],
"000097": [
0,
0,
50,
0,
66.66666666666666,
33.33333333333333
],
"000099": [
0,
0,
100,
0,
66.66666666666666,
33.33333333333333
],
"000100": [
0,
0,
0,
0,
66.66666666666666,
100
],
"000103": [
0,
0,
100,
0,
66.66666666666666,
66.66666666666666
],
"000104": [
0,
0,
50,
100,
100,
0
],
"000106": [
0,
0,
0,
0,
66.66666666666666,
0
],
"000108": [
0,
0,
50,
0,
100,
66.66666666666666
],
"000109": [
0,
0,
100,
100,
66.66666666666666,
0
],
"000110": [
0,
0,
100,
0,
66.66666666666666,
0
],
"000111": [
0,
66.66666666666666,
0,
0,
66.66666666666666,
66.66666666666666
],
"000114": [
0,
0,
0,
100,
0,
0
],
"000115": [
0,
0,
100,
100,
100,
0
],
"000116": [
0,
0,
0,
100,
66.66666666666666,
0
],
"000117": [
0,
100,
0,
0,
0,
100
],
"000118": [
0,
33.33333333333333,
0,
0,
0,
66.66666666666666
],
"000121": [
0,
0,
0,
0,
0,
0
],
"000122": [
0,
0,
50,
0,
100,
100
],
"000125": [
0,
0,
50,
100,
66.66666666666666,
0
],
"000126": [
0,
0,
100,
0,
100,
33.33333333333333
],
"000129": [
0,
0,
100,
100,
0,
0
],
"000131": [
0,
66.66666666666666,
0,
0,
0,
66.66666666666666
],
"000132": [
0,
33.33333333333333,
0,
0,
0,
100
],
"000133": [
0,
0,
50,
0,
100,
33.33333333333333
],
"000134": [
0,
100,
0,
100,
0,
0
],
"000135": [
0,
66.66666666666666,
0,
100,
0,
0
],
"000137": [
0,
0,
50,
100,
0,
0
],
"000140": [
0,
0,
50,
0,
100,
33.33333333333333
],
"000142": [
0,
0,
50,
0,
33.33333333333333,
0
],
"000143": [
0,
0,
50,
100,
66.66666666666666,
0
],
"000145": [
0,
0,
0,
0,
0,
0
],
"000146": [
0,
0,
0,
0,
33.33333333333333,
33.33333333333333
],
"000147": [
0,
0,
50,
0,
100,
33.33333333333333
],
"000148": [
0,
0,
50,
0,
0,
33.33333333333333
],
"000150": [
0,
0,
50,
100,
33.33333333333333,
0
],
"000151": [
0,
0,
0,
0,
0,
0
],
"000152": [
0,
0,
50,
100,
66.66666666666666,
0
],
"000153": [
0,
0,
0,
100,
0,
0
],
"000155": [
0,
0,
0,
0,
33.33333333333333,
33.33333333333333
],
"000156": [
0,
0,
100,
0,
100,
33.33333333333333
],
"000157": [
0,
0,
50,
0,
100,
0
],
"000160": [
0,
0,
0,
100,
0,
0
],
"000161": [
0,
0,
50,
0,
0,
33.33333333333333
]
}
{
"000001": [
0,
0,
44,
0,
65,
100,
35
],
"000002": [
0,
0,
100,
100,
56.00000000000001,
100,
100
],
"000005": [
0,
0,
26,
100,
67,
53,
37
],
"000006": [
0,
0,
31,
100,
80,
89,
0
],
"000007": [
100,
100,
80,
0,
20,
100,
100
],
"000009": [
0,
0,
73,
0,
100,
33,
26
],
"000010": [
0,
0,
10,
0,
62,
17,
100
],
"000013": [
100,
100,
12,
2,
28.000000000000004,
24,
100
],
"000014": [
0,
0,
85,
100,
90,
100,
0
],
"000015": [
100,
100,
21,
0,
90,
56.00000000000001,
100
],
"000016": [
100,
100,
84,
16,
91,
89,
100
],
"000018": [
0,
0,
0,
100,
66,
89,
100
],
"000020": [
100,
100,
79,
0,
62,
100,
100
],
"000023": [
100,
100,
84,
0,
38,
28.999999999999996,
100
],
"000028": [
0,
0,
86,
0,
71,
100,
35
],
"000029": [
0,
0,
0,
0,
61,
0,
80
],
"000030": [
100,
100,
9,
35,
30,
88,
80
],
"000031": [
0,
0,
69,
11,
81,
4,
53
],
"000032": [
100,
100,
34,
60,
72,
100,
53
],
"000035": [
0,
0,
71,
49,
100,
48,
100
],
"000037": [
100,
100,
28.000000000000004,
100,
68,
100,
100
],
"000038": [
100,
100,
36,
0,
50,
30,
100
],
"000040": [
0,
0,
55.00000000000001,
0,
49,
90,
100
],
"000041": [
100,
100,
63,
39,
65,
100,
100
],
"000042": [
0,
0,
64,
15,
100,
6,
51
],
"000043": [
0,
0,
73,
0,
49,
53,
51
],
"000044": [
0,
0,
67,
0,
78,
100,
0
],
"000045": [
0,
0,
91,
0,
100,
100,
5
],
"000047": [
0,
0,
78,
0,
53,
100,
0
],
"000048": [
100,
100,
57.99999999999999,
0,
55.00000000000001,
100,
0
],
"000050": [
100,
100,
68,
0,
66,
100,
0
],
"000051": [
100,
100,
0,
5,
11,
100,
0
],
"000052": [
100,
100,
77,
68,
54,
100,
0
],
"000054": [
0,
0,
0,
8,
85,
38,
47
],
"000055": [
100,
100,
84,
2,
68,
81,
47
],
"000056": [
100,
100,
78,
2,
75,
31,
47
],
"000058": [
0,
0,
80,
2,
82,
0,
100
],
"000060": [
100,
100,
14.000000000000002,
100,
20,
100,
100
],
"000064": [
100,
100,
64,
0,
49,
100,
100
],
"000065": [
100,
100,
75,
37,
73,
100,
100
],
"000068": [
100,
100,
0,
27,
0,
31,
100
],
"000069": [
100,
100,
79,
75,
77,
100,
100
],
"000071": [
0,
0,
0,
38,
57.99999999999999,
20,
99
],
"000073": [
0,
0,
78,
38,
75,
70,
27
],
"000076": [
100,
100,
78,
5,
43,
100,
27
],
"000077": [
0,
0,
77,
5,
50,
100,
59
],
"000078": [
0,
0,
68,
5,
100,
67,
17
],
"000079": [
100,
100,
0,
4,
47,
67,
17
],
"000080": [
100,
100,
70,
17,
16,
100,
17
],
"000081": [
100,
100,
77,
0,
91,
100,
17
],
"000083": [
0,
0,
77,
0,
91,
74,
85
],
"000085": [
0,
0,
83,
0,
73,
17,
100
],
"000086": [
0,
0,
53,
0,
64,
100,
100
],
"000088": [
0,
0,
88,
0,
77,
81,
76
],
"000091": [
100,
100,
78,
0,
68,
100,
76
],
"000092": [
0,
0,
0,
0,
94,
17,
100
],
"000096": [
0,
0,
45,
0,
100,
100,
0
],
"000097": [
0,
0,
53,
0,
63,
0,
51
],
"000099": [
0,
0,
49,
0,
83,
28.000000000000004,
42
],
"000100": [
0,
0,
0,
0,
100,
50,
100
],
"000103": [
0,
0,
79,
0,
100,
0,
81
],
"000104": [
100,
100,
30,
0,
55.00000000000001,
40,
81
],
"000106": [
0,
0,
43,
0,
100,
94,
38
],
"000108": [
0,
0,
0,
0,
100,
0,
92
],
"000109": [
100,
100,
65,
21,
56.99999999999999,
0,
92
],
"000110": [
0,
0,
55.00000000000001,
28.000000000000004,
50,
12,
62
],
"000111": [
0,
0,
0,
36,
100,
100,
0
],
"000114": [
100,
100,
69,
0,
34,
100,
0
],
"000115": [
100,
100,
0,
0,
71,
6,
0
],
"000116": [
100,
100,
68,
0,
41,
100,
0
],
"000117": [
0,
0,
74,
0,
100,
100,
0
],
"000118": [
0,
0,
74,
0,
76,
100,
0
],
"000121": [
0,
0,
62,
0,
67,
100,
69
],
"000122": [
0,
0,
0,
0,
100,
100,
100
],
"000125": [
100,
100,
40,
42,
26,
0,
100
],
"000126": [
0,
0,
0,
42,
31,
0,
100
],
"000129": [
100,
100,
82,
0,
64,
56.00000000000001,
100
],
"000131": [
0,
0,
72,
3,
100,
100,
0
],
"000132": [
0,
0,
72,
3,
61,
100,
16
],
"000133": [
0,
0,
0,
3,
87,
0,
33
],
"000134": [
100,
100,
76,
100,
37,
100,
33
],
"000135": [
100,
100,
74,
37,
50,
100,
33
],
"000137": [
100,
100,
74,
34,
50,
48,
33
],
"000140": [
0,
0,
0,
34,
65,
18,
17
],
"000142": [
0,
0,
71,
32,
45,
0,
100
],
"000143": [
100,
100,
69,
6,
68,
0,
100
],
"000145": [
0,
0,
76,
0,
77,
100,
11
],
"000146": [
0,
0,
91,
0,
55.00000000000001,
100,
11
],
"000147": [
0,
0,
0,
0,
70,
74,
9
],
"000148": [
0,
0,
81,
0,
56.00000000000001,
0,
100
],
"000150": [
100,
100,
94,
0,
49,
68,
100
],
"000151": [
0,
0,
69,
0,
66,
56.00000000000001,
60
],
"000152": [
100,
100,
25,
57.99999999999999,
64,
33,
60
],
"000153": [
100,
100,
68,
57.99999999999999,
68,
75,
60
],
"000155": [
0,
0,
100,
57.99999999999999,
84,
100,
28.000000000000004
],
"000156": [
0,
0,
0,
57.99999999999999,
67,
0,
100
],
"000157": [
0,
0,
0,
57.99999999999999,
63,
0,
31
],
"000160": [
100,
100,
73,
0,
37,
100,
31
],
"000161": [
0,
0,
66,
0,
45,
0,
100
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 7;
// other variables can be in here too
// here's some examples for colors used
// const yee_bg_color = [225, 206, 187];
// const yee_fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function YeeFace() {
// these are state variables for a face
// (your variables should be different!)
this.gender = 1;
this.suits = 0;
this.eyeball_move = 0;
this.eye_color = 0;
this.blush_color = 0;
this.mouth_open = 0;
this.hair_bun = 0;
this.hair_color = 0;
const skin = [255, 229, 184];
const gold = [255, 227, 82];
const mustache = [204, 150, 82];
const red = [250, 80, 80];
const black = [50];
const pink = [255, 200, 200];
const orange = [255, 140, 0];
const brown = [130, 90, 5];
const grey = [120];
const blue = [52, 141, 224];
const shadow = [180, 130, 10];
const hair_black = [30];
const hair_yellow = [219, 175, 39];
const hair_brown = [105, 76, 29];
const hair_red = [128, 44, 23];
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
let crown_dist = dist(positions.left_eye[0][0], positions.left_eye[0][1], positions.right_eye[3][0], positions.right_eye[3][1]);
let crown_1 = dist(positions.right_eye[3][0], positions.right_eye[3][1], positions.chin[16][0], positions.chin[16][1]);
let crown_2 = dist(positions.chin[0][0], positions.chin[0][1], positions.left_eye[0][0], positions.left_eye[0][1]);
let map_crown1 = map(crown_1, 0.2, 1.8, 0.1, -0.2);
let map_crown2 = map(crown_2, 0.2, 1.5, 0.1, -0.2);
let map_hairbun1 = map(crown_1, 0.2, 1.8, 1.5, 0.5);
let map_hairbun2 = map(crown_2, 0.2, 1.8, 0.5, 1.5);
noStroke();
angleMode(DEGREES);
//Face
fill(skin);
beginShape();
noStroke();
curveVertex(positions.chin[0][0], positions.chin[0][1]-0.8);
curveVertex(positions.chin[4][0]-0.5, positions.chin[4][1]);
curveVertex(positions.chin[8][0], positions.chin[8][1]);
curveVertex(positions.chin[12][0]+0.1, positions.chin[12][1]+0.1);
curveVertex(positions.chin[16][0]-0.2, positions.chin[16][1]-0.8);
curveVertex(positions.chin[0][0], positions.chin[0][1]-0.8);
curveVertex(positions.chin[4][0]-0.5, positions.chin[4][1]);
curveVertex(positions.chin[8][0], positions.chin[8][1]);
curveVertex(positions.chin[12][0], positions.chin[12][1]);
endShape();
//Left_eye
fill(255);
push();
translate(0, 0.3);
beginShape();
noStroke();
curveVertex(positions.left_eye[0][0]-0.5, positions.left_eye[0][1]+0.2);
curveVertex(positions.left_eye[1][0]-0.3, positions.left_eye[1][1]);
curveVertex(positions.left_eye[2][0], positions.left_eye[2][1]);
curveVertex(positions.left_eye[3][0], positions.left_eye[3][1]);
curveVertex(positions.left_eye[4][0], positions.left_eye[4][1]+0.3);
curveVertex(positions.left_eye[5][0]-0.4, positions.left_eye[5][1]+0.3);
curveVertex(positions.left_eye[0][0]-0.5, positions.left_eye[0][1]+0.1);
curveVertex(positions.left_eye[1][0]-0.3, positions.left_eye[1][1]);
curveVertex(positions.left_eye[2][0], positions.left_eye[2][1]);
endShape();
pop();
//Right_eye
push();
translate(0, 0.3);
beginShape();
noStroke();
curveVertex(positions.right_eye[0][0], positions.right_eye[0][1]);
curveVertex(positions.right_eye[1][0], positions.right_eye[1][1]);
curveVertex(positions.right_eye[2][0]+0.3, positions.right_eye[2][1]);
curveVertex(positions.right_eye[3][0]+0.3, positions.right_eye[3][1]+0.1);
curveVertex(positions.right_eye[4][0]+0.3, positions.right_eye[4][1]+0.25);
curveVertex(positions.right_eye[5][0], positions.right_eye[5][1]+0.25);
curveVertex(positions.right_eye[0][0], positions.right_eye[0][1]);
curveVertex(positions.right_eye[1][0], positions.right_eye[1][1]);
curveVertex(positions.right_eye[2][0]+0.3, positions.right_eye[2][1]);
endShape();
pop();
//Eyeball color
if(this.eye_color >0 && this.eye_color <= 1){
fill(brown);
}else
if(this.eye_color >1 && this.eye_color <= 2){
fill(black);
}else
if(this.eye_color >2 && this.eye_color <= 3){
fill(grey);
}else
if(this.eye_color >3 && this.eye_color <= 4){
fill(blue);
}
//Eyeball
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
ellipse(left_eye_pos[0]+this.eyeball_move, left_eye_pos[1]+0.4, 0.2, 0.3);
ellipse(right_eye_pos[0]+this.eyeball_move, right_eye_pos[1]+0.35, 0.2, 0.3);
//Blush
let from = color(pink);
let to = color(orange);
colorMode(RGB);
let inter = lerpColor(from, to, this.blush_color);
fill(inter);
ellipse(positions.top_lip[0][0]-0.5, positions.top_lip[0][1]-0.2, 0.8);
ellipse(positions.top_lip[6][0]+0.5, positions.top_lip[6][1]-0.2, 0.8);
//nose
fill(100);
if(positions.nose_tip[2][1] < 0.1){
ellipse(positions.nose_tip[1][0], positions.nose_tip[1][1], 0.2, 0.15);
ellipse(positions.nose_tip[3][0], positions.nose_tip[3][1], 0.2, 0.15);
}
if (this.gender < 0 && this.gender <= 0.5){
///QUEEN///
//Hair color
if(this.hair_color > 0 && this.hair_color <= 1){
fill(hair_black);
}else
if(this.hair_color > 1 && this.hair_color <= 2){
fill(hair_brown);
}else
if(this.hair_color > 2 && this.hair_color <= 3){
fill(hair_red);
}else
if(this.hair_color > 3 && this.hair_color <= 4){
fill(hair_yellow);
}
//Queen hair
push();
beginShape();
curveVertex(positions.chin[0][0]-0.5, positions.chin[0][1]-1);
curveVertex(positions.chin[1][0]-0.5, positions.chin[1][1]-0.5);
curveVertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-0.3);
curveVertex(positions.chin[15][0]+0.1, positions.chin[15][1]-0.3);
curveVertex(positions.chin[16][0]+0.1, positions.chin[16][1]-1);
curveVertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1]-1.2);
curveVertex(positions.left_eyebrow[1][0], positions.left_eyebrow[2][1]-1);
curveVertex(positions.chin[0][0]-0.5, positions.chin[0][1]-1);
curveVertex(positions.chin[1][0]-0.5, positions.chin[1][1]-0.5);
curveVertex(positions.left_eyebrow[1][0], positions.left_eyebrow[1][1]-0.3);
endShape();
pop();
//Hair 'bun'
let bun = segment_average(positions.chin);
if(positions.nose_bridge[0][0] < -0.17){
push();
translate(positions.nose_bridge[0][0]+map_hairbun2, positions.nose_bridge[0][1]-2.6);
beginShape();
curveVertex(bun[0], bun[1]);
curveVertex(bun[0], bun[1]-1);
curveVertex(bun[0]+1, bun[1]-1);
curveVertex(bun[0]+1, bun[1]);
curveVertex(bun[0], bun[1]);
curveVertex(bun[0], bun[1]-1);
curveVertex(bun[0]+1, bun[1]-1);
endShape();
pop();
}else{
push();
translate(positions.nose_bridge[0][0]-map_hairbun1, positions.nose_bridge[0][1]-2.6);
beginShape();
curveVertex(bun[0], bun[1]);
curveVertex(bun[0], bun[1]-1);
curveVertex(bun[0]+1, bun[1]-1);
curveVertex(bun[0]+1, bun[1]);
curveVertex(bun[0], bun[1]);
curveVertex(bun[0], bun[1]-1);
curveVertex(bun[0]+1, bun[1]-1);
endShape();
pop();
}
//Queen crown_left shadow
if (positions.nose_bridge[0][0] < -0.05){
push();
fill(shadow);
translate(positions.nose_bridge[0][0]+0.4, positions.nose_bridge[0][1]-0.8);
beginShape();
vertex(-crown_dist/2, -0.5-map_crown2);
vertex(0.2+crown_dist/2, -0.5-map_crown1);
vertex(0.2+crown_dist/2, 0);
vertex(-crown_dist/2, 0);
endShape();
triangle(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-0.2,
positions.nose_bridge[0][0]-0.6, positions.nose_bridge[0][1]+0.7,
positions.nose_bridge[0][0]+0.6, positions.nose_bridge[0][1]+0.7);
pop();
}
//Queen crown_right shadow
if (positions.nose_bridge[0][0] > 0.05){
push();
fill(shadow);
translate(positions.nose_bridge[0][0]+0.2, positions.nose_bridge[0][1]-0.8);
beginShape();
vertex(-crown_dist/2, -0.5-map_crown2);
vertex(0.2+crown_dist/2, -0.5-map_crown1);
vertex(0.2+crown_dist/2, 0);
vertex(-crown_dist/2, 0);
endShape();
triangle(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-0.2,
positions.nose_bridge[0][0]-0.6, positions.nose_bridge[0][1]+0.7,
positions.nose_bridge[0][0]+0.6, positions.nose_bridge[0][1]+0.7);
pop();
}
//Queen crown
push();
fill(gold);
translate(positions.nose_bridge[0][0]+0.3, positions.nose_bridge[0][1]-0.8);
beginShape();
vertex(-crown_dist/2, -0.5-map_crown2);
vertex(0.2+crown_dist/2, -0.5-map_crown1);
vertex(0.2+crown_dist/2, 0);
vertex(-crown_dist/2, 0);
endShape();
triangle(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-0.2,
positions.nose_bridge[0][0]-0.6, positions.nose_bridge[0][1]+0.7,
positions.nose_bridge[0][0]+0.6, positions.nose_bridge[0][1]+0.7);
//Suits
fill(red);
translate(positions.nose_bridge[0][0]+0.1, positions.nose_bridge[0][1]+1.7);
scale(0.5);
if(this.suits > 0 && this.suits <= 1){
draw_diamond();
}
if(this.suits > 1 && this.suits <= 2){
draw_heart();
}
if(this.suits > 2 && this.suits <= 3){
draw_spade();
}
if(this.suits > 3 && this.suits <=4){
draw_club();
}
pop();
//Queen mouth
push();
fill(255);
translate(0, 0.2);
beginShape();
curveVertex(positions.top_lip[7][0], positions.top_lip[6][1]);
curveVertex(positions.top_lip[8][0], positions.top_lip[8][1]);
curveVertex(positions.top_lip[9][0], positions.top_lip[9][1]);
curveVertex(positions.top_lip[10][0], positions.top_lip[10][1]);
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]);
curveVertex(positions.bottom_lip[7][0], positions.bottom_lip[6][1]);
curveVertex(positions.bottom_lip[8][0], positions.bottom_lip[8][1]);
curveVertex(positions.bottom_lip[9][0], positions.bottom_lip[9][1]);
curveVertex(positions.bottom_lip[10][0], positions.bottom_lip[10][1]);
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]);
endShape();
pop();
//Queen lips
fill(red);
push();
translate(0, 0.2);
beginShape();
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]+0.05);
curveVertex(positions.top_lip[2][0], positions.top_lip[2][1]-0.03);
curveVertex(positions.top_lip[3][0], positions.top_lip[3][1]);
curveVertex(positions.top_lip[4][0], positions.top_lip[4][1]);
curveVertex(positions.top_lip[6][0], positions.top_lip[6][1]+0.05);
curveVertex(positions.top_lip[8][0], positions.top_lip[8][1]+0.05);
curveVertex(positions.top_lip[10][0], positions.top_lip[10][1]+0.05);
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]+0.05);
curveVertex(positions.top_lip[2][0], positions.top_lip[2][1]-0.03);
curveVertex(positions.top_lip[3][0], positions.top_lip[3][1]);
endShape();
beginShape();
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
curveVertex(positions.bottom_lip[1][0], positions.bottom_lip[1][1]);
curveVertex(positions.bottom_lip[2][0], positions.bottom_lip[2][1]);
curveVertex(positions.bottom_lip[3][0], positions.bottom_lip[3][1]);
curveVertex(positions.bottom_lip[5][0], positions.bottom_lip[5][1]);
curveVertex(positions.bottom_lip[6][0], positions.bottom_lip[6][1]);
curveVertex(positions.bottom_lip[8][0], positions.bottom_lip[8][1]);
curveVertex(positions.bottom_lip[9][0], positions.bottom_lip[9][1]);
curveVertex(positions.bottom_lip[10][0], positions.bottom_lip[10][1]);
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
curveVertex(positions.bottom_lip[1][0], positions.bottom_lip[1][1]);
curveVertex(positions.bottom_lip[3][0], positions.bottom_lip[3][1]);
endShape();
pop();
}else{
///KING///
//King crown_left shadow
if (positions.nose_bridge[0][0] > 0.1){
push();
fill(shadow);
translate(-0.1, -0.05);
beginShape();
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]-map_crown1);
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1]-map_crown2);
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1]-1.5-map_crown1);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[0][1]-1);
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-2.3-map_crown1);
vertex(positions.left_eyebrow[4][0], positions.left_eyebrow[4][1]-1);
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]-1.5-map_crown2);
endShape();
pop();
}
//King crown_right shadow
if (positions.nose_bridge[0][0] < -0.1){
push();
fill(shadow);
translate(0.1, -0.05);
beginShape();
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]-map_crown1);
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1]-map_crown2);
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1]-1.5-map_crown1);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[0][1]-1);
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-2.3-map_crown1);
vertex(positions.left_eyebrow[4][0], positions.left_eyebrow[4][1]-1);
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]-1.5-map_crown2);
endShape();
pop();
}
//King crown
fill(gold);
push();
beginShape();
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]-map_crown1);
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1]-map_crown2);
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1]-1.5-map_crown1);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[0][1]-1);
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-2.3-map_crown1);
vertex(positions.left_eyebrow[4][0], positions.left_eyebrow[4][1]-1);
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]-1.5-map_crown2);
endShape();
pop();
push();
fill(red);
translate(positions.nose_bridge[0][0]+0.1, positions.nose_bridge[0][1]+0.1);
scale(0.5);
if(this.suits > 0 && this.suits <= 1){
draw_diamond();
}
if(this.suits > 1 && this.suits <= 2){
draw_heart();
}
if(this.suits > 2 && this.suits <= 3){
draw_spade();
}
if(this.suits > 3 && this.suits <=4){
draw_club();
}
pop();
//King mustache
fill(mustache);
beginShape();
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]+0.1);
curveVertex(positions.top_lip[6][0], positions.top_lip[6][1]+0.1);
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[1][1]+0.8);
curveVertex(positions.bottom_lip[5][0], positions.bottom_lip[5][1]+0.8);
curveVertex(positions.top_lip[0][0], positions.top_lip[0][1]+0.1);
curveVertex(positions.top_lip[6][0], positions.top_lip[6][1]+0.1);
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[1][1]+0.8);
endShape();
fill(255);
//King mouth
translate(0, 0.3);
beginShape();
curveVertex(positions.bottom_lip[7][0]+0.2, positions.bottom_lip[7][1]);
curveVertex(positions.top_lip[7][0]-0.2, positions.top_lip[7][1]);
curveVertex(positions.bottom_lip[10][0], positions.bottom_lip[10][1]+this.mouth_open);
curveVertex(positions.bottom_lip[8][0], positions.bottom_lip[8][1]+this.mouth_open);
curveVertex(positions.bottom_lip[7][0]+0.2, positions.bottom_lip[7][1]);
curveVertex(positions.top_lip[7][0]-0.2, positions.top_lip[7][1]);
curveVertex(positions.bottom_lip[10][0], positions.bottom_lip[10][1]+this.mouth_open);
endShape();
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.gender = map(settings[0],0, 1, 0.5, 0);
this.suits = map(settings[1], 0, 100, 1, 4);
this.eyeball_move = map(settings[2], 0, 100, -0.1, 0.1);
this.eye_color = map(settings[3], 0, 100, 1, 4);
this.blush_color = map(settings[4], 0, 100, 0, 1);
this.mouth_open = map(settings[5], 0, 100, 0.05, 0.3);
this.hair_color = map(settings[6], 0, 100, 1, 4);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(7);
settings[0] = map(this.gender, 0.5, 0, 0, 1);
settings[1] = map(this.suits, 0, 4, 0, 100);
settings[2] = map(this.eyeball_move, -0.1, 0.1, 0, 100);
settings[3] = map(this.eye_color, 1, 4, 0, 100);
settings[4] = map(this.blush_color, 0, 1, 0, 100);
settings[5] = map(this.mouth_open, 0.05, 0.3, 0, 100);
settings[6] = map(this.hair_color, 1, 4, 0, 100);
return settings;
}
}
//Suits
function draw_diamond(){
beginShape();
vertex(-0.7, -2.5);
vertex(-0.2, -3);
vertex(0.3, -2.5);
vertex(-0.2, -2);
endShape();
}
function draw_heart(){
beginShape();
vertex(-0.7, -2.5);
vertex(-0.4, -2.8);
vertex(-0.2, -2.6);
vertex(0, -2.8);
vertex(0.3, -2.5);
vertex(-0.2, -2);
endShape();
}
function draw_spade(){
beginShape();
vertex(-0.7, -2.5);
vertex(-0.2, -3);
vertex(0.3, -2.5);
vertex(0, -2.3);
vertex(-0.2, -2.5);
vertex(-0.4, -2.3);
endShape();
triangle(-0.2, -2.5, -0.05, -2.1, -0.35, -2.1);
}
function draw_club(){
beginShape();
vertex(-0.2, -2.5);
vertex(-0.35, -2.75);
vertex(-0.2, -3);
vertex(-0.05, -2.75);
vertex(-0.2, -2.5);
vertex(-0.45, -2.35);
vertex(-0.7, -2.5);
vertex(-0.45, -2.65);
vertex(-0.2, -2.5);
vertex(0, -2.65);
vertex(0.3, -2.5);
vertex(0, -2.35);
endShape();
triangle(-0.2, -2.5, -0.05, -2.1, -0.35, -2.1);
}
{
"000001": [
100,
73.75,
18.000000000000004,
26,
16,
58.00000000000001,
100
],
"000002": [
100,
100,
0,
17,
0,
33,
62
],
"000005": [
100,
81.25,
0,
45,
0,
66.00000000000001,
100
],
"000006": [
100,
100,
100,
0,
100,
0,
26
],
"000007": [
0,
53.5,
0,
11.999999999999995,
0,
33,
33
],
"000009": [
100,
43.75,
0,
19.000000000000004,
33,
33,
17
],
"000010": [
100,
56.49999999999999,
0,
41.99999999999999,
0,
66.00000000000001,
100
],
"000013": [
0,
41.5,
35.99999999999999,
48.99999999999999,
0,
66.00000000000001,
0
],
"000014": [
100,
43.75,
0,
0,
100,
33,
0
],
"000015": [
0,
57.25,
38.00000000000001,
44.000000000000014,
0,
66.00000000000001,
0
],
"000016": [
0,
92.5,
100,
9.000000000000002,
66,
33,
0
],
"000018": [
100,
63.25000000000001,
9.000000000000002,
45,
0,
66.00000000000001,
94
],
"000020": [
0,
56.49999999999999,
43,
13.000000000000004,
33,
0,
0
],
"000023": [
0,
100,
9.000000000000002,
45,
0,
100,
0
],
"000025": [
0,
45.25,
9.000000000000002,
45,
66,
0,
0
],
"000028": [
100,
56.49999999999999,
9.000000000000002,
26,
66,
0,
65
],
"000029": [
100,
36.25,
9.000000000000002,
100,
0,
100,
100
],
"000030": [
0,
25,
0,
0,
66,
66.00000000000001,
0
],
"000031": [
100,
57.25,
0,
63,
33,
66.00000000000001,
28.000000000000004
],
"000032": [
0,
41.5,
5.999999999999998,
0,
33,
0,
0
],
"000035": [
100,
49.75,
5.999999999999998,
41.99999999999999,
0,
66.00000000000001,
0
],
"000037": [
0,
75.25,
26,
0,
100,
0,
0
],
"000038": [
0,
52,
46,
61,
0,
100,
0
],
"000040": [
100,
71.5,
46,
31,
0,
33,
0
],
"000041": [
0,
25,
3.0000000000000027,
0,
66,
0,
33
],
"000042": [
100,
61,
3.0000000000000027,
63,
0,
66.00000000000001,
33
],
"000043": [
100,
53.5,
3.0000000000000027,
16,
33,
33,
0
],
"000044": [
100,
53.5,
3.0000000000000027,
0,
100,
0,
0
],
"000045": [
100,
53.5,
3.0000000000000027,
15,
0,
33,
43
],
"000047": [
100,
65.5,
3.0000000000000027,
0,
100,
0,
0
],
"000048": [
0,
45.25,
0,
0,
0,
0,
0
],
"000050": [
0,
52,
32,
11.999999999999995,
33,
33,
0
],
"000051": [
0,
37.75,
0,
0,
66,
0,
0
],
"000052": [
0,
47,
6,
51,
66,
100,
0
],
"000054": [
100,
34.75,
5.999999999999998,
56.00000000000001,
0,
66.00000000000001,
100
],
"000055": [
0,
48.25,
17,
13.000000000000004,
0,
33,
0
],
"000056": [
0,
43.75,
0,
52,
0,
66.00000000000001,
0
],
"000058": [
100,
78.25,
0,
88,
0,
66.00000000000001,
0
],
"000060": [
0,
47.5,
16,
0,
100,
0,
0
],
"000064": [
0,
47.5,
11.000000000000004,
56.00000000000001,
33,
66.00000000000001,
0
],
"000065": [
0,
45.25,
22,
19.000000000000004,
100,
0,
0
],
"000068": [
0,
57.25,
48,
13.999999999999998,
66,
33,
0
],
"000069": [
0,
35.5,
12.999999999999998,
25,
66,
33,
0
],
"000071": [
100,
66.25000000000001,
62,
36.99999999999999,
33,
66.00000000000001,
100
],
"000073": [
100,
63.25000000000001,
0,
19.000000000000004,
33,
33,
0
],
"000076": [
0,
25,
0,
0,
33,
0,
0
],
"000077": [
100,
76.75,
60,
0,
33,
0,
0
],
"000078": [
100,
28.000000000000004,
9.000000000000002,
65,
34,
0,
0
],
"000079": [
0,
69.25,
61,
16,
33,
0,
0
],
"000080": [
0,
25,
28.999999999999996,
64,
21,
0,
0
],
"000081": [
0,
76.75,
100,
20.000000000000004,
33,
33,
0
],
"000083": [
100,
72.25,
0,
46,
0,
0,
22.000000000000007
],
"000085": [
100,
70,
30,
51.000000000000014,
0,
0,
63
],
"000086": [
100,
25,
0,
20.999999999999996,
0,
33,
33
],
"000088": [
100,
85.00000000000001,
66,
0,
0,
33,
52.99999999999999
],
"000091": [
0,
49,
0,
44.000000000000014,
0,
33,
100
],
"000092": [
100,
49.75,
0,
46,
33,
66.00000000000001,
100
],
"000096": [
100,
39.25,
0,
0,
66,
0,
0
],
"000097": [
100,
61,
0,
100,
0,
77,
30
],
"000099": [
100,
52.75,
0,
57.99999999999999,
0,
66.00000000000001,
32
],
"000100": [
100,
52.75,
0,
16,
0,
33,
100
],
"000103": [
100,
25,
0,
64,
0,
66.00000000000001,
0
],
"000104": [
0,
49,
21,
50,
0,
100,
0
],
"000106": [
100,
68.5,
0,
0,
33,
33,
33
],
"000108": [
100,
53.5,
9.000000000000002,
43,
33,
66.00000000000001,
100
],
"000109": [
0,
39.25,
12.999999999999998,
47,
66,
66.00000000000001,
0
],
"000110": [
100,
48.25,
15,
55.000000000000014,
33,
66.00000000000001,
24
],
"000111": [
100,
84.25,
78.00000000000001,
0,
100,
33,
100
],
"000114": [
0,
41.5,
5.000000000000004,
25,
0,
33,
0
],
"000115": [
0,
50.5,
22,
41,
0,
66.00000000000001,
0
],
"000116": [
0,
45.25,
26,
15,
33,
0,
0
],
"000117": [
100,
57.25,
24,
0,
100,
0,
0
],
"000118": [
100,
25,
0,
22.000000000000007,
66,
33,
0
],
"000121": [
100,
43.75,
8,
13.999999999999998,
33,
33,
0
],
"000122": [
100,
72.25,
5.999999999999998,
10.000000000000002,
0,
33,
100
],
"000125": [
0,
67,
20.000000000000004,
100,
33,
100,
0
],
"000126": [
100,
70,
26,
80.00000000000001,
100,
66.00000000000001,
100
],
"000129": [
0,
49.75,
23,
45,
0,
66.00000000000001,
0
],
"000131": [
100,
100,
100,
0,
66,
0,
0
],
"000132": [
100,
45.25,
11.999999999999996,
0,
66,
0,
0
],
"000133": [
100,
33.25,
9.000000000000002,
59,
11,
66.00000000000001,
33
],
"000134": [
0,
25,
0,
0,
100,
0,
0
],
"000135": [
0,
100,
100,
0,
66,
0,
0
],
"000137": [
0,
100,
68,
38.99999999999999,
0,
33,
0
],
"000140": [
100,
52,
13.999999999999998,
55.000000000000014,
100,
100,
100
],
"000142": [
100,
61,
3.0000000000000027,
38.99999999999999,
0,
66.00000000000001,
28.000000000000004
],
"000143": [
0,
50,
34,
100,
33,
100,
33
],
"000145": [
100,
47.5,
34,
10.000000000000002,
33,
33,
0
],
"000146": [
100,
43.75,
34,
13.999999999999998,
33,
33,
38.99999999999999
],
"000147": [
100,
100,
48,
59,
66,
100,
100
],
"000148": [
100,
100,
34,
56.99999999999999,
0,
66,
0
],
"000150": [
0,
1.0000000000000009,
0,
56.99999999999999,
0,
66,
0
],
"000151": [
100,
39.25,
0,
0,
33,
0,
0
],
"000152": [
0,
52,
34,
56.99999999999999,
66,
66,
0
],
"000153": [
0,
38.5,
27,
23,
33,
33,
0
],
"000155": [
100,
51.24999999999999,
27,
22.000000000000007,
0,
33,
36.00000000000001
],
"000156": [
100,
72.25,
27,
46,
0,
66.00000000000001,
100
],
"000157": [
100,
28.749999999999996,
27,
100,
0,
66.00000000000001,
100
],
"000160": [
0,
61.74999999999999,
0,
28.000000000000004,
0,
33,
0
],
"000161": [
100,
0,
0,
100,
0,
66,
0
]
}
[{"weights":[{"name":"dense0/conv0/filters","shape":[3,3,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004853619781194949,"min":-0.5872879935245888}},{"name":"dense0/conv0/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004396426443960153,"min":-0.7298067896973853}},{"name":"dense0/conv1/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00635151559231328,"min":-0.5589333721235686}},{"name":"dense0/conv1/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009354315552057004,"min":-1.2628325995276957}},{"name":"dense0/conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0029380727048013726,"min":-0.5846764682554731}},{"name":"dense0/conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0049374802439820535,"min":-0.6171850304977566}},{"name":"dense0/conv2/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009941946758943446,"min":-1.3421628124573652}},{"name":"dense0/conv2/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030300481062309416,"min":-0.5272283704841838}},{"name":"dense0/conv3/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005672684837790097,"min":-0.7431217137505026}},{"name":"dense0/conv3/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010712201455060173,"min":-1.5639814124387852}},{"name":"dense0/conv3/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030966934035806097,"min":-0.3839899820439956}},{"name":"dense1/conv0/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0039155554537679636,"min":-0.48161332081345953}},{"name":"dense1/conv0/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01023082966898002,"min":-1.094698774580862}},{"name":"dense1/conv0/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0027264176630506327,"min":-0.3871513081531898}},{"name":"dense1/conv1/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004583378632863362,"min":-0.5454220573107401}},{"name":"dense1/conv1/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00915846403907327,"min":-1.117332612766939}},{"name":"dense1/conv1/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003091680419211294,"min":-0.5966943209077797}},{"name":"dense1/conv2/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005407439727409214,"min":-0.708374604290607}},{"name":"dense1/conv2/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00946493943532308,"min":-1.2399070660273235}},{"name":"dense1/conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004409168514550901,"min":-0.9788354102303}},{"name":"dense1/conv3/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004478132958505668,"min":-0.6493292789833219}},{"name":"dense1/conv3/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011063695888893277,"min":-1.2501976354449402}},{"name":"dense1/conv3/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003909627596537272,"min":-0.6646366914113363}},{"name":"dense2/conv0/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003213915404151468,"min":-0.3374611174359041}},{"name":"dense2/conv0/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010917326048308728,"min":-1.4520043644250609}},{"name":"dense2/conv0/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002800439152063108,"min":-0.38085972468058266}},{"name":"dense2/conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0050568851770139206,"min":-0.6927932692509071}},{"name":"dense2/conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01074961213504567,"min":-1.3222022926106174}},{"name":"dense2/conv1/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0030654204242369708,"min":-0.5487102559384177}},{"name":"dense2/conv2/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00591809165244009,"min":-0.917304206128214}},{"name":"dense2/conv2/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01092823346455892,"min":-1.366029183069865}},{"name":"dense2/conv2/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002681120470458386,"min":-0.36463238398234055}},{"name":"dense2/conv3/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0048311497650894465,"min":-0.5797379718107336}},{"name":"dense2/conv3/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.011227761062921263,"min":-1.4483811771168429}},{"name":"dense2/conv3/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0034643323982463162,"min":-0.3360402426298927}},{"name":"dense3/conv0/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003394978887894574,"min":-0.49227193874471326}},{"name":"dense3/conv0/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010051267287310432,"min":-1.2765109454884247}},{"name":"dense3/conv0/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003142924752889895,"min":-0.4588670139219247}},{"name":"dense3/conv1/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00448304671867221,"min":-0.5872791201460595}},{"name":"dense3/conv1/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.016063522357566685,"min":-2.3613377865623026}},{"name":"dense3/conv1/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00287135781026354,"min":-0.47664539650374765}},{"name":"dense3/conv2/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006002906724518421,"min":-0.7923836876364315}},{"name":"dense3/conv2/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.017087187019048954,"min":-1.6061955797906016}},{"name":"dense3/conv2/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003124481205846749,"min":-0.46242321846531886}},{"name":"dense3/conv3/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006576311588287353,"min":-1.0193282961845398}},{"name":"dense3/conv3/pointwise_filter","shape":[1,1,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015590153955945782,"min":-1.99553970636106}},{"name":"dense3/conv3/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004453541601405424,"min":-0.6546706154065973}},{"name":"fc/weights","shape":[256,136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010417488509533453,"min":-1.500118345372817}},{"name":"fc/bias","shape":[136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0025084222648658005,"min":0.07683877646923065}}],"paths":["z_face_landmark_68_model-shard1"]}]
[{"weights":[{"name":"conv32_down/conv/filters","shape":[7,7,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0005260649557207145,"min":-0.07101876902229645}},{"name":"conv32_down/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":8.471445956577858e-7,"min":-0.00014740315964445472}},{"name":"conv32_down/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.06814416062598135,"min":5.788674831390381}},{"name":"conv32_down/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008471635042452345,"min":-0.931879854669758}},{"name":"conv32_1/conv1/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0007328585666768691,"min":-0.0974701893680236}},{"name":"conv32_1/conv1/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.5952091238361e-8,"min":-0.000001978059313556764}},{"name":"conv32_1/conv1/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.02146628510718252,"min":3.1103382110595703}},{"name":"conv32_1/conv1/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0194976619645661,"min":-2.3787147596770644}},{"name":"conv32_1/conv2/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0004114975824075587,"min":-0.05267169054816751}},{"name":"conv32_1/conv2/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.600177166424806e-9,"min":-5.70421968636676e-7}},{"name":"conv32_1/conv2/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.03400764932819441,"min":2.1677730083465576}},{"name":"conv32_1/conv2/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010974494616190593,"min":-1.240117891629537}},{"name":"conv32_2/conv1/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0005358753251094444,"min":-0.0760942961655411}},{"name":"conv32_2/conv1/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":5.9886454383719385e-9,"min":-7.366033889197485e-7}},{"name":"conv32_2/conv1/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014633869657329485,"min":2.769575357437134}},{"name":"conv32_2/conv1/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.022131107367721257,"min":-2.5229462399202234}},{"name":"conv32_2/conv2/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00030145110452876373,"min":-0.03949009469326805}},{"name":"conv32_2/conv2/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":6.8779549306497095e-9,"min":-9.010120959151119e-7}},{"name":"conv32_2/conv2/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.03929369870354148,"min":4.8010945320129395}},{"name":"conv32_2/conv2/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010553357180427103,"min":-1.2452961472903983}},{"name":"conv32_3/conv1/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0003133527642371608,"min":-0.040735859350830905}},{"name":"conv32_3/conv1/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.1064200719547974e-9,"min":-3.0387508532465503e-7}},{"name":"conv32_3/conv1/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009252088210161994,"min":2.333256721496582}},{"name":"conv32_3/conv1/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007104101251153385,"min":-0.34810096130651585}},{"name":"conv32_3/conv2/conv/filters","shape":[3,3,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00029995629892629733,"min":-0.031195455088334923}},{"name":"conv32_3/conv2/conv/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":5.62726418316814e-9,"min":-6.921534945296811e-7}},{"name":"conv32_3/conv2/scale/weights","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0467432975769043,"min":5.362040996551514}},{"name":"conv32_3/conv2/scale/biases","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010314425300149357,"min":-1.268674311918371}},{"name":"conv64_down/conv1/conv/filters","shape":[3,3,32,64],"dtype":"float32"},{"name":"conv64_down/conv1/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":8.373908033218849e-10,"min":-1.172347124650639e-7}},{"name":"conv64_down/conv1/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0066875364266189875,"min":2.5088400840759277}},{"name":"conv64_down/conv1/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01691421620986041,"min":-2.0973628100226906}},{"name":"conv64_down/conv2/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_down/conv2/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.3252014483766877e-9,"min":-2.673981665633191e-7}},{"name":"conv64_down/conv2/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.032557439804077146,"min":2.6351239681243896}},{"name":"conv64_down/conv2/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015429047509735706,"min":-1.5429047509735707}},{"name":"conv64_1/conv1/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_1/conv1/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.1319172039756998e-9,"min":-1.4941307092479238e-7}},{"name":"conv64_1/conv1/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007802607031429515,"min":3.401733160018921}},{"name":"conv64_1/conv1/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01425027146058924,"min":-0.6982633015688727}},{"name":"conv64_1/conv2/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_1/conv2/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.5635019893325435e-9,"min":-2.717312108692496e-7}},{"name":"conv64_1/conv2/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.04062801716374416,"min":3.542381525039673}},{"name":"conv64_1/conv2/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007973166306813557,"min":-0.7415044665336609}},{"name":"conv64_2/conv1/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_2/conv1/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.2535732661062331e-9,"min":-1.8302169685151004e-7}},{"name":"conv64_2/conv1/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005631206549850164,"min":2.9051668643951416}},{"name":"conv64_2/conv1/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01859012585060269,"min":-2.3795361088771445}},{"name":"conv64_2/conv2/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_2/conv2/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.486726369919351e-9,"min":-3.5311514452854786e-7}},{"name":"conv64_2/conv2/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.03740917467603497,"min":5.571568965911865}},{"name":"conv64_2/conv2/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006418555858088475,"min":-0.5263215803632549}},{"name":"conv64_3/conv1/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_3/conv1/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":7.432564576875473e-10,"min":-8.47312361763804e-8}},{"name":"conv64_3/conv1/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006400122362024644,"min":2.268010377883911}},{"name":"conv64_3/conv1/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010945847922680425,"min":-1.3353934465670119}},{"name":"conv64_3/conv2/conv/filters","shape":[3,3,64,64],"dtype":"float32"},{"name":"conv64_3/conv2/conv/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.278228722014533e-9,"min":-3.212302498040492e-7}},{"name":"conv64_3/conv2/scale/weights","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.029840927498013366,"min":7.038398265838623}},{"name":"conv64_3/conv2/scale/biases","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.010651412197187834,"min":-1.161003929493474}},{"name":"conv128_down/conv1/conv/filters","shape":[3,3,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00020040544662989823,"min":-0.022245004575918704}},{"name":"conv128_down/conv1/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.3550543563576545e-10,"min":-4.311503812794078e-8}},{"name":"conv128_down/conv1/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007448580685783835,"min":2.830846071243286}},{"name":"conv128_down/conv1/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01211262824488621,"min":-1.6957679542840696}},{"name":"conv128_down/conv2/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00022380277514457702,"min":-0.02484210804104805}},{"name":"conv128_down/conv2/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":9.031058637304466e-10,"min":-1.1650065642122761e-7}},{"name":"conv128_down/conv2/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.027663578706629135,"min":3.1111555099487305}},{"name":"conv128_down/conv2/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008878476946961646,"min":-1.029903325847551}},{"name":"conv128_1/conv1/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00022380667574265425,"min":-0.032899581334170175}},{"name":"conv128_1/conv1/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.4147297756478345e-10,"min":-5.253528433020923e-8}},{"name":"conv128_1/conv1/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.013599334978589825,"min":3.634530782699585}},{"name":"conv128_1/conv1/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014059314073300829,"min":-1.4059314073300828}},{"name":"conv128_1/conv2/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00021715293474057143,"min":-0.02909849325523657}},{"name":"conv128_1/conv2/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":9.887046963276768e-10,"min":-1.1370104007768284e-7}},{"name":"conv128_1/conv2/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.029993299409454943,"min":3.630716562271118}},{"name":"conv128_1/conv2/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00782704236460667,"min":-0.7200878975438136}},{"name":"conv128_2/conv1/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00017718105923895743,"min":-0.022324813464108636}},{"name":"conv128_2/conv1/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":3.567012027797675e-10,"min":-5.243507680862582e-8}},{"name":"conv128_2/conv1/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.007940645778880399,"min":4.927767753601074}},{"name":"conv128_2/conv1/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015933452867994122,"min":-1.5614783810634238}},{"name":"conv128_2/conv2/conv/filters","shape":[3,3,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0001451439717236687,"min":-0.01712698866339291}},{"name":"conv128_2/conv2/conv/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.0383988570966347e-9,"min":-1.2356946399449953e-7}},{"name":"conv128_2/conv2/scale/weights","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.02892604528688917,"min":4.750600814819336}},{"name":"conv128_2/conv2/scale/biases","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00797275748907351,"min":-0.7414664464838364}},{"name":"conv256_down/conv1/conv/filters","shape":[3,3,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0002698827827093648,"min":-0.03994265184098599}},{"name":"conv256_down/conv1/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":5.036909834755123e-10,"min":-6.396875490139006e-8}},{"name":"conv256_down/conv1/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014870181738161573,"min":4.269900798797607}},{"name":"conv256_down/conv1/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.022031106200872685,"min":-3.1063859743230484}},{"name":"conv256_down/conv2/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00046430734150549946,"min":-0.03946612402796745}},{"name":"conv256_down/conv2/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":6.693064577513153e-10,"min":-7.630093618364995e-8}},{"name":"conv256_down/conv2/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.03475512242784687,"min":3.608360528945923}},{"name":"conv256_down/conv2/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01290142021927179,"min":-1.1482263995151893}},{"name":"conv256_1/conv1/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00037147209924810076,"min":-0.04234781931428348}},{"name":"conv256_1/conv1/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":3.2105515457510146e-10,"min":-3.467395669411096e-8}},{"name":"conv256_1/conv1/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.043242172166412955,"min":5.28542947769165}},{"name":"conv256_1/conv1/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01643658619300992,"min":-1.3149268954407936}},{"name":"conv256_1/conv2/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0003289232651392619,"min":-0.041773254672686264}},{"name":"conv256_1/conv2/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":9.13591691187321e-10,"min":-1.2333487831028833e-7}},{"name":"conv256_1/conv2/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0573908618852204,"min":4.360693454742432}},{"name":"conv256_1/conv2/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0164216583850337,"min":-1.3958409627278647}},{"name":"conv256_2/conv1/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00010476927912118389,"min":-0.015610622589056398}},{"name":"conv256_2/conv1/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":2.418552539068639e-10,"min":-2.539480166022071e-8}},{"name":"conv256_2/conv1/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.06024209564807368,"min":6.598613739013672}},{"name":"conv256_2/conv1/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.01578534350675695,"min":-1.1049740454729864}},{"name":"conv256_2/conv2/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00005543030908002573,"min":-0.007427661416723448}},{"name":"conv256_2/conv2/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.0822061852320308e-9,"min":-1.515088659324843e-7}},{"name":"conv256_2/conv2/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.04302893993901272,"min":2.2855491638183594}},{"name":"conv256_2/conv2/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006792667566561232,"min":-0.8083274404207865}},{"name":"conv256_down_out/conv1/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.000568966465253456,"min":-0.05632768006009214}},{"name":"conv256_down_out/conv1/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":4.5347887884881677e-10,"min":-6.530095855422961e-8}},{"name":"conv256_down_out/conv1/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.017565592597512638,"min":4.594101905822754}},{"name":"conv256_down_out/conv1/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.04850864223405427,"min":-6.306123490427055}},{"name":"conv256_down_out/conv2/conv/filters","shape":[3,3,256,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0003739110687199761,"min":-0.06954745878191555}},{"name":"conv256_down_out/conv2/conv/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":1.2668428328152895e-9,"min":-2.2549802424112154e-7}},{"name":"conv256_down_out/conv2/scale/weights","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.04351314469879749,"min":4.31956672668457}},{"name":"conv256_down_out/conv2/scale/biases","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.021499746921015722,"min":-1.2039858275768804}},{"name":"fc","shape":[256,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.000357687911566566,"min":-0.04578405268052045}}],"paths":["z_face_recognition_model-shard1","z_face_recognition_model-shard2"]}]
// Arithmetic mean
let getMean = function (data) {
return data.reduce(function (a, b) {
return Number(a) + Number(b);
}) / data.length;
};
// Standard deviation
let getSD = function (data) {
let m = getMean(data);
return Math.sqrt(data.reduce(function (sq, n) {
return sq + Math.pow(n - m, 2);
}, 0) / (data.length - 1));
};
const LM_LEN = 68;
const LM_parts = ['chin', 'left_eyebrow', 'right_eyebrow',
'nose_bridge', 'nose_tip', 'left_eye', 'right_eye',
'top_lip', 'bottom_lip'];
const LM_names = [
'chin', 'chin', 'chin', 'chin', 'chin',
'chin', 'chin', 'chin', 'chin', 'chin',
'chin', 'chin', 'chin', 'chin', 'chin',
'chin', 'chin',
'left_eyebrow', 'left_eyebrow', 'left_eyebrow', 'left_eyebrow', 'left_eyebrow',
'right_eyebrow', 'right_eyebrow', 'right_eyebrow', 'right_eyebrow', 'right_eyebrow',
'nose_bridge', 'nose_bridge', 'nose_bridge', 'nose_bridge',
'nose_tip', 'nose_tip', 'nose_tip', 'nose_tip', 'nose_tip',
'left_eye', 'left_eye', 'left_eye', 'left_eye', 'left_eye', 'left_eye',
'right_eye', 'right_eye', 'right_eye', 'right_eye', 'right_eye', 'right_eye',
'lip', 'lip', 'lip', 'lip',
'lip', 'lip', 'lip', 'lip',
'lip', 'lip', 'lip', 'lip',
'lip', 'lip', 'lip', 'lip',
'lip', 'lip', 'lip', 'lip'
]
// https://github.com/ageitgey/face_recognition/blob/d34c622bf42e2c619505a4884017051ecf61ac77/face_recognition/api.py#L190
const top_lip_indices = [48, 49, 50, 51, 52, 53, 54, 64, 63, 62, 61, 60];
const bottom_lip_indices = [54, 55, 56, 57, 58, 59, 48, 60, 67, 66, 65, 64];
function get_landmarks(faceDescriptions) {
let landmarks = []
for(let i=0; i<faceDescriptions.length; i++) {
let curLM = {
'chin': [],
'left_eyebrow': [],
'right_eyebrow': [],
'nose_bridge': [],
'nose_tip': [],
'left_eye': [],
'right_eye': [],
'top_lip': [],
'bottom_lip': []
};
let lm = faceDescriptions[i].landmarks;
let lpts = lm.positions;
let x_points = [];
let y_points = [];
// print(lpts.length)
for(let j=0; j<LM_LEN; j++) {
x_points.push(lpts[j].x)
y_points.push(lpts[j].y)
}
let mean_x = getMean(x_points);
let mean_y = getMean(y_points);
for(let j=0; j<LM_LEN; j++) {
x_points[j] = x_points[j] - mean_x;
y_points[j] = y_points[j] - mean_y;
}
let sdev_x = getSD(x_points);
let sdev_y = getSD(y_points);
let sdev = sdev_x > sdev_y ? sdev_x : sdev_y;
// let p1 = lpts[27]
// let p2 = lpts[28]
// EYES VERSION
// let p1 = lpts[36];
// let p2 = lpts[42];
// EARS VERSION
let p1 = lpts[2];
let p2 = lpts[14];
let xd = p1.x - p2.x;
let yd = p1.y - p2.y;
let angle = Math.atan2(-yd, -xd);
let s_a = Math.sin(-angle);
let c_a = Math.cos(-angle);
let raw_points = []
for(let j=0; j<LM_LEN; j++) {
let pt = [0, 0]
pt[0] = lpts[j].x - mean_x;
pt[1] = lpts[j].y - mean_y;
pt[0] = pt[0] / sdev;
pt[1] = pt[1] / sdev;
let x_new = pt[0] * c_a - pt[1] * s_a;
let y_new = pt[0] * s_a + pt[1] * c_a;
pt[0] = x_new;
pt[1] = y_new;
raw_points.push(pt);
}
// put all raw points into landmarks objects
// first everything but the lips (which start at 48)
for(let j=0; j<48; j++) {
let key = LM_names[j];
curLM[key].push(raw_points[j]);
}
// now the lips, which have dupes
for(let j=0; j<top_lip_indices.length; j++) {
let cur_ix = top_lip_indices[j];
let cur_pt = raw_points[cur_ix];
let pt_copy = [cur_pt[0], cur_pt[1]];
curLM['top_lip'].push(pt_copy);
}
for(let j=0; j<bottom_lip_indices.length; j++) {
let cur_ix = bottom_lip_indices[j];
let cur_pt = raw_points[cur_ix];
let pt_copy = [cur_pt[0], cur_pt[1]];
curLM['bottom_lip'].push(pt_copy);
}
curLM['transform'] = {
'center': [mean_x, mean_y],
'scale': sdev,
'angle': angle
}
landmarks.push(curLM);
}
// print(JSON.stringify(landmarks));
return landmarks;
}
function get_latents(faceDescriptions) {
latents = [];
for(let i=0; i<faceDescriptions.length; i++) {
let lm = faceDescriptions[i].descriptor;
latents.push(lm);
// print(lm);
}
return latents;
}
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)();
}
/**
* k-d Tree JavaScript - V 1.01
*
* https://github.com/ubilabs/kd-tree-javascript
*
* @author Mircea Pricop <pricop@ubilabs.net>, 2012
* @author Martin Kleppe <kleppe@ubilabs.net>, 2012
* @author Ubilabs http://ubilabs.net, 2012
* @license MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports'], factory);
} else if (typeof exports === 'object') {
factory(exports);
} else {
factory((root.commonJsStrict = {}));
}
}(this, function (exports) {
function Node(obj, dimension, parent) {
this.obj = obj;
this.left = null;
this.right = null;
this.parent = parent;
this.dimension = dimension;
}
function kdTree(points, metric, dimensions) {
var self = this;
function buildTree(points, depth, parent) {
var dim = depth % dimensions.length,
median,
node;
if (points.length === 0) {
return null;
}
if (points.length === 1) {
return new Node(points[0], dim, parent);
}
points.sort(function (a, b) {
return a[dimensions[dim]] - b[dimensions[dim]];
});
median = Math.floor(points.length / 2);
node = new Node(points[median], dim, parent);
node.left = buildTree(points.slice(0, median), depth + 1, node);
node.right = buildTree(points.slice(median + 1), depth + 1, node);
return node;
}
// Reloads a serialied tree
function loadTree (data) {
// Just need to restore the `parent` parameter
self.root = data;
function restoreParent (root) {
if (root.left) {
root.left.parent = root;
restoreParent(root.left);
}
if (root.right) {
root.right.parent = root;
restoreParent(root.right);
}
}
restoreParent(self.root);
}
// If points is not an array, assume we're loading a pre-built tree
if (!Array.isArray(points)) loadTree(points, metric, dimensions);
else this.root = buildTree(points, 0, null);
// Convert to a JSON serializable structure; this just requires removing
// the `parent` property
this.toJSON = function (src) {
if (!src) src = this.root;
var dest = new Node(src.obj, src.dimension, null);
if (src.left) dest.left = self.toJSON(src.left);
if (src.right) dest.right = self.toJSON(src.right);
return dest;
};
this.insert = function (point) {
function innerSearch(node, parent) {
if (node === null) {
return parent;
}
var dimension = dimensions[node.dimension];
if (point[dimension] < node.obj[dimension]) {
return innerSearch(node.left, node);
} else {
return innerSearch(node.right, node);
}
}
var insertPosition = innerSearch(this.root, null),
newNode,
dimension;
if (insertPosition === null) {
this.root = new Node(point, 0, null);
return;
}
newNode = new Node(point, (insertPosition.dimension + 1) % dimensions.length, insertPosition);
dimension = dimensions[insertPosition.dimension];
if (point[dimension] < insertPosition.obj[dimension]) {
insertPosition.left = newNode;
} else {
insertPosition.right = newNode;
}
};
this.remove = function (point) {
var node;
function nodeSearch(node) {
if (node === null) {
return null;
}
if (node.obj === point) {
return node;
}
var dimension = dimensions[node.dimension];
if (point[dimension] < node.obj[dimension]) {
return nodeSearch(node.left, node);
} else {
return nodeSearch(node.right, node);
}
}
function removeNode(node) {
var nextNode,
nextObj,
pDimension;
function findMin(node, dim) {
var dimension,
own,
left,
right,
min;
if (node === null) {
return null;
}
dimension = dimensions[dim];
if (node.dimension === dim) {
if (node.left !== null) {
return findMin(node.left, dim);
}
return node;
}
own = node.obj[dimension];
left = findMin(node.left, dim);
right = findMin(node.right, dim);
min = node;
if (left !== null && left.obj[dimension] < own) {
min = left;
}
if (right !== null && right.obj[dimension] < min.obj[dimension]) {
min = right;
}
return min;
}
if (node.left === null && node.right === null) {
if (node.parent === null) {
self.root = null;
return;
}
pDimension = dimensions[node.parent.dimension];
if (node.obj[pDimension] < node.parent.obj[pDimension]) {
node.parent.left = null;
} else {
node.parent.right = null;
}
return;
}
// If the right subtree is not empty, swap with the minimum element on the
// node's dimension. If it is empty, we swap the left and right subtrees and
// do the same.
if (node.right !== null) {
nextNode = findMin(node.right, node.dimension);
nextObj = nextNode.obj;
removeNode(nextNode);
node.obj = nextObj;
} else {
nextNode = findMin(node.left, node.dimension);
nextObj = nextNode.obj;
removeNode(nextNode);
node.right = node.left;
node.left = null;
node.obj = nextObj;
}
}
node = nodeSearch(self.root);
if (node === null) { return; }
removeNode(node);
};
this.nearest = function (point, maxNodes, maxDistance) {
var i,
result,
bestNodes;
bestNodes = new BinaryHeap(
function (e) { return -e[1]; }
);
function nearestSearch(node) {
var bestChild,
dimension = dimensions[node.dimension],
ownDistance = metric(point, node.obj),
linearPoint = {},
linearDistance,
otherChild,
i;
function saveNode(node, distance) {
bestNodes.push([node, distance]);
if (bestNodes.size() > maxNodes) {
bestNodes.pop();
}
}
for (i = 0; i < dimensions.length; i += 1) {
if (i === node.dimension) {
linearPoint[dimensions[i]] = point[dimensions[i]];
} else {
linearPoint[dimensions[i]] = node.obj[dimensions[i]];
}
}
linearDistance = metric(linearPoint, node.obj);
if (node.right === null && node.left === null) {
if (bestNodes.size() < maxNodes || ownDistance < bestNodes.peek()[1]) {
saveNode(node, ownDistance);
}
return;
}
if (node.right === null) {
bestChild = node.left;
} else if (node.left === null) {
bestChild = node.right;
} else {
if (point[dimension] < node.obj[dimension]) {
bestChild = node.left;
} else {
bestChild = node.right;
}
}
nearestSearch(bestChild);
if (bestNodes.size() < maxNodes || ownDistance < bestNodes.peek()[1]) {
saveNode(node, ownDistance);
}
if (bestNodes.size() < maxNodes || Math.abs(linearDistance) < bestNodes.peek()[1]) {
if (bestChild === node.left) {
otherChild = node.right;
} else {
otherChild = node.left;
}
if (otherChild !== null) {
nearestSearch(otherChild);
}
}
}
if (maxDistance) {
for (i = 0; i < maxNodes; i += 1) {
bestNodes.push([null, maxDistance]);
}
}
if(self.root)
nearestSearch(self.root);
result = [];
for (i = 0; i < Math.min(maxNodes, bestNodes.content.length); i += 1) {
if (bestNodes.content[i][0]) {
result.push([bestNodes.content[i][0].obj, bestNodes.content[i][1]]);
}
}
return result;
};
this.balanceFactor = function () {
function height(node) {
if (node === null) {
return 0;
}
return Math.max(height(node.left), height(node.right)) + 1;
}
function count(node) {
if (node === null) {
return 0;
}
return count(node.left) + count(node.right) + 1;
}
return height(self.root) / (Math.log(count(self.root)) / Math.log(2));
};
}
// Binary heap implementation from:
// http://eloquentjavascript.net/appendix2.html
function BinaryHeap(scoreFunction){
this.content = [];
this.scoreFunction = scoreFunction;
}
BinaryHeap.prototype = {
push: function(element) {
// Add the new element to the end of the array.
this.content.push(element);
// Allow it to bubble up.
this.bubbleUp(this.content.length - 1);
},
pop: function() {
// Store the first element so we can return it later.
var result = this.content[0];
// Get the element at the end of the array.
var end = this.content.pop();
// If there are any elements left, put the end element at the
// start, and let it sink down.
if (this.content.length > 0) {
this.content[0] = end;
this.sinkDown(0);
}
return result;
},
peek: function() {
return this.content[0];
},
remove: function(node) {
var len = this.content.length;
// To remove a value, we must search through the array to find
// it.
for (var i = 0; i < len; i++) {
if (this.content[i] == node) {
// When it is found, the process seen in 'pop' is repeated
// to fill up the hole.
var end = this.content.pop();
if (i != len - 1) {
this.content[i] = end;
if (this.scoreFunction(end) < this.scoreFunction(node))
this.bubbleUp(i);
else
this.sinkDown(i);
}
return;
}
}
throw new Error("Node not found.");
},
size: function() {
return this.content.length;
},
bubbleUp: function(n) {
// Fetch the element that has to be moved.
var element = this.content[n];
// When at 0, an element can not go up any further.
while (n > 0) {
// Compute the parent element's index, and fetch it.
var parentN = Math.floor((n + 1) / 2) - 1,
parent = this.content[parentN];
// Swap the elements if the parent is greater.
if (this.scoreFunction(element) < this.scoreFunction(parent)) {
this.content[parentN] = element;
this.content[n] = parent;
// Update 'n' to continue at the new position.
n = parentN;
}
// Found a parent that is less, no need to move it further.
else {
break;
}
}
},
sinkDown: function(n) {
// Look up the target element and its score.
var length = this.content.length,
element = this.content[n],
elemScore = this.scoreFunction(element);
while(true) {
// Compute the indices of the child elements.
var child2N = (n + 1) * 2, child1N = child2N - 1;
// This is used to store the new position of the element,
// if any.
var swap = null;
// If the first child exists (is inside the array)...
if (child1N < length) {
// Look it up and compute its score.
var child1 = this.content[child1N],
child1Score = this.scoreFunction(child1);
// If the score is less than our element's, we need to swap.
if (child1Score < elemScore)
swap = child1N;
}
// Do the same checks for the other child.
if (child2N < length) {
var child2 = this.content[child2N],
child2Score = this.scoreFunction(child2);
if (child2Score < (swap == null ? elemScore : child1Score)){
swap = child2N;
}
}
// If the element needs to be moved, swap it, and continue.
if (swap != null) {
this.content[n] = this.content[swap];
this.content[swap] = element;
n = swap;
}
// Otherwise, we are done.
else {
break;
}
}
}
};
this.kdTree = kdTree;
exports.kdTree = kdTree;
exports.BinaryHeap = BinaryHeap;
}));
// 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);
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
var NUM_SLIDERS = 10;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function ZhangFace() {
//head color/////////////////////////////
const orange1 = color (252, 128, 18); //front face color
const oranget = color(158, 85, 11); //texture's color when orange1
const orange2 = color (176, 94, 12);//darker orange
const oranget2 = color(122, 66, 10); //texture's color when orange2
const orange3 = color (252, 84, 18);//darker that orange2
const oranget3 = color(126, 41, 7); //texture's color when orange3
const orange4 = color (44, 5, 49);//most dark orange 94, 49, 4 25, 31, 10
const oranget4 = color(18, 3, 16); //texture's color when orange3 13, 18, 1
const evilgreen = color(74, 140, 43);
const cutevil = color(128, 209, 116);
const cut = color (242, 151, 61); //color of nose, eyes, mouth
//vein color
const green = color(105, 125, 16);
const dry_vein = color (45, 47, 5);
const dryer_vein = color (49, 30, 0);
this.earSize = 5;
this.earDist = 5;
this.faceColor = 0;
this.vein = 5;
this.vein2 = 5;
this.mouthshape = -2;
this.mouth_value = -1;
this.veinx = 5
this.vein2x = 5
this.veingreen = 5;
this.pupil = 5;
this.pupily = 5;
this.leave_num = 0;
this.blush = 0;
angleMode(DEGREES);
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
// lip variables///////////////////////////
let top_lip0 = positions.top_lip[0];
let top_lip1 = positions.top_lip[3];
let top_lip2 = positions.top_lip[6];
let bottom_lip0 = positions.bottom_lip[0];
let bottom_lip1 = positions.bottom_lip[3];
let bottom_lip2 = positions.bottom_lip[6];
//Eyebrow variables///////////////////////////
let eyebrow0 = positions. left_eyebrow[0];
let eyebrow1 = positions. left_eyebrow[1];
let eyebrow2 = positions. left_eyebrow[2];
let eyebrow3 = positions. left_eyebrow[3];
let eyebrow4 = positions. left_eyebrow[4];
let eyebrow_right0 = positions. right_eyebrow[0];
let eyebrow_right1 = positions. right_eyebrow[1];
let eyebrow_right2 = positions. right_eyebrow[2];
let eyebrow_right3 = positions. right_eyebrow[3];
let eyebrow_right4 = positions. right_eyebrow[4];
//head//////////////////////
let face_pos = segment_average(positions.chin);
strokeWeight(0.05);
stroke(0);
if(this.faceColor == 0) {
fill(oranget);
}
else if (this.faceColor==1) {
fill(oranget2);
}
else if (this.faceColor==2) {
fill(oranget3);
}
else {
fill(oranget4);
}
push();
rectMode(CENTER);
rect(face_pos[0]-0.05, face_pos[0],4, 4,1 );
pop();
//main vein/////////////////////////////////////////change based on length of hair
let vein_length = map (this. veingreen, 0, 100, 0, -12);
if (this.leave_num >= 0 && this.leave_num<1 ) {
fill(dryer_vein);
}else if (this.leave_num >= 1 && this.leave_num<2) {
fill(dry_vein);
}else {
fill(green);
}
push();
translate(0, vein_length);
beginShape();
vertex(-0.25, -2.25);
vertex(0.1, -2);
quadraticVertex(0.4, -1.5, 0.2, -0.5);
vertex(-0.25, -0.5);
quadraticVertex(0.3, -0.55, -0.2, -2.25);
endShape();
pop();
let eyebrow_pos = segment_average(positions. right_eyebrow);
let eyebrow_pos_l = segment_average(positions. left_eyebrow);
// head///////////////////////////////////////////////////////
if(this.faceColor == 0) {
fill(orange1);
}
else if (this.faceColor==1) {
fill(orange2);
}
else if (this.faceColor==2) {
fill(orange3);
}
else {
fill(orange4);
}
push();
rectMode(CENTER);
rect(0, 0, 4, 4,1);
pop();
//pumpkin texture, long stripes//////////////////////////////////////////////////////
noFill();
if(this.faceColor == 0) {
stroke(oranget);
}
else if (this.faceColor==1) {
stroke(oranget2);
}
else if (this.faceColor==2) {
stroke(oranget3);
}
else {
stroke(oranget4);
}
strokeWeight(0.15);
let texture = segment_average(positions.nose_bridge);
let texture1 = positions.chin[10];
let texture2 = positions.chin[9];
let texture3 = positions.chin[7];
let texture4 = positions.chin[6];
let short_texture1 = positions.chin[5];
let short_texture2 = positions.chin[11];
//long stripes
arc (texture1[0], 0, 1.5, 3.8,270, 90);
arc (texture2[0], 0, 1, 3.8,270, 90);
arc (texture3[0], 0, 1, 3.8, 90, 270);
arc (texture4[0], 0, 1.5, 3.8, 90, 270);
stroke(0);
strokeWeight(0.05);
arc (texture1[0], 0, 1.5, 4,270, 90);
arc (texture2[0], 0, 1, 4,270, 90);
arc (texture3[0], 0, 1, 4, 90, 270);
arc (texture4[0], 0, 1.5, 4, 90, 270);
//pupil position//////////////////////////////////////////////////
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
let pupil_pos = map (this.pupil, -40,40, -2, 1.5);
let pupil_posy = map (this.pupily, -40,50, -1.5, 1.5);
//When draw purple color///////////////////////////////////////
if (this.faceColor == 3){
let left = positions. left_eye [0];
let left1 = positions. left_eye [1];
let left2 = positions. left_eye [2];
let left3 = positions. left_eye [3];
let left4 = positions. left_eye [4];
let left5 = positions. left_eye [5];
//purple face, draw green eyes//////////////////
push();
translate(-1*left_eye_pos[0],-1*left_eye_pos[1]);
fill(cutevil);
scale(2);
strokeWeight(0.03);
beginShape();
vertex(left[0], left[1]);
vertex(left1[0], left1[1]);
vertex(left2[0], left2[1]);
vertex(left3[0], left3[1]);
vertex(left4[0], left4[1]);
vertex(left5[0], left5[1]);
vertex(left[0], left[1]);
endShape();
pop();
push();
scale(1);
strokeWeight(0.05);
stroke(evilgreen);
fill(evilgreen);
beginShape();
vertex(left[0], left[1]);
vertex(left1[0], left1[1]);
vertex(left2[0], left2[1]);
vertex(left3[0], left3[1]);
vertex(left4[0], left4[1]);
vertex(left5[0], left5[1]);
vertex(left[0], left[1]);
endShape();
pop();
let right = positions. right_eye [0];
let right1 = positions. right_eye [1];
let right2 = positions. right_eye [2];
let right3 = positions. right_eye [3];
let right4 = positions. right_eye [4];
let right5 = positions. right_eye [5];
push();
fill(cutevil);
strokeWeight(0.03);
translate(-right_eye_pos[0],-right_eye_pos[1]);
scale(2);
beginShape();
vertex(right1[0]+0.1, right1[1]);
vertex(right2[0], right2[1]);
vertex(right3[0], right3[1]);
vertex(right4[0], right4[1]);
vertex(right5[0], right5[1]);
vertex(right[0]+0.1, right[1]);
endShape(CLOSE);
pop();
push();
stroke(evilgreen);
strokeWeight(0.01);
fill(evilgreen);
noStroke();
beginShape();
vertex(right1[0]+0.1, right1[1]);
vertex(right2[0], right2[1]);
vertex(right3[0], right3[1]);
vertex(right4[0], right4[1]);
vertex(right5[0], right5[1]);
vertex(right[0], right[1]);
endShape();
pop();
//evil smile/////////////////////////////////////////////////
stroke(0);
strokeWeight(0.05);
fill(cutevil);
beginShape();
vertex(top_lip0[0]-0.6,top_lip0[1]-0.8);
quadraticVertex(top_lip1[0],top_lip1[1]+0.5, top_lip2[0]+0.6,top_lip2[1]-0.8);
quadraticVertex(bottom_lip0[0]+0.6, bottom_lip0[1]+0.5,bottom_lip1[0],bottom_lip1[1]+0.5);
quadraticVertex(bottom_lip2[0]-0.6,bottom_lip2[1]+0.5, top_lip0[0]-0.6,top_lip0[1]-0.8);
endShape();
fill(evilgreen);
push();
beginShape();
vertex(top_lip0[0]-0.6,top_lip0[1]-0.8);
quadraticVertex(top_lip1[0]-0.1,top_lip1[1]+0.8, top_lip2[0]+0.55,top_lip2[1]-0.7);
quadraticVertex(bottom_lip0[0]+0.4, bottom_lip0[1]+0.4,bottom_lip1[0],bottom_lip1[1]+0.3 );
quadraticVertex(bottom_lip2[0]-0.4,bottom_lip2[1]+0.3, top_lip0[0]-0.6,top_lip0[1]-0.8);
endShape();
pop();
//nose////////////////////////////
fill(cutevil);
let nose1 = positions.nose_bridge[1];
let nose2 = positions.nose_tip[0];
let nose3 = positions.nose_tip[4];
beginShape();
vertex(nose1[0],nose1[1]);
vertex(nose2[0],nose2[1]);
vertex(nose3[0],nose3[1]);
vertex(nose1[0],nose1[1]);
endShape();
//nose, the dark part//////////////////////
fill(evilgreen);
push();
noStroke();
scale(0.8);
beginShape();
vertex(nose1[0],nose1[1]);
vertex(nose2[0],nose2[1]);
vertex(nose3[0],nose3[1]);
vertex(nose1[0],nose1[1]);
endShape();
pop();
push();
noFill();
beginShape();
vertex(nose1[0],nose1[1]);
vertex(nose2[0],nose2[1]);
vertex(nose3[0],nose3[1]);
vertex(nose1[0],nose1[1]);
endShape();
pop();
}
else {
//when orange face color, draw normal face expression///////////////
let left_eyepoint = positions.left_eye[5];
let eye_d = dist (eyebrow2[0], eyebrow2[1], left_eyepoint[0], left_eyepoint[1]);
if(eye_d<0.1){
eye_d=0;
}
left_eye = map(eye_d, 0, 0.6, 0, 10);
let eye_size = map(left_eye, 0, 10, 0.1,1);
fill(cut); // dark orange shadow
strokeWeight(0.05);
stroke(0);
ellipse(left_eye_pos[0], left_eye_pos[1], eye_size/2, eye_size);
ellipse(right_eye_pos[0], right_eye_pos[1], eye_size/2, eye_size);
//pupil
noStroke();
fill(0);
ellipse(left_eye_pos[0]+ pupil_pos, left_eye_pos[1]+pupil_posy, eye_size/3, eye_size/1.2);
ellipse(right_eye_pos[0] +pupil_pos, right_eye_pos[1]+pupil_posy, eye_size/3, eye_size/1.2);
if(this.faceColor == 0) {
fill(oranget);
}
else if (this.faceColor==1) {
fill(oranget2);
}
else if (this.faceColor==2) {
fill(oranget3);
}
else {
fill(oranget4);
}
stroke(0);
strokeWeight(0.05);
ellipse(left_eye_pos[0]- pupil_pos, left_eye_pos[1]-pupil_posy, eye_size/4, eye_size/2);
ellipse(right_eye_pos[0]- pupil_pos, right_eye_pos[1]-pupil_posy, eye_size/4, eye_size/2);
//smile mouth//////////////////////////////////////////////
stroke(0);
strokeWeight(0.05);
fill(cut);
beginShape();
vertex(top_lip0[0]-0.5,top_lip0[1]-0.5);
quadraticVertex(top_lip1[0],top_lip1[1]+0.5, top_lip2[0]+0.5,top_lip2[1]-0.5);
quadraticVertex(bottom_lip0[0], bottom_lip0[1]+0.5,bottom_lip1[0],bottom_lip1[1]);
quadraticVertex(bottom_lip2[0],bottom_lip2[1]+0.5, top_lip0[0]-0.5,top_lip0[1]-0.5);
endShape();
fill(0);
push();
beginShape();
vertex(top_lip0[0]-0.5,top_lip0[1]-0.5);
quadraticVertex(top_lip1[0],top_lip1[1]+0.7, top_lip2[0]+0.5,top_lip2[1]-0.5);
quadraticVertex(bottom_lip0[0], bottom_lip0[1]+0.4,bottom_lip1[0],bottom_lip1[1]-0.2 );
quadraticVertex(bottom_lip2[0],bottom_lip2[1]+0.4, top_lip0[0]-0.5,top_lip0[1]-0.5);
endShape();
pop();
//nose////////////////////////////
fill(cut);
let nose1 = positions.nose_bridge[1];
let nose2 = positions.nose_tip[0];
let nose3 = positions.nose_tip[4];
beginShape();
vertex(nose1[0],nose1[1]);
vertex(nose2[0],nose2[1]);
vertex(nose3[0],nose3[1]);
vertex(nose1[0],nose1[1]);
endShape();
//nose, the dark part/////////////////////
fill(0);
push();
noStroke();
scale(0.8);
beginShape();
vertex(nose1[0],nose1[1]);
vertex(nose2[0],nose2[1]);
vertex(nose3[0],nose3[1]);
vertex(nose1[0],nose1[1]);
endShape();
pop();
}
//eyebrow and small, curve vein////////////////////////////////////////////////////////////////
let veinlefty = map (this.vein, 0, 100, -1, 10);
let veinleftx = map (this.veinx, 0, 100, -1, 10);
let veinrighty = map (this.vein2, 0, 100, -1, 10);
let veinrightx = map (this.vein2x, 0, 100, -1, 10);
stroke(1);
strokeWeight(0.1);
strokeWeight(0.05);
push();
translate(-eyebrow_pos_l[0]+veinleftx,-eyebrow_pos_l[0]+veinlefty );
scale(2);
noFill();
beginShape();
curveVertex(eyebrow0[0],eyebrow0[1]);
curveVertex(eyebrow0[0],eyebrow0[1]);
curveVertex(eyebrow1[0],eyebrow1[1]);
curveVertex(eyebrow2[0],eyebrow2[1]);
curveVertex(eyebrow3[0],eyebrow3[1]);
curveVertex(eyebrow4[0],eyebrow4[1]);
curveVertex(eyebrow4[0],eyebrow4[1]);
endShape();
ellipse(eyebrow_pos_l[0], eyebrow_pos_l[1], 0.3, 0.15);
pop();
push();
translate(-eyebrow_pos[0]+veinrightx ,eyebrow_pos[0]+veinrighty );
scale(2);
noFill();
beginShape();
curveVertex(eyebrow_right0[0],eyebrow_right0[1]);
curveVertex(eyebrow_right1[0],eyebrow_right1[1]);
curveVertex(eyebrow_right2[0],eyebrow_right2[1]);
curveVertex(eyebrow_right3[0],eyebrow_right3[1]);
curveVertex(eyebrow_right4[0],eyebrow_right4[1]);
curveVertex(eyebrow_right4[0],eyebrow_right4[1]);
ellipse(eyebrow_pos[0], eyebrow_pos[1], 0.3, 0.15);
endShape();
strokeWeight(0.03);
pop();
//leave number represent the age/////////////////////////////////
if (this.leave_num >= 0 && this.leave_num<1 ) {
//draw one leaf represent old face//////////////////
if(this.faceColor == 0) {
stroke(oranget);
}
else if (this.faceColor==1) {
stroke(oranget2);
}
else if (this.faceColor==2) {
stroke(oranget3);
}
else {
stroke(oranget4);
}
//draw wrinkle/////////////////////////////////////
noFill();
push();
rotate(180);
arc(texture2[0]-0.5, 2*texture2[0],1.5,1, 50, 130);
arc(texture2[0]-0.5, 1.5*texture2[0],1.5,1, 50, 130);
arc(texture2[0]-0.5, texture2[0],1.5,1, 50, 130);
pop();
//draw one leaf////////////////////////////
fill(dryer_vein);
stroke(0);
push();
translate(2*eyebrow2[0], 2* eyebrow2[1]);
beginShape();
vertex(0.2,0.2);
quadraticVertex(0.2, 0.8, 0.8, 0.8);
quadraticVertex(0.8, 0.2, 0.2, 0.2);
endShape();
pop();
}else if (this.leave_num >= 1 && this.leave_num<2) {
//draw two leave, represent mature face////////////////////////////
fill(dry_vein);
push();
translate(2*eyebrow2[0], 2* eyebrow2[1]);
beginShape();
vertex(0.2,0.2);
quadraticVertex(0.2, 0.8, 0.8, 0.8);
quadraticVertex(0.8, 0.2, 0.2, 0.2);
endShape();
pop();
push();
translate(2*eyebrow_right2[0], 2* eyebrow_right2[1]);
rotate(90);
beginShape();
vertex(0.8,0.8);
quadraticVertex(0.8, 0, 0, 0);
quadraticVertex(0, 0.8, 0.8, 0.8);
endShape();
pop();
}else {
//three leave, yound faces/////////////////////////////////////
fill(green);
push();
translate(2*eyebrow2[0], 2* eyebrow2[1]);
beginShape();
vertex(0.2,0.2);
quadraticVertex(0.2, 0.8, 0.8, 0.8);
quadraticVertex(0.8, 0.2, 0.2, 0.2);
endShape();
pop();
push();
translate(2*eyebrow_right2[0], 2* eyebrow_right2[1]);
rotate(90);
beginShape();
vertex(0.8,0.8);
quadraticVertex(0.8, 0, 0, 0);
quadraticVertex(0, 0.8, 0.8, 0.8);
endShape();
pop();
push();
translate(texture[0], -2);
rotate(120);
beginShape();
vertex(0.6,0.6);
quadraticVertex(0.6, 0, 0, 0);
quadraticVertex(0, 0.6, 0.6, 0.6);
endShape();
beginShape();
noFill();
strokeWeight(0.1);
vertex(0, 0);
bezierVertex(0, -1, 1, 0, 1, -1);
endShape();
pop();
}
//When people with big smile will have a blush
if (this.blush >= 0 && this.blush <1.5){
const blush = color(222, 157, 237);
fill(blush);
ellipse(top_lip2[0]+0.8, top_lip2[1]-0.8, 0.5,0.3);
ellipse(top_lip1[0]-1.4, top_lip2[1]-0.8, 0.5,0.3);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.faceColor = int(map(settings[4], 0, 100, 0, 3));
this.vein = map(settings[3], 0, 100, 0, 10);
this.veinx = map(settings[5], 0, 100, 0, 10);
this.vein2 = map(settings[1], 0, 100, 0, 10);
this.vein2x = map(settings[2], 0, 100, 0, 10);
this.veingreen = map(settings[0], 0, 100, 0, 10);
this.pupil = map(settings[6], 0, 100, 0, 10);
this.pupily = map(settings[7], 0, 100, 0, 10);
this.leave_num = int(map(settings[8], 0, 100, 0, 3));
this.blush = int(map(settings[9], 0, 100, 0, 2));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(10);
settings[0] = map(this.veingreen,0, 10, 0, 100);
settings[1] = map(this.vein2,0, 10, 0, 100);
settings[2] = map(this.vein2x,0, 10, 0, 100);
settings[3] = map(this.vein,0, 10, 0, 100);
settings[4] = map(this.faceColor, 0,3, 0, 100);
settings[5] = map(this.veinx,0, 10, 0, 100);
settings[6] = map(this.pupil,0, 10, 0, 100);
settings[7] = map(this.pupily,0, 10, 0, 100);
settings[8] = map(this.leave_num,0, 3, 0, 100);
settings[9] = map(this.blush,0, 2, 0, 100);
return settings;
}
}
{
"000001": [
41,
80,
72,
76,
0,
77,
49,
56,
33,
75
],
"000002": [
100,
100,
93,
71,
0,
100,
56.00000000000001,
53,
33.33333333333333,
0
],
"000005": [
86.99999999999999,
92.00000000000001,
78,
82,
0,
82,
56.00000000000001,
49.00000000000001,
33.33333333333333,
100
],
"000006": [
100,
100,
70,
89,
66.66666666666666,
89,
42.00000000000001,
64,
33.33333333333333,
100
],
"000007": [
35,
69,
79,
56.00000000000001,
0,
82,
56.00000000000001,
50,
33.33333333333333,
100
],
"000009": [
100,
92.00000000000001,
73,
86.99999999999999,
0,
74,
53,
52,
66.66666666666666,
0
],
"000010": [
100,
88.00000000000001,
74,
75,
0,
86,
53,
53,
66.66666666666666,
100
],
"000013": [
24,
82.99999999999999,
76,
72,
0,
81.00000000000001,
57.99999999999999,
57.99999999999999,
33.33333333333333,
100
],
"000014": [
100,
93,
71,
84.00000000000001,
100,
79,
48,
62,
66.66666666666666,
100
],
"000015": [
28.999999999999996,
84.00000000000001,
74,
84.00000000000001,
0,
70,
52,
53,
33.33333333333333,
100
],
"000016": [
23.000000000000004,
86.99999999999999,
72,
74,
0,
79,
56.00000000000001,
52,
33.33333333333333,
100
],
"000018": [
100,
100,
76,
86,
0,
90.99999999999999,
56.99999999999999,
56.99999999999999,
0,
100
],
"000037": [
16,
89,
82,
85,
100,
86,
56.00000000000001,
53,
33.33333333333333,
100
],
"000044": [
90,
93,
82,
81.00000000000001,
100,
90,
62,
52,
100,
100
],
"000045": [
100,
73,
79,
55.00000000000001,
0,
89,
61,
50,
100,
0
],
"000047": [
100,
90,
84.00000000000001,
75,
100,
89,
61,
50,
33.33333333333333,
100
],
"000065": [
26,
76,
72,
63,
0,
89,
54,
50,
100,
100
],
"000068": [
43,
88.00000000000001,
76,
90,
0,
72,
43,
50,
0,
100
],
"000071": [
79,
63,
86,
50,
0,
90,
71,
38,
100,
100
],
"000073": [
100,
100,
100,
81.00000000000001,
0,
100,
76,
41,
100,
100
],
"000020": [
61,
93,
84.00000000000001,
88.00000000000001,
0,
90,
52,
49.00000000000001,
0,
100
],
"000023": [
28.000000000000004,
84.00000000000001,
78,
75,
0,
70,
48,
50,
66.66666666666666,
100
],
"000025": [
26,
72,
81.00000000000001,
56.00000000000001,
0,
84.00000000000001,
63,
45,
33.33333333333333,
100
],
"000028": [
100,
88.00000000000001,
71,
74,
0,
74,
46.99999999999999,
54,
100,
0
],
"000029": [
100,
76,
74,
65,
0,
82,
56.00000000000001,
49.00000000000001,
66.66666666666666,
100
],
"000030": [
28.000000000000004,
80,
63,
69,
0,
56.00000000000001,
52,
51,
0,
100
],
"000031": [
100,
90,
73,
84.00000000000001,
0,
77,
52,
54,
33.33333333333333,
50
],
"000032": [
31,
84.00000000000001,
77,
76,
0,
75,
54,
56.00000000000001,
0,
100
],
"000035": [
95,
81.00000000000001,
77,
56.99999999999999,
0,
86.99999999999999,
57.99999999999999,
53,
33.33333333333333,
100
],
"000038": [
41,
90,
82.99999999999999,
78,
0,
86.99999999999999,
56.99999999999999,
50,
33.33333333333333,
0
],
"000040": [
89,
70,
70,
52,
0,
77,
62,
66,
100,
100
],
"000041": [
36,
100,
100,
63,
0,
100,
60,
46.99999999999999,
0,
50
],
"000042": [
93.99999999999999,
78,
71,
67,
0,
80,
52,
51,
66.66666666666666,
100
],
"000043": [
84.00000000000001,
78,
72,
71,
0,
84.00000000000001,
53,
57.99999999999999,
100,
50
],
"000048": [
28.000000000000004,
100,
74,
100,
0,
88.00000000000001,
56.99999999999999,
50,
100,
100
],
"000050": [
28.000000000000004,
81.00000000000001,
63,
80,
0,
72,
56.99999999999999,
50,
33.33333333333333,
50
],
"000051": [
0,
98.00000000000001,
66,
84.00000000000001,
0,
81.00000000000001,
56.99999999999999,
50,
0,
100
],
"000052": [
43,
98.00000000000001,
92.00000000000001,
85,
0,
92.00000000000001,
56.99999999999999,
50,
0,
100
],
"000054": [
100,
92.00000000000001,
82,
72,
0,
93,
56.99999999999999,
50,
100,
0
],
"000055": [
44.00000000000001,
82,
79,
81.00000000000001,
0,
86.99999999999999,
56.99999999999999,
50,
33.33333333333333,
100
],
"000056": [
67,
99,
66,
95,
0,
70,
42.00000000000001,
43,
100,
100
],
"000058": [
100,
90,
74,
81.00000000000001,
0,
85,
56.99999999999999,
50,
100,
100
],
"000060": [
0,
100,
93,
100,
100,
99,
56.99999999999999,
50,
100,
0
],
"000064": [
28.000000000000004,
93,
76,
86.99999999999999,
0,
81.00000000000001,
56.99999999999999,
50,
100,
100
],
"000069": [
43,
88.00000000000001,
77,
86.99999999999999,
0,
82,
56.00000000000001,
71,
33.33333333333333,
100
],
"000076": [
63,
100,
81.00000000000001,
95,
0,
90,
56.00000000000001,
78,
100,
100
],
"000077": [
100,
90,
89,
55.00000000000001,
0,
98.00000000000001,
73,
48,
100,
100
],
"000078": [
100,
100,
65,
100,
0,
81.00000000000001,
51,
82.99999999999999,
100,
100
],
"000079": [
0,
89,
80,
79,
0,
92.00000000000001,
77,
46.00000000000001,
33.33333333333333,
100
],
"000080": [
39,
70,
71,
53,
0,
78,
45,
46.99999999999999,
33.33333333333333,
100
],
"000117": [
100,
100,
82,
86.99999999999999,
100,
100,
59,
39,
66.66666666666666,
50
],
"000118": [
79,
82,
72,
67,
0,
88.00000000000001,
55.00000000000001,
54,
100,
100
],
"000081": [
39,
82,
64,
84.00000000000001,
0,
62,
41,
59,
33.33333333333333,
0
],
"000083": [
100,
82,
82,
73,
0,
82.99999999999999,
67,
48,
33.33333333333333,
100
],
"000085": [
100,
82,
82,
73,
0,
82.99999999999999,
67,
48,
66.66666666666666,
100
],
"000086": [
100,
96,
64,
100,
0,
67,
41,
57.99999999999999,
66.66666666666666,
100
],
"000088": [
100,
100,
95,
81.00000000000001,
0,
100,
68,
57.99999999999999,
33.33333333333333,
100
],
"000091": [
22.000000000000004,
50,
84.00000000000001,
28.999999999999996,
0,
82.99999999999999,
56.00000000000001,
57.99999999999999,
66.66666666666666,
100
],
"000092": [
100,
81.00000000000001,
62,
86.99999999999999,
0,
68,
49.00000000000001,
57.99999999999999,
66.66666666666666,
100
],
"000096": [
100,
95,
70,
88.00000000000001,
0,
84.00000000000001,
49.00000000000001,
54,
33.33333333333333,
100
],
"000097": [
100,
86.99999999999999,
77,
65,
0,
88.00000000000001,
55.00000000000001,
54,
66.66666666666666,
100
],
"000099": [
100,
82,
72,
67,
0,
88.00000000000001,
55.00000000000001,
54,
66.66666666666666,
0
],
"000100": [
61,
85,
62,
88.00000000000001,
0,
69,
46.00000000000001,
54,
66.66666666666666,
100
],
"000103": [
100,
93,
68,
88.00000000000001,
0,
79,
46.00000000000001,
54,
66.66666666666666,
100
],
"000104": [
37,
80,
76,
72,
0,
85,
46.00000000000001,
54,
66.66666666666666,
0
],
"000106": [
100,
80,
76,
72,
0,
85,
46.00000000000001,
54,
33.33333333333333,
0
],
"000108": [
100,
80,
76,
72,
0,
85,
46.00000000000001,
54,
66.66666666666666,
0
],
"000109": [
40,
80,
76,
72,
0,
85,
46.00000000000001,
54,
0,
100
],
"000110": [
70,
57.99999999999999,
73,
39,
0,
72,
57.99999999999999,
54,
100,
0
],
"000111": [
70,
89,
93.99999999999999,
69,
100,
100,
65,
54,
33.33333333333333,
0
],
"000114": [
51,
85,
75,
82,
0,
82.99999999999999,
65,
54,
100,
100
],
"000115": [
0,
85,
75,
82,
0,
82.99999999999999,
65,
54,
33.33333333333333,
100
],
"000116": [
32,
95,
76,
79,
0,
82.99999999999999,
55.00000000000001,
54,
100,
0
],
"000121": [
100,
82,
72,
67,
0,
88.00000000000001,
55.00000000000001,
54,
66.66666666666666,
100
],
"000122": [
49.00000000000001,
92.00000000000001,
81.00000000000001,
76,
0,
90,
55.00000000000001,
54,
0,
0
],
"000125": [
0,
92.00000000000001,
81.00000000000001,
76,
0,
90,
55.00000000000001,
54,
0,
100
],
"000126": [
100,
90,
86,
64,
0,
95,
55.00000000000001,
54,
66.66666666666666,
0
],
"000129": [
32,
90,
86,
64,
0,
95,
55.00000000000001,
54,
33.33333333333333,
0
],
"000131": [
32,
90,
86,
64,
100,
95,
55.00000000000001,
54,
66.66666666666666,
0
],
"000132": [
100,
90,
86,
64,
100,
95,
55.00000000000001,
54,
66.66666666666666,
0
],
"000133": [
100,
75,
73,
64,
66.66666666666666,
95,
55.00000000000001,
54,
66.66666666666666,
0
],
"000134": [
10,
100,
100,
100,
100,
100,
55.00000000000001,
54,
33.33333333333333,
0
],
"000135": [
49.00000000000001,
85,
72,
76,
100,
72,
55.00000000000001,
54,
66.66666666666666,
100
],
"000137": [
18,
77,
70,
100,
0,
25,
55.00000000000001,
54,
33.33333333333333,
0
],
"000140": [
100,
90.99999999999999,
76,
84.00000000000001,
66.66666666666666,
77,
55.00000000000001,
54,
100,
100
],
"000142": [
100,
90.99999999999999,
76,
84.00000000000001,
0,
77,
55.00000000000001,
54,
100,
100
],
"000143": [
100,
99,
86,
88.00000000000001,
0,
90.99999999999999,
55.00000000000001,
54,
33.33333333333333,
100
],
"000145": [
100,
99,
86,
88.00000000000001,
33.33333333333333,
90.99999999999999,
55.00000000000001,
54,
100,
0
],
"000146": [
100,
99,
61,
100,
66.66666666666666,
30,
55.00000000000001,
54,
100,
0
],
"000147": [
100,
80,
71,
60,
66.66666666666666,
80,
51,
54,
100,
100
],
"000148": [
100,
100,
74,
100,
0,
53,
51,
54,
33.33333333333333,
100
],
"000150": [
55.00000000000001,
68,
71,
45,
0,
70,
56.99999999999999,
54,
66.66666666666666,
100
],
"000151": [
100,
86,
77,
70,
0,
79,
59,
54,
66.66666666666666,
0
],
"000152": [
41,
95,
81.00000000000001,
81.00000000000001,
0,
79,
59,
54,
33.33333333333333,
0
],
"000153": [
41,
82,
81.00000000000001,
68,
0,
86,
56.99999999999999,
52,
33.33333333333333,
0
],
"000155": [
100,
76,
84.00000000000001,
56.99999999999999,
0,
96,
56.00000000000001,
52,
100,
0
],
"000156": [
55.00000000000001,
96,
90,
74,
0,
100,
63,
52,
100,
0
],
"000157": [
100,
77,
75,
62,
0,
86,
63,
52,
100,
100
],
"000160": [
33,
55.00000000000001,
86,
37,
0,
80,
62,
60,
33.33333333333333,
100
],
"000161": [
100,
100,
77,
86.99999999999999,
0,
93,
62,
60,
100,
50
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 4;
// other variables can be in here too
// here's some examples for colors used
// angleMode(DEGREES);
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
/*
* s1:tilt_value is in degrees from -30 to 25 and controls how the lips rotate
* s2:lipsHeight ranges from 0.3 to -1 and controls the distance between nose and mouth
* s3:lipsSize ranges from 0.7 to 1.5 and controls the scale of the mouth
* s4:browpeakX ranges from -7 to -4 and controls the x position of the browpeak
* s5:browpeakY ranges from -3 to -5 and controls the y position of the browpeak
* s6:eyelashLength ranges from 1 to 3.5 and controls the length of the eyelash and eyeshadows
* s7:nevusX ranges from 3 to 5 and controls the x position of the nevus
* s8:nevusY ranges from 1 to 6 and controls the y position of the nevus
* s9: blurLength decides how long the eyeshadow flows down the face
*/
function ZhaoFace() {
const green = [210,221,185];//green
const blue = [179, 198, 193];
const fg_color3 = [151, 102, 52];
const red = [196, 29, 54];
const pink = [240, 55, 144];
const purple = [222, 199, 255];
const faceColor = [217, 160, 143];
const black = [0,0,0];
const darkblue = [49, 50, 56];
// these are state variables for a face
this.eyelashLength = 0.56;
this.eyeShape = 1;
this.tearValue = 1;
this.lipColor = 0.5;
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for(let i=0; i<segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if(i < segment.length - 1) {
let nx = segment[i+1][0];
let ny = segment[i+1][1];
line(px, py, nx, ny);
}
else if(do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
}
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
// scale(2.5/10) //a quarter of the original size
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
//head----------------------------------------------------
noStroke();
push();
translate(-2/4,0.5/4);
rotate(-27);
fill(blue);//blue
ellipse(0,0, 30/2.2/4,5);
pop();
fill(faceColor);
push();
translate(2.3/4,0);
rotate(15);
ellipse(0,0, 30/2.2/4, 5);
pop();
//nose----------------------------------------------------
let nose_top = positions.nose_bridge[0];
let nose_bottom = positions.nose_bridge[3];
let nose32 = positions.nose_tip[1];
let nose34 = positions.nose_tip[3];
let nose_apex = positions.nose_tip[2];
let nd = nose_apex[1]-nose_bottom[1];
// print(dist(nose_bottom[0],nose_bottom[1],nose_apex[0],nose_apex[1]));
let nose_end = null;
let nose_hole = null;
let eyebrow_start = null;
let eyebrow_end = null;
let eyebrow_peak = null;
let dx = null;
let dy = null;
let rightY = null;
let leftY = null;
noFill();
beginShape();
//turn right
if(nose_top[0]<nose_bottom[0]&&abs(nose_top[0]-nose_bottom[0])>=0.05){
if(nd >=0.33){
nose_end = positions.nose_tip[2];
nose_apex = positions.nose_tip[2]
}
else{
nose_end = positions.nose_tip[0];
}
eyebrow_start = positions.right_eyebrow[0];
eyebrow_peak = positions.right_eyebrow[2];
eyebrow_end = positions.right_eyebrow[4];
// nose_hole = positions;
dx = 0.55;
rightY = right_eye_pos[1]+0.2;
leftY = left_eye_pos[0]+0.7;
}
else if(abs(nose_top[0]-nose_bottom[0])<0.05){
nose_end = positions.nose_tip[2];
eyebrow_start = positions.right_eyebrow[0];
eyebrow_peak = positions.right_eyebrow[2];
eyebrow_end = positions.right_eyebrow[4];
rightY = right_eye_pos[1]+0.4;
leftY = left_eye_pos[0]+0.4;
dx = 0.55;
}
//turn left
else{
if(nd > 0.33){
nose_end = positions.nose_tip[3];
nose_apex = positions.nose_tip[3];
}
else{
nose_end = positions.nose_tip[4];
}
eyebrow_start = positions.left_eyebrow[4];
eyebrow_peak = positions.left_eyebrow[2];
eyebrow_end = positions.left_eyebrow[1];
dx = -0.55;
rightY = right_eye_pos[1]+0.7;
leftY = left_eye_pos[0]+0.2;
}
//right eyes ----------------------------------------------------
var rightX = right_eye_pos[0]+0.2;
if(this.eyeShape == 1){//quad
var Dx = 2.5/4;
var Dy = 0.3;
var e1={x:rightX-Dx,y:rightY},e2={x:rightX,y:rightY-Dy},
e3={x:rightX+Dx,y:rightY},e4={x:rightX,y:rightY+Dy};
// eyelash-----------------------------------
stroke(0);
strokeWeight(0.075);
push();
translate(rightX,rightY);
for(i=0;i<=7;i++){
if (i == 3||i == 4) {
stroke(faceColor);
}
else {
stroke(0);
}
rotate(45*i);
strokeCap(SQUARE);
strokeWeight(0.075);
line(0,0,0,-this.eyelashLength);
}
push();
noStroke();
fill(faceColor);
scale(this.eyelashLength*2);//0.25~0.875
ellipse(0,0,0.7,0.6);
pop();
pop();
fill(255,245,245);
stroke(0);
quad(e1.x,e1.y,e2.x,e2.y,e3.x,e3.y,e4.x,e4.y);
fill(217, 184, 198);
ellipse(rightX,rightY,0.5/4,0.5);
}
else if(this.eyeShape ==0){//cross
noFill();
stroke(0);
push();
var leftX = left_eye_pos[0]-0.3;//-0.4
translate(rightX,rightY);
rotate(45);
for(i=0;i<=4;i++){
rotate(90*i);
strokeWeight(0.075);
strokeCap(SQUARE);
line(0,0,0,-1.7/4);
}
pop();
}
else{//ellipse
// eyelash-----------------------------------
stroke(0);
strokeWeight(0.075);
push();
translate(rightX,rightY);
for(i=0;i<=7;i++){
if (i == 3||i == 4) {
stroke(faceColor);
}
else {
stroke(0);
}
rotate(45*i);
strokeCap(SQUARE);
strokeWeight(0.075);
line(0,0,0,-this.eyelashLength);
}
noStroke();
push();
fill(faceColor);
scale(this.eyelashLength*2);//0.25~0.875
ellipse(0,0,1,0.5);
pop();
pop();
fill(255,245,245);
stroke(0);
ellipse(rightX,rightY,1,0.5);//right
//pupils----------------------------------------------------
fill(217, 184, 198);
ellipse(rightX,rightY, 0.5/4, 0.5);
}
//left cross eye----------------------------------------------------
noFill();
stroke(0);
push();
var leftX = left_eye_pos[0]-0.3;//-0.4
translate(leftX,leftY);
rotate(45);
for(i=0;i<=4;i++){
rotate(90*i);
strokeWeight(0.3/4);
strokeCap(SQUARE);
line(0,0,0,-1.7/4);
}
pop();
strokeWeight(0.075);
curveVertex(eyebrow_end[0]+dx,eyebrow_end[1]);//eyebrow ends
curveVertex(eyebrow_end[0]+dx,eyebrow_end[1]);
curveVertex(eyebrow_peak[0]+dx/2,eyebrow_peak[1]);//browpeak
curveVertex(eyebrow_start[0]+dx/3,eyebrow_start[1]);//browstart
curveVertex(nose_top[0],nose_top[1]);//connect brow and nose
curveVertex(nose_bottom[0], nose_bottom[1]);
curveVertex(nose_apex[0],nose_apex[1]);//nose apex
curveVertex(nose_end[0],nose_end[1]);//nose end
curveVertex(nose_end[0],nose_end[1]);//nose end
endShape();
// mouth----------------------------------------------------
let mouth_left = positions.top_lip[0];//48
let mouth_right = positions.top_lip[6];//54
let lipbow1 = positions.top_lip[2];//50
let lipbow2 = positions.top_lip[4];//52
let lip62 = positions.top_lip[9];//62
let lip66 = positions.bottom_lip[9];//66
let lip61 = positions.bottom_lip[10];
let lip65 = positions.bottom_lip[10];
let lip57 = positions.bottom_lip[3];//57
let lip51 = positions.top_lip[3];//51
let lip56 = positions.bottom_lip[2];
let lip58 = positions.bottom_lip[4];
let mouthHei = lip57[1]-lipbow1[1];//57-50
let mouthWid = mouth_right[0]-mouth_left[0];
let mouthY = mouthHei/2+lip51[1];//57-50
let mouthX = mouthWid/2+mouth_left[0];
let openWid = mouthWid*0.85;
let openHei = lip66[1]-lip62[1];
let openY = lip62[1]+openHei/2;
let openX = lip61[0]+(lip65[0]-lip61[0])/2;
// // text---------------------------------------------------
// textSize(0.08);
// fill(0);
// noStroke();
// for(let i = 0;i<positions.bottom_lip.length;i++){
// let b = positions.bottom_lip[i];
// let t = positions.top_lip[i];
// text(i,t[0],t[1]);
// text(i,b[0],b[1]);
// }
//lips
noStroke();
if (this.lipColor == 0) {
fill(red);
}
else {
fill(black);
}
beginShape();
curveVertex(mouth_left[0],mouth_left[1]);
curveVertex(lipbow1[0],lipbow1[1]);
// curveVertex(lip51[0],lip51[1]);
curveVertex(lipbow2[0],lipbow2[1]);
curveVertex(mouth_right[0],mouth_right[1]);
curveVertex(lip56[0],lip56[1]);
// curveVertex(lip57[0],lip57[1]);
curveVertex(lip58[0],lip58[1]);
endShape(CLOSE);
//open
var ox = 0.2;
fill(faceColor);
beginShape();
curveVertex(mouth_left[0]+ox,mouth_left[1]);
curveVertex(lip62[0],lip62[1]);
curveVertex(mouth_right[0]-ox,mouth_right[1]);
curveVertex(lip66[0],lip66[1]);
endShape(CLOSE);
//tears----------------------------------------------------
strokeWeight(0.05);
let rEyeDis = 0.375;
let q1 = {x:leftX, y:leftY+rEyeDis};
let tW = 0.5/4;
let tH = 1/4;
let q2 = {x:q1.x-tW, y:q1.y+tH};
let q3 = {x:q1.x, y:q1.y+2*tH};
let q4 = {x:q1.x+tW, y:q1.y+tH};
var tearD = 2.5/4;//diatance between each tear
stroke(255);
fill(purple);
quad(q1.x,q1.y,q2.x,q2.y,q3.x,q3.y,q4.x,q4.y);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.lipColor = int(map(settings[0], 0, 100, 0, 1));
this.eyeShape = int(map(settings[1], 0, 100, 0, 2));
this.tearValue = int(map(settings[2], 0, 100, 0, 3));
this.eyelashLength = map(settings[3],0,100,0.25,0.875);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(2);
settings[0] = int(map(this.lipColor,0, 1, 0, 100));
settings[1] = int(map(this.eyeShape, 0, 2, 0, 100));
settings[2] = int(map(this.tearValue, 0, 3, 0, 100));
settings[3] = map(this.eyelashLength, 0.25,0.875, 0, 100);
return settings;
}
}
{
"000001": [
25,
87,
0,
28
],
"000002": [
0,
100,
0,
41
],
"000005": [
0,
100,
33,
72
],
"000006": [
0,
100,
33,
50
],
"000007": [
100,
50,
0,
71
],
"000009": [
0,
100,
0,
51
],
"000010": [
0,
100,
0,
68
],
"000013": [
100,
50,
0,
93.99999999999999
],
"000015": [
100,
50,
0,
40
],
"000016": [
100,
50,
0,
50
],
"000018": [
0,
100,
0,
39
],
"000020": [
100,
0,
0,
24.000000000000004
],
"000023": [
100,
50,
0,
64
],
"000025": [
100,
50,
0,
18
],
"000028": [
0,
100,
0,
41.99999999999999
],
"000029": [
0,
100,
0,
41.99999999999999
],
"000030": [
100,
50,
0,
44.00000000000001
],
"000031": [
0,
100,
33,
43.00000000000001
],
"000032": [
100,
50,
0,
22.000000000000004
],
"000035": [
0,
100,
0,
93
],
"000037": [
100,
50,
0,
32
],
"000038": [
100,
50,
0,
61.999999999999986
],
"000040": [
0,
100,
0,
85
],
"000041": [
100,
50,
0,
39
],
"000042": [
0,
100,
0,
39
],
"000043": [
0,
100,
0,
100
],
"000044": [
0,
100,
0,
72
],
"000045": [
0,
100,
0,
48.00000000000001
],
"000047": [
0,
100,
0,
72
],
"000048": [
100,
0,
0,
44.00000000000001
],
"000050": [
100,
50,
0,
58.00000000000001
],
"000051": [
100,
50,
0,
43.00000000000001
],
"000052": [
100,
50,
0,
18
],
"000054": [
0,
100,
0,
73.00000000000001
],
"000055": [
100,
50,
0,
55.00000000000001
],
"000056": [
100,
50,
0,
64
],
"000058": [
0,
100,
0,
78
],
"000060": [
100,
100,
0,
30.999999999999993
],
"000065": [
100,
50,
0,
48.00000000000001
],
"000068": [
100,
50,
0,
48.00000000000001
],
"000069": [
100,
50,
0,
97
],
"000071": [
0,
100,
0,
97
],
"000073": [
0,
100,
0,
68.99999999999999
],
"000076": [
100,
50,
0,
68.99999999999999
],
"000077": [
0,
100,
0,
100
],
"000078": [
0,
100,
0,
64
],
"000079": [
100,
50,
0,
51
],
"000080": [
100,
50,
0,
36
],
"000081": [
100,
50,
0,
28.000000000000007
],
"000083": [
0,
100,
0,
66.00000000000001
],
"000085": [
0,
100,
0,
81.00000000000001
],
"000086": [
0,
100,
0,
41.99999999999999
],
"000088": [
0,
100,
0,
27
],
"000091": [
100,
50,
0,
81.00000000000001
],
"000092": [
0,
50,
0,
54
],
"000096": [
0,
100,
0,
80
],
"000097": [
0,
100,
0,
80
],
"000099": [
0,
100,
0,
50
],
"000100": [
0,
100,
0,
50
],
"000103": [
0,
100,
0,
65
],
"000104": [
100,
100,
0,
33.00000000000001
],
"000106": [
0,
100,
0,
50
],
"000108": [
0,
100,
0,
34
],
"000109": [
100,
50,
0,
45
],
"000110": [
0,
100,
0,
56.000000000000014
],
"000111": [
0,
100,
0,
43.00000000000001
],
"000114": [
100,
50,
0,
58.00000000000001
],
"000115": [
100,
50,
0,
32
],
"000116": [
100,
50,
0,
15.999999999999998
],
"000117": [
0,
100,
0,
56.000000000000014
],
"000118": [
0,
100,
0,
56.000000000000014
],
"000121": [
0,
100,
0,
100
],
"000122": [
0,
100,
0,
67
],
"000125": [
100,
50,
0,
34
],
"000126": [
0,
100,
0,
76
],
"000129": [
100,
50,
0,
92.00000000000001
],
"000131": [
0,
100,
0,
39
],
"000132": [
0,
100,
0,
39
],
"000133": [
0,
100,
0,
72
],
"000134": [
100,
50,
0,
30
],
"000135": [
100,
50,
0,
72
],
"000137": [
100,
50,
0,
44.00000000000001
],
"000140": [
0,
100,
0,
46.99999999999999
],
"000142": [
0,
100,
0,
58.00000000000001
],
"000143": [
100,
50,
0,
54
],
"000145": [
0,
100,
0,
29.000000000000004
],
"000146": [
0,
100,
0,
29.000000000000004
],
"000147": [
0,
100,
0,
46.000000000000014
],
"000148": [
0,
100,
0,
46.000000000000014
],
"000150": [
100,
50,
0,
56.000000000000014
],
"000151": [
0,
100,
0,
0
],
"000152": [
100,
50,
0,
0
],
"000153": [
100,
50,
0,
49.00000000000001
],
"000155": [
0,
100,
0,
100
],
"000156": [
0,
100,
0,
39
],
"000157": [
0,
100,
0,
79
],
"000160": [
100,
50,
0,
20
],
"000161": [
0,
100,
0,
56.99999999999999
],
"000014": [
0,
100,
0,
85
],
"000064": [
100,
100,
0,
41.99999999999999
]
}