xxxxxxxxxx
155
points = []
noOfPoints = 20
boundStack = []
startPoint = null
currInd = null
isLoop = true
function setup() {
createCanvas(400, 400);
buffer = 20
for(let i=0; i<noOfPoints; ++i) {
points.push(createVector(random(buffer, width-buffer), random(buffer, height-buffer)))
}
getStart()
points.sort(sortFunc)
boundStack.push(0)
boundStack.push(1)
currInd = 2
nopLabel = createP('No Of Points (20): ')
nopLabel.position(80, 390)
nopSlider = createSlider(10, 200, 20)
nopSlider.position(200, 400)
button = createButton('New Points')
button.position(0, 430)
button.mousePressed(newPoints);
label = createP('FrameRate (2): ')
label.position(100, 420)
frameSlider = createSlider(1, 60, 2)
frameSlider.position(200, 430)
frameRate(2)
}
function newPoints() {
points = []
noOfPoints = nopSlider.value()
boundStack = []
startPoint = null
isLoop = true
currInd = null
for(let i=0; i<noOfPoints; ++i) {
points.push(createVector(random(buffer, width-buffer), random(buffer, height-buffer)))
}
getStart()
points.sort(sortFunc)
boundStack.push(0)
boundStack.push(1)
currInd = 2
}
function getStart() {
let maxY = 0
let minX = width
let index = -1
for(let i=0; i<noOfPoints; ++i) {
if(maxY < points[i].y) {
maxY = points[i].y
index = i
} else if (maxY == points[i].y && minX > points[i].x) {
minX = points[i].x
index = i
}
}
startPoint = points[index]
}
function sortFunc(a, b) {
if(a.equals(startPoint)) return -1*Infinity;
if(b.equals(startPoint)) return Infinity;
distA = a.dist(startPoint)
distB = b.dist(startPoint)
cosA = (a.x - startPoint.x)/distA
cosB = (b.x - startPoint.x)/distB
return cosB-cosA
}
function checkTurn(ai, bi, ci) {
if(ci >= points.length) return 1
// (x2-x1)(y3-y1) - (y2-y1)(x3-x1)
a = points[ai]
b = points[bi]
c = points[ci]
crossProd = ((b.x-a.x)*(c.y-a.y)) - ((b.y-a.y)*(c.x-a.x))
if(crossProd<0) return 1;
else return -1;
}
function draw() {
background(220);
frameRate(frameSlider.value())
label.html('FrameRate (' + frameSlider.value() +'):')
nopLabel.html('No Of Points (' + nopSlider.value() +'):')
if(points.length != nopSlider.value()) {
newPoints()
}
stroke(0)
strokeWeight(8)
point(startPoint.x, startPoint.y)
strokeWeight(4)
for(let i=0; i<noOfPoints; ++i) {
point(points[i].x, points[i].y)
}
stroke(0, 255, 0)
strokeWeight(2)
let bl = boundStack.length
for(let i=1; i<bl; ++i) {
line(points[boundStack[i]].x, points[boundStack[i]].y, points[boundStack[i-1]].x, points[boundStack[i-1]].y)
}
if(currInd < points.length) {
stroke(0, 0, 255)
line(points[boundStack[bl-1]].x, points[boundStack[bl-1]].y, points[currInd].x, points[currInd].y)
} else {
stroke(0, 255, 0)
line(points[boundStack[bl-1]].x, points[boundStack[bl-1]].y, startPoint.x, startPoint.y)
isLoop = false
}
if(isLoop) {
if(bl>1) {
if(checkTurn(boundStack[bl-2], boundStack[bl-1], currInd) == -1) {
boundStack.pop()
}
else {
if(currInd == points.length) currInd=0;
boundStack.push(currInd)
currInd++
}
}
else {
if(currInd == points.length) currInd=0;
boundStack.push(currInd)
currInd++
}
}
}