Shape.pde
enum ShapeType {
TRIANGLE,
UPSIDE_DOWN_TRIANGLE
}
class Shape {
ShapeType type;
PVector center;
float radius;
float max_distance;
int step = 0;
int step_cycle = 180;
float angle;
float x1, y1;
float x2, y2;
float x3, y3;
color col;
Shape(ShapeType type_, PVector center_, float radius_) {
type = type_;
center = new PVector();
center = center_.copy();
radius = radius_;
col = color(100);
// default max distance from center to edge of sketch, set more accurately later
setMaxDistance(dist(0, 0, (width / 2), (height / 2)));
// calculate initial points
calculatePoints(radius);
}
void setColor(color col_) {
col = col_;
}
void setMaxDistance(float max_distance_) {
max_distance = max_distance_;
// setup starting step
float distance_to_center = distanceToCenter();
step = floor(map(
distance_to_center,
0,
abs(max_distance),
(step_cycle - 1),
0
));
calculateColorBasedOnDistance();
}
void calculateColorBasedOnDistance() {
float distance_to_center = distanceToCenter();
col = color(map(distance_to_center, 0, max_distance, 0, 100), 100, 100);
}
void setAngle(float angle_) {
angle = angle_;
}
float width() {
return ((cos(radians(30)) - cos(radians(150))) * radius);
}
float height() {
return ((sin(radians(150)) - sin(radians(-90))) * radius);
}
float distanceToCenter() {
// calculate distance
return dist(center.x, center.y, (width / 2), (height / 2));
}
void calculatePoints(float r_) {
if(type == ShapeType.TRIANGLE) {
x1 = (center.x + (cos(radians(-90 + angle)) * r_));
y1 = (center.y + (sin(radians(-90 + angle)) * r_));
x2 = (center.x + (cos(radians(30 + angle)) * r_));
y2 = (center.y + (sin(radians(30 + angle)) * r_));
x3 = (center.x + (cos(radians(150 + angle)) * r_));
y3 = (center.y + (sin(radians(150 + angle)) * r_));
} else if(type == ShapeType.UPSIDE_DOWN_TRIANGLE) {
x1 = (center.x + (cos(radians(90 + angle)) * r_));
y1 = (center.y + (sin(radians(90 + angle)) * r_));
x2 = (center.x + (cos(radians(-30 + angle)) * r_));
y2 = (center.y + (sin(radians(-30 + angle)) * r_));
x3 = (center.x + (cos(radians(-150 + angle)) * r_));
y3 = (center.y + (sin(radians(-150 + angle)) * r_));
}
}
void calculateStepAngle() {
int steps[];
if(type == ShapeType.UPSIDE_DOWN_TRIANGLE) {
steps = new int[2];
steps[0] = 0;
steps[1] = 90;
//steps[2] = 200;
//steps[3] = 300;
//steps[4] = 400;
} else {
steps = new int[2];
steps[0] = 0;
steps[1] = 90;
//steps[2] = 200;
//steps[3] = 300;
//steps[4] = 400;
}
int step_size = 45;
int step_multiplier = 1;
for(int i = 0; i < steps.length; i++) {
if((step >= steps[ i ]) && (step <= (steps[ i ] + step_size))) {
angle = map(step, steps[ i ], (steps[ i ] + step_size), 0, (360 * step_multiplier));
break;
}
step_multiplier *= -1;
}
// trim angle
if(angle >= 360) {
angle = 0;
} else if(angle <= -360) {
angle = 0;
}
}
color calculateAngledColor() {
if((angle > 0) || (angle < 0)) {
return col;
}
/*if(angle > 0) {
float angle_amt = map(angle, 1, 359, 0, 1);
//return color(map(angle, 1, 359, 0, 100), 100, 100);
return lerpColor(
color(100),
col,
angle_amt
);
} else if(angle < 0) {
float angle_amt = map(angle, -1, -359, 0, 1);
//return color(map(angle, -1, -359, 0, 100), 100, 100);
return lerpColor(
col,
color(100),
angle_amt
);
} else {*/
if(type == ShapeType.UPSIDE_DOWN_TRIANGLE) {
return color(20, 10, 10, 0);
}
return color(100);
//}
}
void update() {
// set next step
step += 1;
if(step > step_cycle) {
step = 1;
}
calculateStepAngle();
float step_radius = radius;
if(angle != 0) {
float middle_angle = 180;
float radius_min = (radius * 0.3);
step_radius = (radius - (radius_min * (1 - (abs(abs(angle) - middle_angle) / middle_angle))));
}
// calculate new points
calculatePoints(step_radius);
}
void render() {
pushMatrix();
//white: fill(100);
//distance color: fill(map(distanceToCenter(), 0, (width / 2), 100, 0), 100, 100);
fill(calculateAngledColor());
noStroke();
triangle(x1, y1, x2, y2, x3, y3);
popMatrix();
}
}
triangle_triangles.pde
Shape[] shapes;
int num_tris = 17;
float tri_radius = 16.0;
int nth_triangle(int t) {
return ((int(sq(float(t))) + t) / 2);
}
float nth_triangle(float t) {
return ((sq(t) + t) / 2);
}
float triangleWidth(float radius) {
return ((cos(radians(30)) - cos(radians(150))) * radius);
}
float triangleHeight(float radius) {
return ((sin(radians(150)) - sin(radians(-90))) * radius);
}
void setup() {
size(640, 640);
colorMode(HSB, 100);
shapes = new Shape[ nth_triangle(num_tris) ];
//shapes = new Shape[ ((nth_triangle(num_tris) * 2) - num_tris) ];
int si = 0;
PVector pos = new PVector(0.0, 0.0);
pos.x += (width / 2);
pos.y += ((height / 2) - (((triangleHeight(tri_radius) * num_tris) / 2) - (triangleHeight(tri_radius) / 2)));
for(int i = 1; i <= num_tris; i++) {
PVector tri_pos = new PVector();
tri_pos = pos.copy();
for(int t = 0; t < i; t++) {
shapes[ si ] = new Shape(ShapeType.TRIANGLE, tri_pos, tri_radius);
si++;
tri_pos.add(triangleWidth(tri_radius), 0.0);
}
pos.add((triangleWidth(tri_radius) * -0.5), triangleHeight(tri_radius));
}
/*// add upside down triangles
int lsi = 0;
for(int i = 1; i < num_tris; i++) {
for(int t = 0; t < i; t++) {
PVector u_pos = new PVector();
u_pos = shapes[ lsi ].center.copy();
u_pos.add(0, (triangleHeight(tri_radius) / 2) + 4.3);
shapes[ si ] = new Shape(ShapeType.UPSIDE_DOWN_TRIANGLE, u_pos, tri_radius);
si++;
lsi++;
}
}*/
// find most distant triangle from center (bottom right) and max distance on all
PVector last_tri_center = new PVector();
last_tri_center = shapes[ (nth_triangle(num_tris) - 1) ].center.copy();
float max_dist = dist(last_tri_center.x, last_tri_center.y, (width / 2), (height / 2));
for(int i = 0; i < shapes.length; i++) {
shapes[ i ].setMaxDistance(max_dist);
}
}
void draw() {
background(20, 10, 10);
for(int i = 0; i < shapes.length; i++) {
shapes[ i ].update();
shapes[ i ].render();
}
if(frameCount == 50) { save("preview.png"); }
}