-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflake.h
executable file
·108 lines (101 loc) · 2.89 KB
/
flake.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <string>
#include "vector.h"
#include "color.h"
using namespace std;
class flake;
class flake{
public:
int degree;
int direction; //Index of basis from child to parent
flake* parent; //Has to be a pointer or won't compile b/c flake is not
//yet full declared... No clue why this makes sense...
flake* child [6];
vector position;
color clr;
flake** ancestors;
flake* DEBUG[3];
static const double rBase;
static const double rChild;
static const int pointerLength;
flake();
flake(flake*,int);
int getDegree();
string svgStr();
flake* spawn();
void spawn(flake*);
bool withinHex(vector);
void getAncestors(flake*);
};
const double flake::rBase=500;
const double flake::rChild=2*pow(3.0,-0.5)*rBase;
const int ptrLen=sizeof(int *);
flake::flake(){
}
flake::flake(flake* initParent,int initDirection){
parent=initParent;
direction=initDirection;
degree=(*parent).degree+1;
position=(*parent).position-vector::basis[direction]*(rChild*pow(3.0,-(*parent).degree));
clr=color::black;
ancestors = (flake**) malloc(ptrLen*(degree+2));
ancestors[0]=parent;
memcpy(ancestors+1,(*parent).ancestors,ptrLen*(degree+1));
for(int i=0;i<3;i++){
vector testPoint=position+vector::basis[(direction+2*i)%6]*(rChild*pow(3.0,-degree));
for(int j=0;j<degree+2;j++){
if((*ancestors[j]).withinHex(testPoint)){
clr=clr+((*ancestors[j]).clr);
DEBUG[i]=ancestors[j];
break;
}
}
}
clr=color::normalize(clr);
}
int flake::getDegree(){
return degree;
}
string flake::svgStr(){
//This is no longer used.
char buffer [200];//This is pretty stupid, make it good...
size_t len=sprintf(buffer,"<circle cx=\"%f\" cy=\"%f\" r=\"%f\" fill=\"rgb(%i,%i,%i)\"/>\n"\
,position.x,position.y,(rBase*pow(3.0,-degree))\
,int(clr.r),int(clr.g),int(clr.b));
return string(buffer,len);
}
void flake::spawn(flake* pointer){
//This version writes the flakes to a specified memory location.
for(int i=0;i<6;i++){
pointer[i]=flake(this,i);
}
}
bool flake::withinHex(vector point){
//Tests if a point is within this flake's bounding hexagon.
double x=point.x-position.x;
double y=point.y-position.y;
double u= x*pow(3.0,-0.5)+y;
double v=-x*pow(3.0,-0.5)+y;
double radius=rChild*pow(3.0,-degree);
return ( radius>u && u>0 && radius>v && v>0) ||
(-radius<u && u<0 && -radius<v && v<0) ||
((0.5>(y/radius) && (y/radius)>-0.5) &&
(pow(3.0,0.5)/2>(x/radius) && (x/radius)>-pow(3.0,0.5)/2));
}
class hardFlake: public flake{
//Class for hardcoded flakes, like the primary and seccondary color ones.
public:
hardFlake(vector,color,int);
hardFlake(vector,color,int,flake**);
};
hardFlake::hardFlake(vector initPosition,color initColor,int initDegree){
position=initPosition;
clr=initColor;
degree=initDegree;
}
hardFlake::hardFlake(vector initPosition,color initColor,int initDegree,
flake** initAncestors){
position=initPosition;
clr=initColor;
degree=initDegree;
ancestors=initAncestors;
}