diff --git a/examples/HCircleLayout/HCircleLayout_004/HCircleLayout_004.pde b/examples/HCircleLayout/HCircleLayout_004/HCircleLayout_004.pde new file mode 100644 index 00000000..9c09b311 --- /dev/null +++ b/examples/HCircleLayout/HCircleLayout_004/HCircleLayout_004.pde @@ -0,0 +1,41 @@ +import hype.*; +import hype.extended.layout.HCircleLayout; + +HDrawablePool pool; +float numAssets = 200.0; + +void setup() { + size(640,640); + H.init(this).background(#242424); + + pool = new HDrawablePool((int)numAssets); + pool.autoAddToStage() + .add(new HRect(2,100).rounding(4)) + + .layout( + new HCircleLayout() + .radius(200) + .startLoc(width/2,height/2) + .angleStep(360.0/numAssets) + .rotateTarget(true) + + ) + + .onCreate( + new HCallback() { + public void run(Object obj) { + HDrawable d = (HDrawable) obj; + d.noStroke().fill(#ECECEC).anchorAt(H.CENTER); + } + } + ) + .requestAll() + ; + + H.drawStage(); + noLoop(); +} + +void draw() { + +} \ No newline at end of file diff --git a/examples/HCircleLayout/HCircleLayout_007/HCircleLayout_007.pde b/examples/HCircleLayout/HCircleLayout_007/HCircleLayout_007.pde new file mode 100644 index 00000000..b010ec3d --- /dev/null +++ b/examples/HCircleLayout/HCircleLayout_007/HCircleLayout_007.pde @@ -0,0 +1,66 @@ +import hype.*; +import hype.extended.layout.HCircleLayout; + +import hype.extended.behavior.HOscillator; + +int assets = 2880; +HCircleLayout circle; +HDrawablePool pool; + +void setup() { + size(640, 640, P3D); + H.init(this).background(#242424).use3D(true); + + circle = new HCircleLayout() + .startLoc(width/2, height/2).radius(150).angleStep((float)22*360/assets) + .useNoise(true) + .rotateTarget(true) + .noiseRadius(100); + + pool = new HDrawablePool(assets); + pool.autoAddToStage() + .add(new HRect(2, 2).noStroke().fill(#FF3300).anchorAt(H.CENTER)) + .layout(circle) + .onCreate( + new HCallback() { + public void run(Object obj) { + int i = pool.currentIndex(); + HDrawable d = (HDrawable) obj; + new HOscillator() + .target(d) + .property(H.Z) + .relativeVal(d.z()) + .range(-120, 120) + .speed(2.3) + .freq(1.5) + .currentStep(i%360) + .waveform(H.EASE) + ; + + } + } + ) + .requestAll() + ; + + + + //outline to show min/max noise bounds + float x = circle.startX(); + float y = circle.startY(); + //H.add(new HEllipse(circle.minRadius()).noFill().loc(x, y).anchorAt(H.CENTER)); + //H.add(new HEllipse(circle.maxRadius()).noFill().loc(x, y).anchorAt(H.CENTER)); + + //map dark/light colors according to min/max noise radisu + for (HDrawable d : pool) { + float len = dist(d.x(), d.y(), x, y); + int clr = (int)map(len, circle.minRadius(), circle.maxRadius(), 0, 255); + d.fill(clr, clr); + } + + +} + +void draw() { + H.drawStage(); +} \ No newline at end of file diff --git a/src/main/java/hype/extended/layout/HCircleLayout.java b/src/main/java/hype/extended/layout/HCircleLayout.java new file mode 100644 index 00000000..a9b44bc1 --- /dev/null +++ b/src/main/java/hype/extended/layout/HCircleLayout.java @@ -0,0 +1,197 @@ +package hype.extended.layout; + +import hype.interfaces.HLayout; +import hype.H; +import hype.HDrawable; + +import processing.core.PVector; + +import static processing.core.PApplet.cos; +import static processing.core.PApplet.sin; +import static processing.core.PApplet.radians; +import static processing.core.PApplet.map; + +public class HCircleLayout implements HLayout { + + private int currentIndex; + private float angleStep, startAngle; + private float angleStepRad, startAngleRad; + private float radius, startX, startY, startZ; + private float noiseRadius; + private boolean rotateTarget; + private boolean useNoise; + + public HCircleLayout() { + radius = 100; + startX = 0; + startY = 0; + startZ = 0; + currentIndex = 0; + noiseRadius = radius / 10.0F; + this.angleStep(60.0F); + this.startAngle(0.0F); + } + + public PVector startLoc() { + return new PVector(startX, startY, startZ); + } + + public HCircleLayout startLoc(float x, float y) { + startX = x; + startY = y; + startZ = 0; + return this; + } + + public HCircleLayout startLoc(float x, float y, float z) { + startX = x; + startY = y; + startZ = z; + return this; + } + + public float startX() { + return startX; + } + + public HCircleLayout startX(float x) { + startX = x; + return this; + } + + public float startY() { + return startY; + } + + public HCircleLayout startY(float y) { + startY = y; + return this; + } + + public float startZ() { + return startZ; + } + + public HCircleLayout startZ(float z) { + startZ = z; + return this; + } + + public HCircleLayout currentIndex(int i) { + currentIndex = i; + return this; + } + + public int currentIndex() { + return currentIndex; + } + + public HCircleLayout resetIndex() { + currentIndex = 0; + return this; + } + + public HCircleLayout radius(float f) { + radius = f; + return this; + } + + public float radius() { + return radius; + } + + public HCircleLayout angleStep(float f) { + angleStepRad = radians(f); + angleStep = f; + return this; + } + + public float angleStep() { + return angleStep; + } + + public float angleStepRad() { + return angleStepRad; + } + + public HCircleLayout startAngle(float f) { + startAngleRad = radians(f); + startAngle = f; + return this; + } + + public float startAngle() { + return startAngle; + } + + public float startAngleRad() { + return startAngleRad; + } + + public HCircleLayout rotateTarget(boolean b) { + rotateTarget = b; + return this; + } + + public boolean rotateTarget() { + return rotateTarget; + } + + + public HCircleLayout useNoise(boolean b) { + useNoise = b; + return this; + } + + public boolean useNoise() { + return useNoise; + } + + public float noiseRadius() { + return noiseRadius; + } + + public HCircleLayout noiseRadius(float r) { + noiseRadius = r; + return this; + } + + public float maxRadius() { + return radius + noiseRadius; + } + + public float minRadius() { + return radius - noiseRadius; + } + + + @Override + public PVector getNextPoint() { + + float a = startAngleRad + (angleStepRad * currentIndex); + + float r = radius; + if (useNoise) { + float n = H.app().noise(0.1f * currentIndex); + n = map(n, 0.0f, 1.0f, -1.0f, 1.0f); + r = radius + noiseRadius * n; + } + + float x = r * cos(a) + startX; + float y = r * sin(a) + startY; + float z = startZ; + + ++currentIndex; + return new PVector(x, y, z); + } + + @Override + public void applyTo(HDrawable target) { + if (rotateTarget) { + float a = radians(90) + startAngleRad + (angleStepRad * currentIndex); + target.rotationZRad(a); + } + target.loc(getNextPoint()); + } +} +