class IGPFamily { PVector mid; float diameter; float radius; Float[] defaultFillColor = {0.0, 0.0, 0.0, 0.0}; Float[] defaultStrokeColor = {0.66, 0.66, 0.66, 0.4}; Float[] fillColor; Float[] strokeColor; ArrayList alphaCircleVectors; ArrayList alphaCircleVectorsSixteen; ArrayList constructionCircleCenters; ArrayList twelveBaseVectorsOnOuterSquare; ArrayList sixteenBaseVectorsOnOuterSquare; IGPFamily(float x, float y, float d){ ellipseMode(CENTER); rectMode(CENTER); colorMode(RGB, 1.0, 1.0, 1.0, 1.0); mid = new PVector(x, y); diameter = d; radius = d/2; setVectorsOnAlphaCircle(); println("New IGP object: x="+mid.x+"/ y="+mid.y+"/ diameter="+diameter); } void setVectorsOnAlphaCircle(){ alphaCircleVectors = new ArrayList (12); alphaCircleVectors.add(getVectorOnAlphaCircle(0)); alphaCircleVectors.add(getVectorOnAlphaCircle(30)); alphaCircleVectors.add(getVectorOnAlphaCircle(60)); alphaCircleVectors.add(getVectorOnAlphaCircle(90)); alphaCircleVectors.add(getVectorOnAlphaCircle(120)); alphaCircleVectors.add(getVectorOnAlphaCircle(150)); alphaCircleVectors.add(getVectorOnAlphaCircle(180)); alphaCircleVectors.add(getVectorOnAlphaCircle(210)); alphaCircleVectors.add(getVectorOnAlphaCircle(240)); alphaCircleVectors.add(getVectorOnAlphaCircle(270)); alphaCircleVectors.add(getVectorOnAlphaCircle(300)); alphaCircleVectors.add(getVectorOnAlphaCircle(330)); alphaCircleVectorsSixteen = new ArrayList (16); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(0)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(22.5)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(45)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(67.5)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(90)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(112.5)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(135)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(157.5)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(180)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(202.5)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(225)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(247.5)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(270)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(292.5)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(315)); alphaCircleVectorsSixteen.add(getVectorOnAlphaCircle(337.5)); } void setFillColor(Float[] fillColor){ if (fillColor.length==4){ this.fillColor = fillColor; } } void setStrokeColor(Float[] strokeColor){ if (strokeColor.length==4){ this.strokeColor = strokeColor; } } void useStrokeColor(){ if(this.strokeColor == null || this.strokeColor.length!=4){ strokeColor = defaultStrokeColor; } stroke(strokeColor[0], strokeColor[1], strokeColor[2], strokeColor[3]); } void useFillColor(){ if(fillColor == null || fillColor.length!=4){ fillColor = defaultFillColor; } fill(fillColor[0], fillColor[1], fillColor[2], fillColor[3]); } PVector getVectorOnCircle(PVector mid, float degree){ PVector point = new PVector(mid.x + radius*cos(radians(degree)), mid.y + radius * sin(radians(degree))); return point; } PVector getVectorOnAlphaCircle(float degree){ return getVectorOnCircle(mid, degree); } void createSquare(PVector mid, float diameter){ useStrokeColor(); useFillColor(); rect(mid.x, mid.y, diameter, diameter); } void createOuterSquare() { createSquare(mid, diameter); } void createInnerSquare() { createSquare(mid, sqrt(sq(diameter)/2)); } void createInnerSquareTilted(float angle){ translate(mid.x, mid.y); pushMatrix(); rotate(radians(angle)); createSquare(new PVector(0, 0), sqrt(sq(diameter)/2)); popMatrix(); translate(mid.x*(-1), mid.y*(-1)); } void createCircle(PVector v, float diameter) { useStrokeColor(); useFillColor(); ellipse(v.x, v.y, diameter, diameter); } void createAlphaCircle() { createCircle(mid, diameter); } void createConstructionCircles(){ for (PVector constructionCircle : constructionCircleCenters) { createCircle(constructionCircle, diameter); } } void createLine(PVector from, PVector to){ useStrokeColor(); useFillColor(); beginShape(LINES); vertex(from.x, from.y); vertex(to.x, to.y); endShape(); } void createVerticalHorizontalConstructionLines(){ createLine(alphaCircleVectors.get(0), alphaCircleVectors.get(6)); createLine(alphaCircleVectors.get(3), alphaCircleVectors.get(9)); } void createDiagonalConstructionLinesOnOuterSquare(){ createLine(new PVector(mid.x+radius, mid.y+radius), new PVector(mid.x-radius, mid.y-radius)); createLine(new PVector(mid.x+radius, mid.y-radius), new PVector(mid.x-radius, mid.y+radius)); } void createDiagonalConstructionLinesOnAlphaCircle(){ createLine(alphaCircleVectorsSixteen.get(2), alphaCircleVectorsSixteen.get(10)); createLine(alphaCircleVectorsSixteen.get(6), alphaCircleVectorsSixteen.get(14)); } void createInnerHexagon(){ useStrokeColor(); useFillColor(); beginShape(LINES); vertex(alphaCircleVectors.get(1).x, alphaCircleVectors.get(1).y); vertex(alphaCircleVectors.get(3).x, alphaCircleVectors.get(3).y); vertex(alphaCircleVectors.get(3).x, alphaCircleVectors.get(3).y); vertex(alphaCircleVectors.get(5).x, alphaCircleVectors.get(5).y); vertex(alphaCircleVectors.get(5).x, alphaCircleVectors.get(5).y); vertex(alphaCircleVectors.get(7).x, alphaCircleVectors.get(7).y); vertex(alphaCircleVectors.get(7).x, alphaCircleVectors.get(7).y); vertex(alphaCircleVectors.get(9).x, alphaCircleVectors.get(9).y); vertex(alphaCircleVectors.get(9).x, alphaCircleVectors.get(9).y); vertex(alphaCircleVectors.get(11).x, alphaCircleVectors.get(11).y); vertex(alphaCircleVectors.get(11).x, alphaCircleVectors.get(11).y); vertex(alphaCircleVectors.get(1).x, alphaCircleVectors.get(1).y); endShape(); } void createInnerHexagonTilted(float angle){ useStrokeColor(); useFillColor(); translate(mid.x, mid.y); pushMatrix(); rotate(radians(angle)); beginShape(LINES); vertex(alphaCircleVectors.get(1).x-mid.x, alphaCircleVectors.get(1).y-mid.y); vertex(alphaCircleVectors.get(3).x-mid.x, alphaCircleVectors.get(3).y-mid.y); vertex(alphaCircleVectors.get(3).x-mid.x, alphaCircleVectors.get(3).y-mid.y); vertex(alphaCircleVectors.get(5).x-mid.x, alphaCircleVectors.get(5).y-mid.y); vertex(alphaCircleVectors.get(5).x-mid.x, alphaCircleVectors.get(5).y-mid.y); vertex(alphaCircleVectors.get(7).x-mid.x, alphaCircleVectors.get(7).y-mid.y); vertex(alphaCircleVectors.get(7).x-mid.x, alphaCircleVectors.get(7).y-mid.y); vertex(alphaCircleVectors.get(9).x-mid.x, alphaCircleVectors.get(9).y-mid.y); vertex(alphaCircleVectors.get(9).x-mid.x, alphaCircleVectors.get(9).y-mid.y); vertex(alphaCircleVectors.get(11).x-mid.x, alphaCircleVectors.get(11).y-mid.y); vertex(alphaCircleVectors.get(11).x-mid.x, alphaCircleVectors.get(11).y-mid.y); vertex(alphaCircleVectors.get(1).x-mid.x, alphaCircleVectors.get(1).y-mid.y); endShape(); popMatrix(); translate(mid.x*(-1), mid.y*(-1)); } void createInnerTriangle(){ useStrokeColor(); useFillColor(); triangle(alphaCircleVectors.get(1).x, alphaCircleVectors.get(1).y, alphaCircleVectors.get(5).x, alphaCircleVectors.get(5).y, alphaCircleVectors.get(9).x, alphaCircleVectors.get(9).y); } void createInnerTriangleTilted(float angle){ useStrokeColor(); useFillColor(); translate(mid.x, mid.y); pushMatrix(); rotate(radians(angle)); triangle(alphaCircleVectors.get(1).x-mid.x, alphaCircleVectors.get(1).y-mid.y, alphaCircleVectors.get(5).x-mid.x, alphaCircleVectors.get(5).y-mid.y, alphaCircleVectors.get(9).x-mid.x, alphaCircleVectors.get(9).y-mid.y); popMatrix(); translate(mid.x*(-1), mid.y*(-1)); } PVector getLineIntersection(PVector p1, PVector p2, PVector p3, PVector p4) { PVector b = PVector.sub(p2, p1); PVector d = PVector.sub(p4, p3); float b_dot_d_perp = b.x * d.y - b.y * d.x; if (b_dot_d_perp == 0) { return null; } PVector c = PVector.sub(p3, p1); float t = (c.x * d.y - c.y * d.x) / b_dot_d_perp; if (t < 0 || t > 1) { return null; } float u = (c.x * b.y - c.y * b.x) / b_dot_d_perp; if (u < 0 || u > 1) { return null; } return new PVector(p1.x+t*b.x, p1.y+t*b.y); } float getAngleBetweenTwoVectors (PVector p1, PVector p2) { float angle = atan2(p1.y-p2.y, p1.x-p2.x); if (angle < 0) { angle+=TWO_PI; } return degrees(angle); } PVector getVectorOnExtendedLine(PVector startPoint, PVector endPoint, float boundary, boolean vertical){ float m,n; boolean dirac = false; if (endPoint.x-startPoint.x == 0){ dirac = true; m = 0; } else { m = (endPoint.y-startPoint.y)/(endPoint.x-startPoint.x); } n = endPoint.y-m*endPoint.x; if (vertical){ if (dirac){ return new PVector(startPoint.x, boundary); }else{ return new PVector((boundary-n)/m, boundary); } } else { return new PVector(boundary, (m*boundary)+n); } } void displayConstructionLines() { setStrokeColor(new Float[] {0.8, 0.4, 0.4, 1.0}); setFillColor(new Float[] {0.0, 0.0, 0.0, 0.0}); createAlphaCircle(); createConstructionCircles(); createVerticalHorizontalConstructionLines(); } }