#include #include #include #include #include #include #include #include using namespace std; typedef std::pair coord; typedef std::list coordlist; coordlist tessellate(const coord &, const coord&, const double&); void print_pair(std::ostream &, const coord &); void save_data(const string &, const coordlist &); double distance(const coord &, const coord &); coord vec2rot(const coord &, const double &); coord vnormalize(const coord&); /* NAME: main DATE: 3/12/2016 AUTH: Anthony D. Baye DESC: main function for gosper boundary program. */ int main(const int argc, const char **argv) { coord c1, c2; double length, epsilon; coordlist vertices; coordlist::const_iterator it; string fName; if(argc < 4 || argc > 4) { cerr << "usage: SHM length epsilon file_name" << endl; return EXIT_FAILURE; } length = std::strtod(argv[1], NULL); epsilon = std::strtod(argv[2], NULL); fName = argv[3]; c1 = std::make_pair(-length/2.0, 0.0); c2 = std::make_pair(length/2.0, 0.0); vertices = tessellate(c1,c2,epsilon); save_data(fName, vertices); return EXIT_SUCCESS; } /* NAME: print_pair DATE: 3/14/2016 AUTH: Anthony D. Baye DESC: prints the contents of a std::pair as a comma-separated ordered pair. */ void print_pair(std::ostream &O, const coord &c) { O << setprecision(6) << fixed << left; O << "<" << c.first << "," << c.second << ">"; } /* NAME: distance DATE: 3/14/2016 AUTH: Anthony D. Baye DESC: computes the euclidean distance between p1 and p2. */ double distance(const coord &p1, const coord &p2) { return sqrt(pow(p2.first - p1.first,2) + pow(p2.second - p1.second,2)); } /* NAME: vec2rot DATE: 3/14/2016 AUTH: Anthony D. Baye DESC: rotates a given vector V by angle A. */ coord vec2rot(const coord &V, const double &A) { coord RESULT; RESULT = std::make_pair( V.first*cos(A) - V.second*sin(A), V.first*sin(A) + V.second*cos(A) ); return RESULT; } /* NAME: vnormalize DATE: 3/14/2016 AUTH: Anthony D. Baye DESC: converts the 2D vector V into a normalized unit-vector. */ coord vnormalize(const coord &V) { double length = sqrt(V.first * V.first + V.second * V.second); return std::make_pair(V.first/length, V.second/length); } /* NAME: tessellate DATE: 3/14/2016 AUTH: Anthony D. Baye DESC: breaks the line between p0 and p1 into a gosper island boundary. */ coordlist tessellate(const coord &p0, const coord&p1, const double &E) { double dist, THETA = asin(sqrt(3)/(2*sqrt(7))); coord vec,np1,np2; coordlist RESULT; dist = distance(p0, p1); vec = make_pair(p1.first-p0.first, p1.second-p0.second); vec = vnormalize(vec); vec = vec2rot(vec, THETA); vec = make_pair(dist/sqrt(7)*vec.first, dist/sqrt(7)*vec.second); np1 = make_pair(p0.first + vec.first, p0.second + vec.second); np2 = make_pair(p1.first - vec.first, p1.second - vec.second); if(dist > E) { RESULT.splice(RESULT.end(),std::move(tessellate(p0,np1,E))); RESULT.splice(RESULT.end(),std::move(tessellate(np1,np2,E))); RESULT.splice(RESULT.end(),std::move(tessellate(np2,p1,E))); } else { RESULT.push_back(std::move(np1)); RESULT.push_back(std::move(np2)); } return RESULT; } /* NAME: save_data DATE: 3/13/2016 AUTH: Anthony D. Baye DESC: saves coords contained in L to a file named according to fName. */ void save_data(const string &fName, const coordlist &L) { fstream fout; coordlist::const_iterator it; int count = 0; std::setprecision(6); fout.open(fName.c_str(),ios::out); fout << "array [" << L.size() << "] {" << endl; for(it = L.begin(); it != L.end(); it++, count++) { fout << " "; print_pair(fout, *it); fout << (*it == L.back() ? "" : ",") << endl; } fout << " }" << endl; fout.close(); }