xxxxxxxxxx
106
//True if segments [p1,p2] and [p3,p4] intersect
function cross(p1,p2,p3,p4) {
let t = (p1.x-p3.x)*(p3.y-p4.y)-(p1.y-p3.y)*(p3.x-p4.x);
t = t/((p1.x-p2.x)*(p3.y-p4.y)-(p1.y-p2.y)*(p3.x-p4.x));
let u = -(p1.x-p2.x)*(p1.y-p3.y)+(p1.y-p2.y)*(p1.x-p3.x);
u = u/((p1.x-p2.x)*(p3.y-p4.y)-(p1.y-p2.y)*(p3.x-p4.x));
return(0<u && u<1 && 0<t && t<1);
}
class Shape {
constructor(n) {
this.npoints = n;
this.points = [];
this.createShape(n);
}
createShape(n){
//Simple random shape generation
//Choose n angles a and n distances r add a point at distance r from the center in direction a.
let angles = [];
//Random angles
for (let i=0;i<n;i++) {
angles.push(random(TWO_PI));
}
angles.sort();
for (let i=0;i<n;i++) {
//Change range of r for different types of shapes
let r = random(width/8,width/3);
this.points.push(new Point(width/2+r*cos(angles[i]),height/2+r*sin(angles[i])));
}
}
contains(p) {
//Draw a horizontal line from p. p inside the shape if odd number of intersections with the sides of the shape.
let p2 = new Point(p.x+width,p.y);
let count = 0;
for (let i=0;i<this.npoints;i++) {
if (cross(p,p2,this.points[i],this.points[(i+1)%this.npoints])) {
count = count+1;
}
}
return (count%2==1);
}
inside(r) {
//Check if shape completely inside a rectangle
//Since a rectangle is a convex shape, checking the vertices is enough
let x;
let y;
for (let i=0;i<this.npoints;i++) {
x = this.points[i].x;
y = this.points[i].y;
if (x<r.x || x>r.x+r.w || y<r.y || y>r.y+r.h) {
return(false);
}
}
return(true);
}
intersects(r) {
//True if r inside shape or r intersects shape
if (r.inside(this)||this.inside(r)) {
return(true);
}
let r1 = new Point(r.x,r.y);
let r2 = new Point(r.x+r.w,r.y);
let r3 = new Point(r.x,r.y+r.h);
let r4 = new Point(r.x+r.w,r.y+r.h);
for (let i=0;i<this.npoints;i++) {
if (cross(r1,r2,this.points[i],this.points[(i+1)%this.npoints])||
cross(r2,r3,this.points[i],this.points[(i+1)%this.npoints])||
cross(r3,r4,this.points[i],this.points[(i+1)%this.npoints])||
cross(r4,r1,this.points[i],this.points[(i+1)%this.npoints])) {
return(true);
}
}
return(false);
}
show() {
stroke(255,0,0);
strokeWeight(2);
noFill();
beginShape();
for (let i=0;i<this.npoints;i++){
vertex(this.points[i].x,this.points[i].y);
}
endShape(CLOSE);
}
}