xxxxxxxxxx
288
let p = [[25,50],[300,60],[210,360]];
let colors = [];
let polygons = [];
const markersize = 5;
function setup() {
createCanvas(400, 400);
background(255);
//draw points
for(let a=0;a<p.length;a++){
drawMarker(p[a][0],p[a][1],0);
colors.push(random(255));
}
for(let a=0;a<3;a++){
print('STARTING NEW POLYGON')
//draw lines for all other points
let c = [];
let s = [];
let my = []; // on which side of line is point
let mx = []; // where is the middle x of the line
let pdist = sqrt(width**2 + height**2);
let l1;
for(let b=0;b<p.length;b++){
if(b!=a){
c[b] = ((p[b][0]-p[a][0]) / (p[a][1]-p[b][1]));
s[b] = ((p[a][1]+p[b][1])/2 - c[b] * (p[a][0]+p[b][0]) / 2);
//AB = c*x + s
my[b] = (p[a][1] + p[b][1]) / 2; //1 if a is right of b, -1 if a is left
mx[b] = (p[a][0] + p[b][0]) / 2;
if(sqrt((p[a][0]-p[b][0])**2 + (p[a][1]-p[b][1])**2) < pdist){
pdist = sqrt((p[a][0]-p[b][0])**2 + (p[a][1]-p[b][1])**2);
l1 = b;
}
}
else{
c[b] = 'n/a';
s[b] = 'n/a';
my[b] = 'n/a';
mx[b] = 'n/a';
}
}
my.push((0+p[a][1])/2, (height+p[a][1])/2, p[a][1], p[a][1]);
mx.push(p[a][0], p[a][0], (0+p[a][0])/2, (width+p[a][0])/2);
//create array to store polygon points
let pol = [];
print('coefficients: ' + c + ' , shifts: ' + s + ' , middle x: ' + mx + ' , middle y: ' + my);
//draw lines
stroke(0);
for(let l=0;l<c.length;l++){
if(c[l] != 'n/a'){
line(0,c[l]*0+s[l],400,c[l]*400+s[l]);
}
}
noStroke();
// find intersections with current line
let insec = findLineIntersections(l1,c,s);
print(insec)
//draw and print intersections
drawIntersections(insec);
//find closest intersection
let curdist = sqrt(width**2 + height**2);
let curint;
for(let i=0; i<insec.length; i++){
if(sqrt((p[a][0]-insec[i][0])**2 + (p[a][1]-insec[i][1])**2) < curdist){
curdist = sqrt((p[a][0]-insec[i][0])**2 + (p[a][1]-insec[i][1])**2);
curint = i;
}
}
pol.push([insec[curint][0], insec[curint][1]]); // store it to our polygon array
print(pol);
print(curint);
//start looping through the points
findPolygonLoop(c, s, mx, my, pol, insec, l1, curint);
polygons.push(pol);
}
print(polygons);
}
function findLineIntersections(l1,c,s){
let xint = [], yint = [];
for(let l=0;l<c.length;l++){
if(l!=l1 && c[l] != 'n/a'){
xint[l] = ( (s[l] - s[l1]) / (c[l1] - c[l]) );
yint[l] = (c[l1] * xint[l] + s[l1]);
}
else{
xint[l] = 'n/a';
yint[l] = 'n/a'
}
}
//add intersections with borders in order T,B,L,R
xint.push( (0 - s[l1])/c[l1], (height - s[l1])/c[l1], 0, width );
yint.push(0, height, s[l1], c[l1] * width + s[l1]);
let intersections = [];
for(let i=0;i<xint.length;i++){
intersections.push([xint[i], yint[i]])
}
return intersections;
}
function findPolygonLoop(c, s, mx, my, pol, insec, l1, curint){
if(curint >= c.length){
//its one of the borders
insec = findBorderIntersections(curint - c.length, c, s);
}
else{
//its with another line
insec = findLineIntersections(curint, c, s);
}
//draw and print intersections
drawIntersections(insec);
//find closest intersection in the correct direction
let closestInt;
if(l1 == c.length || l1 == c.length + 1 || curint > c.length + 1){
closestInt = findVertInt(Math.sign(my[curint] - pol[pol.length-1][1]), pol, insec, c);
}
// else if(curint > c.length + 1){
// closestInt = findVertInt(Math.sign(c[l1])*m[l1], pol, insec, c);
// }
else{
closestInt = findHorInt(Math.sign(mx[curint] - pol[pol.length-1][0]), pol, insec);
}
if(pol[0][0] != closestInt[0][0] && pol[0][0] !=closestInt[0][1] ){
l1 = curint;
pol.push(closestInt[0]);
curint = closestInt[1];
findPolygonLoop(c, s, mx, my, pol, insec, l1, curint);
}
print(pol);
print(curint);
}
function findBorderIntersections(b,c,s){
if(b<2){
//top or bottom
let xint = [];
for(let l=0;l<c.length;l++){
if(c[l] != 'n/a'){
xint[l] = (height*b - s[l])/c[l];
}
else{
xint[l] = 'n/a';
}
}
//add intersections with borders in order T,B,L,R
xint.push( 'n/a', 'n/a', 0, width );
let intersections = [];
for(let i=0;i<xint.length;i++){
if(xint[i] != 'n/a'){
intersections.push([xint[i], height*b]);
}
else{
intersections.push(['n/a','n/a']);
}
}
return intersections;
}
else{
//left or right
let yint = [];
for(let l=0;l<c.length;l++){
if(c[l] != 'n/a'){
yint[l] = width*(b-2)*c[l] + s[l];
}
else{
yint[l] = 'n/a';
}
}
//add intersections with borders in order T,B,L,R
yint.push( 0, height, 'n/a', 'n/a' );
let intersections = [];
for(let i=0;i<yint.length;i++){
if(yint[i] != 'n/a'){
intersections.push([width*(b-2), yint[i]]);
}
else{
intersections.push(['n/a','n/a']);
}
}
return intersections;
}
}
function findHorInt(ms, pol, insec){
//use this one normally
let curdist = sqrt(width**2 + height**2);
let curint;
for(let i=0; i<insec.length; i++){
if(abs(pol[pol.length-1][0] - insec[i][0]) < curdist &&
Math.sign(insec[i][0] - pol[pol.length-1][0]) == ms ){
curdist = abs(pol[pol.length-1][0] - insec[i][0]);
curint = i;
}
}
return [[insec[curint][0], insec[curint][1]], curint];
}
function findVertInt(ms, pol, insec, c){
//use this one if on a vertical borderline and/or if previous line was horizontal
let curdist = sqrt(width**2 + height**2);
let curint;
for(let i=0; i<insec.length; i++){
if(abs(pol[pol.length-1][1] - insec[i][1]) < curdist &&
Math.sign(insec[i][1] - pol[pol.length-1][1]) == ms ){
curdist = abs(pol[pol.length-1][1] - insec[i][1]);
curint = i;
}
}
return [[insec[curint][0], insec[curint][1]], curint];
}
function draw(){
//draw using polygon arrays
for(let i = 0; i<polygons.length; i++){
fill(colors[i],255);
beginShape()
for(let j=0; j<polygons[i].length; j++){
vertex(polygons[i][j][0], polygons[i][j][1])
}
endShape(CLOSE)
}
}
function drawIntersections(insec){
for(let i=0; i<insec.length; i++){
if(insec[i][0] != 'n/a'){
drawMarker(insec[i][0], insec[i][1], 150);
}}
print("intersections: " + insec);
}
function drawMarker(x, y, col) {
stroke(col);
line(x - markersize, y, x + markersize, y);
line(x, y - markersize, x, y + markersize);
noStroke();
}