/* -*- c++ -*- * Copyright ©2008 Hugo Mills * * This software is distributed under the terms of the GNU GPL v3 * For more information on the GPL, see the file COPYING or * visit http://www.gnu.org/ * * This software is distributed without warranty */ #include "content_loxodrome.h" extern "C" PluginInfo* getmodules(int i) { if(i==0) { PluginInfo_Content* pi = new PluginInfo_Content(); pi->name = "Loxodrome paths"; pi->author = "Hugo Mills"; pi->copyright = "©2008 Hugo Mills"; pi->version = 0x00200; pi->parser = Content_Loxodrome::parse; return pi; } else return NULL; } Content* Content_Loxodrome::parse( ConfigLexer* lex, const std::string& type, const std::string& subtype ) { if(type != "loxodrome") return NULL; double x0 = 0.0; double y0 = 0.0; double x1 = 1.0; double y1 = 1.0; int loops = 0; bool solid = false; ivec3 col1(255); while(!lex->eos()) { if(readkeyedvalue(lex, "start", &x0, &y0) || readkeyedvalue(lex, "end", &x1, &y1) || readkeyedvalue(lex, "loops", &loops) || readbooleanvalue(lex, "solid", &solid) || readkeyedvalue(lex, "colour", &col1[0], &col1[1], &col1[2]) ) { } else throw(UnknownConfigToken(lex)); } return new Content_Loxodrome(x0, y0, x1, y1, loops-1, solid, col1); } Content_Loxodrome::Content_Loxodrome( double x0, double y0, double x1, double y1, int loops, bool s, const ivec3& col1 ) : solid(s), colour(col1) { x0 = degrad(x0); x1 = degrad(x1); y0 = degrad(y0); y1 = degrad(y1); double sigma0 = asinh(tan(y0)); double sigma1 = asinh(tan(y1)); double l = 2*M_PI*loops; lon0 = x0; // Longitude origin for t=0 lons = (x1 + l - x0); // Longitude distance for t=0 to t=1 k = (sigma1-sigma0)/lons; // "Slope" value C = x0 - sigma0/k; // "Offset" value } void Content_Loxodrome::plot( Output* bitmap, XfView* viewport, XfMap* projection, XfOrbit* orbit, XfSphere* sphere ) { dvec2 latlong; dvec3 globe_pos; dvec3 shifted_pos; dvec2 map_pos; ivec2 vp_pos; // Draw loxodrome double t = 0.0; while(t <= 1.0) { latlong[0] = lon0 + lons * t; latlong[1] = atan(sinh(k * (latlong[0]-C))); if(sphere->f(globe_pos, latlong) && orbit->f(shifted_pos, globe_pos) && projection->f(map_pos, shifted_pos) && viewport->f(vp_pos, map_pos)) { bitmap->setpixel(vp_pos, colour); } else { // Do nothing, and move on to the next point } t += 0.01; } }