All pastes #1537430 Raw Edit

Stuff

public cpp v1 · immutable
#1537430 ·published 2009-08-21 08:44 UTC
rendered paste body
/* * astro.cpp written by nickolas * * this is a utility to display the astrological configuration for a specific * date, time, and set of lat- and longitudinal coordinates. * * this application uses the astrodienst swisseph library and swiss ephemeris, * and must be built on the system that this is being compiled on. if you have * this utility you probably have it as well as the necessary ephemeride files * to compute charts for the dates you desire. if not, see here: * * if you're doing computation for dates between 1800 AD and 2399 AD, you only * need these ephemeride files: * * sepl_18.se1 (planets file) * semo_18.se1 (moon file) * seas_18.se1 (asteroid file) * * ... each of which i have in the current working directory. * * in regards to the command-line options, there are only a couple things that * should be noted; most else should be self-explanitory if you're using this. * * * when you're providing a time value to the '-u' flag, you're providing a *   24-hour value in _universal time_. so, if you live in the EST time zone, *   and you would like to calculate a chart for noon time, you would provide *   17:00, because UTC is 5 hours in front of EST, and 17:00 is the 24-hour *   equivalent of 5 PM. * * * although the '-c' flag should also be pretty self-explanitory, an example *   for the coordinates of Boston, MA, which is 42.37 north latitude and *   71.05 west longitude, the topo value would be '-c 42.37N,71.05W'. also, *   if you don't use capital letters, you might get some errors spat out at *   you if you don't get any erratic behavior. about the lingering '0' after *   the latitude and longitude values, that is the altitude. if you don't know *   the correct altitude for the coordinates you're providing, you can just *   leave it at 0. it most likely won't make that much of a difference to *   any part of your chart (except by maybe a degree or two or three). * * * $ 8/20/2009: currently no real checks for the proper formatting of the *              date and time strings, so take care to use them properly! *              i.e. two digits for day, month, minutes and hours, and four *              for the year (same for topo). i'll fix this in the next update. *  * $ 8/21/2009: added checks for dates/times/topo. quicker than i thought that *              i would! * * that's all, enjoy! * */#include <iostream>#include <fstream>#include <string>#include <vector>#include <unistd.h>#include <swephexp.h>using namespace std;struct options{	bool sidereal;	bool tropical;	bool deg_to_sign;	double timeval;	double geo_long;	double geo_lati;	double geo_alti;	char londir;	char latdir;	int jd_day;	int jd_month;	int jd_year;};// set the datevoid set_date(options op, char *arg){	string date;	string delim;	vector<string> date_res;	int cutmark;	char *a = "/";	date = arg;	delim = a;	while ((cutmark = date.find_first_of(delim)) != date.npos)	{	if (cutmark > 0) date_res.push_back(date.substr(0, cutmark));		date = date.substr(cutmark + 1);	}	if (date.length() > 0) date_res.push_back(date);	op.jd_month =  atoi(date_res[0].c_str());	op.jd_day = atoi(date_res[1].c_str());	op.jd_year = atoi(date_res[2].c_str());}// set the timevoid set_time(options op, char *arg){	string time;	string lconv, ldelm, delim;	vector<string> time_res;	int cutmark;	char *a = ".", *b = ":";	time = arg;	ldelm = a;	delim = b;	while ((cutmark = time.find_first_of(delim)) != time.npos)	{	if (cutmark > 0) time_res.push_back(time.substr(0, cutmark));		time = time.substr(cutmark + 1);	}	if (time.length() > 0) time_res.push_back(time);        lconv = time_res[0] + ldelm + time_res[1];	op.timeval = strtod(lconv.c_str(), NULL);}// set the geographic positions (latitude, longitude, altitude)void set_topo(options op, char *arg){	string coord;	string lldelim;	string altit;	vector<string> ll_res;	int cutmark;	char *a = ",";	coord = arg;	lldelim = a;	while ((cutmark = coord.find_first_of(lldelim)) != coord.npos)	{	if (cutmark > 0) ll_res.push_back(coord.substr(0, cutmark));		coord = coord.substr(cutmark + 1);	}	if (coord.length() > 0) ll_res.push_back(coord);	char tmp_a[sizeof(coord[0]) - 1];	char tmp_b[sizeof(coord[1]) - 1];	string a_tmp, b_tmp;	a_tmp = coord[0];	b_tmp = coord[1];	if (a_tmp[strlen(a_tmp.c_str()) - 1] == 'S')	{	snprintf(tmp_a, sizeof(tmp_a) + 2, "-%s", coord[0]);		op.latdir = 'S';	} else	{	snprintf(tmp_a, sizeof(tmp_a) + 1, "%s", coord[0]);		op.latdir = 'N';	}	if (b_tmp[strlen(b_tmp.c_str()) - 1] == 'W')	{	snprintf(tmp_b, sizeof(tmp_b) + 2, "-%s", coord[1]);		op.londir = 'W';	} else	{	snprintf(tmp_b, sizeof(tmp_b) + 1, "%s", coord[1]);		op.londir = 'E';	}	altit = coord[2];	op.geo_lati = strtod(tmp_a, NULL);	op.geo_long = strtod(tmp_b, NULL);	op.geo_alti = strtod(altit.c_str(), NULL);}// print the chart to stdoutvoid print_chart(options op){	double comp_jdate;	double comp_jtime;	double parray[6];	int32 iflag = SEFLG_SPEED, iflag_ret;	char error[AS_MAXCH];	char pname[40];	int i;	comp_jdate = swe_julday(op.jd_year, op.jd_month, op.jd_day, op.timeval, SE_GREG_CAL);	comp_jtime = comp_jdate + swe_deltat(comp_jdate);	swe_set_topo(op.geo_long, op.geo_lati, op.geo_alti);	cout << "* at " << op.timeval << " on " << op.jd_month << "/"	     << op.jd_day << "/" << op.jd_year << endl;	cout << "* latitude: " << op.geo_lati << op.latdir << " "	     << "longitude: " << op.geo_long << op.londir << " "	     << "altitude: " << op.geo_alti << endl;	iflag |= SEFLG_TOPOCTR;	for (i = SE_SUN; i <= SE_CHIRON; i++)	{	if (i == SE_EARTH) continue;		iflag_ret = swe_calc(comp_jtime, i, iflag, parray, error);		if (iflag_ret < 0) cout << "# error: " << error << endl;		else if (iflag_ret != iflag) cout << "# warning: iflag_ret != iflag: " << error << endl;		swe_get_planet_name(i, pname);		cout << pname << "\t" << parray[0] << "\t" << parray[1];		cout << "\t" << parray[2] << "\t" << parray[3] << endl;	}}// show the help/usage screenvoid help_screen(char *name){	cout << "* utility to display astrological configurations" << endl;	cout << "* written by nickolas, using astrodienst swisseph" << endl;	cout << endl;	cout << "usage: " << name << " [-hjst] [-d date] [-u time] [-c topo]" << endl;	cout << "-h\tdisplay this intro/help message screen." << endl;	cout << "-j\t(requires either -s or -t flags) translate" << endl;	cout << "  \tconstellation degrees to signs, based on the" << endl;	cout << "  \tsidereal or tropical assigments." << endl;	cout << "-s\t(requires -j flag) display sidereal flavor chart, with" << endl;	cout << "  \tpisces at zero degrees." << endl;	cout << "-t\t(requires -j flag) display tropical flavor chart, with" << endl;	cout << "  \taries at zero degrees." << endl;	cout << "-d date\tcalculate chart for the date (on a gregorian calendar)" << endl;	cout << "       \tprovided by 'date' (format mm/dd/yyyy)" << endl;	cout << "-u time\tcalculate chart for the time (universal time)" << endl;	cout << "       \tprovided by 'time' (format hh:mm)" << endl;	cout << "-c topo\tcalculate chart for the lat- and longitudinal" << endl;	cout << "       \tcoordinates provided by 'topo' (format 00.00N,00.00W,0)" << endl;	cout << endl;	cout << "see the comments in the source file for extra (more detailed) help" << endl;	cout << "with these options and the general usage of this application; it" << endl;	cout << "is much, much easier to use than this help screen will have you believe." << endl;}// the main routineint main(int argc, char **argv){	options op;	int c;	while ((c = getopt(argc, argv, "hjstd:u:c:")) != -1)	{	switch(c)		{	case 'h':				help_screen(argv[0]);				return EXIT_FAILURE;			case 'j':				cout << "* converting degrees to constellation names" << endl;				op.deg_to_sign = true;				break;			case 's':				cout << "* using sidereal flavor chart (pisces at 0 degrees)" << endl;				if (op.deg_to_sign == true)				{	op.sidereal = true;					op.tropical = false;				}				break;			case 't':				cout << "* using tropical flavor chart (aries at 0 degrees)" << endl;				if (op.deg_to_sign == true)				{	op.sidereal = false;					op.tropical = true;				}				break;			case 'd':				set_date(op, optarg);				if (op.jd_day > 31 or op.jd_month > 12)				{	cout << argv[0] << ": error: invalid date string. quitting." << endl;					return EXIT_FAILURE;				}				break;			case 'u':				set_time(op, optarg);				if (op.timeval > 24.59)				{	cout << argv[0] << ": error: invalid time string. quitting." << endl;					return EXIT_FAILURE;				}				break;			case 'c':				set_topo(op, optarg);				break;			default:				help_screen(argv[0]);				return EXIT_FAILURE;		}	}	if (op.deg_to_sign == true and (op.sidereal == false and op.tropical == false))	{	help_screen(argv[0]);		return EXIT_FAILURE;	} 	print_chart(op);	return EXIT_SUCCESS;}