Published
Edited
Feb 22, 2022
Importers
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
var svgContext = DOM.svg(contextWidth,contextHeight);

var convPolyCoords = [];
if (alg == 'valtr') {convPolyCoords = MakeValtrConvexPolygonCoords(numSides,polygonRadius);}
if (alg == 'circumcircle') {convPolyCoords = MakeCircumcircleConvexPolygonCoords(numSides,polygonRadius);}
if (alg == 'regular') {convPolyCoords = MakeRegularConvexPolygonCoords(numSides,polygonRadius);}
drawSVGPolygon(convPolyCoords,svgContext)

return svgContext
}
Insert cell
function MakeValtrConvexPolygonCoords(numSides,radius) {
var xs = Array.from({length: numSides}, () => 2.0 * radius * Math.random());
var ys = Array.from({length: numSides}, () => 2.0 * radius * Math.random());
xs.sort(function(a, b){return a - b});
ys.sort(function(a, b){return a - b});
console.log("xs: ",xs);
console.log("ys: ",ys);

let minXS = xs[0];
let maxXS = xs[xs.length-1];
let minYS = ys[0];
let maxYS = ys[ys.length-1];
console.log("minXS: ",minXS);
console.log("minYS: ",minYS);
console.log("maxXS: ",maxXS);
console.log("maxYS: ",maxYS);
var vecXS = makeVectorChain(xs,minXS,maxXS);
var vecYS = makeVectorChain(ys,minYS,maxYS);

console.log("vecXS: ",vecXS);
console.log("vecYS: ",vecYS);

shuffleArray(vecYS);
console.log("shuffled vecYS: ",vecYS);

function makeVectorChain(valuesArray, minVal, maxVal) {
let lastMin = minVal;
let lastMax = minVal;
var ary = []
for (let idx = 1; idx < valuesArray.length - 1; idx++) {
var val = valuesArray[idx];
if (Math.random() > 0.5) {
ary.push(val - lastMin);
lastMin = val;
} else {
ary.push(lastMax - val);
lastMax = val;
}
}
ary.push(maxVal - lastMin);
ary.push(lastMax - maxVal);
return ary;
}
// Zip the vec arrays together
var vecs = vecXS.map(function(e, i) {
return [e, vecYS[i]];
});
//console.log("vecs: ",vecs);

/* var vecAngs = [];
for (const vec of vecs) {
let a = Math.atan2(vec[1],vec[0]);
vecAngs.push(a);
}
console.log("vecAngs: ",vecAngs);
*/
// Sort the vectors by angle, in a counter clockwise fashion.
vecs.sort(function(a, b){
// a and b are tuples representing vectors. Compute angle for each vector and compare them.
let aAng = Math.atan2(a[1],a[0]);
let bAng = Math.atan2(b[1],b[0]);
//console.log("aAng: ",aAng, " bAng: ",bAng);
return (aAng - bAng);
});
console.log("sorted vecs: ",vecs);


var vecAngs2 = [];
for (const vec of vecs) {
let a = Math.atan2(vec[1],vec[0]);
vecAngs2.push(a);
}
console.log("vecAngs2: ",vecAngs2);

//Make polygon coordinates from the vecs by laying them out end to end
var polyCoords = [];
let x = 0;
let y = 0;
for (const vec of vecs) {
x += (vec[0] * 1);
y += (vec[1] * 1);
polyCoords.push([x,y])
}

// Move coordinates to put polygon's centroid at (0,0)
var centroid = getCentroid(polyCoords);
polyCoords = polyCoords.map(function(e){
let x = e[0] - centroid[0];
let y = e[1] - centroid[1];
return [x,y];
});
console.log("polyCoords: ", polyCoords);
return polyCoords;
}
Insert cell
//Makes a Convex Polygon where all vertices lie on a circle. Does not! produce all possible convex polygons.
function MakeCircumcircleConvexPolygonCoords(numSides,radius) {
//Angle in radians which must be exceeded between adjacent vertices
var tooCloseThresholdRad = tooCloseThresholdDegrees * Math.PI/180
var vertAngles = [];
for (let i=0; i < numSides; i++) {
let angle = Math.random() * Math.PI * 2; // Get angle between 0 and 2PI
//Check if angle is within threshold of and other angle in vertAngles list.
var tooClose = false;
for (const prevAng of vertAngles) {
let minAng = Math.min(angle,prevAng);
let maxAng = Math.max(angle,prevAng);
//console.log("prevAng: ", prevAng, " angle: ", angle);
//console.log("minAng: ", minAng, " maxAng: ", maxAng);
let diff = maxAng - minAng;
if (diff < tooCloseThresholdRad || 2*Math.PI - diff < tooCloseThresholdRad) {
tooClose = true;
break;
}
}

if (!tooClose) {
vertAngles.push(angle);
} else {
//console.log("tooClose: ", tooClose);
i--;
}
}
vertAngles.sort(function(a, b){return a - b});
//console.log("vertAngles: ", vertAngles);

//var polyCoords = [];
//for (const ang of vertAngles) {
// let x = radius * Math.cos(ang);
// let y = radius * Math.sin(ang);
// polyCoords.push([x,y]);
//}
//console.log("polyCoords: ", polyCoords);
//return polyCoords;
return CCWAnglesToPolygonCoords(vertAngles,radius);
}
Insert cell
function MakeRegularConvexPolygonCoords(numSides, radius) {
var vertAngles = [];
for (let i=0; i < numSides; i++) {
let angle = i * (2.0 * Math.PI / numSides);
vertAngles.push(angle);
}

return CCWAnglesToPolygonCoords(vertAngles,radius);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {slider, radio} from "@jashkenas/inputs"
Insert cell
require('d3@6')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more