1
0
Fork 0

Initial revision of:

geocoord.cxx geocoord.h lowleveltime.cxx lowleveltime.h
   mymath.cxx mymath.h timezone.cxx timezone.h
Incorporating Durk's better timezone handling:
   Makefile.am fg_time.cxx fg_time.hxx
This commit is contained in:
curt 1999-09-07 23:11:22 +00:00
parent 92f7e1123c
commit 4dc4764510
11 changed files with 2584 additions and 34 deletions

View file

@ -4,8 +4,12 @@ libTime_a_SOURCES = \
event.cxx event.hxx \
fg_time.cxx fg_time.hxx \
fg_timer.cxx fg_timer.hxx \
geocoord.cxx geocoord.h \
light.cxx light.hxx \
lowleveltime.cxx lowleveltime.h \
timezone.cxx timezone.h \
moonpos.cxx moonpos.hxx \
mymath.cxx mymath.h \
sunpos.cxx sunpos.hxx \
timestamp.hxx

View file

@ -55,9 +55,12 @@
#include <FDM/flight.hxx>
#include <Include/fg_constants.h>
#include <Main/options.hxx>
#include <Misc/fgpath.hxx>
#include <Time/light.hxx>
#include "fg_time.hxx"
#include "timezone.h"
#include "lowleveltime.h"
#define DEGHR(x) ((x)/15.)
@ -77,62 +80,103 @@ FGTime::FGTime()
}
cur_time_params = this;
FGPath buffer( current_options.get_fg_root() );
buffer.append( "Timezone" );
buffer.append( "zone.tab" );
FG_LOG( FG_EVENT, FG_INFO, "Reading timezone info from: " << buffer.str() );
tzContainer = new TimezoneContainer( buffer.c_str() );
warp=0;
warp_delta=0;
}
FGTime::~FGTime()
{
delete tzContainer;
delete zonename;
}
// Initialize the time dependent variables (maybe I'll put this in the
// constructor later)
void FGTime::init()
void FGTime::init(FGInterface *f)
{
FG_LOG( FG_EVENT, FG_INFO, "Initializing Time" );
gst_diff = -9999.0;
FG_LOG( FG_EVENT, FG_DEBUG,
"time offset = " << current_options.get_time_offset() );
time_t timeOffset = current_options.get_time_offset();
time_t gstStart = current_options.get_start_gst();
time_t lstStart = current_options.get_start_lst();
int offsetType = current_options.get_time_offset_type();
time_t currGMT;
time_t systemLocalTime;
time_t aircraftLocalTime;
// would it be better to put these sanity checks in the options
// parsing code? (CLO)
if (timeOffset && gstStart)
{
FG_LOG( FG_EVENT, FG_ALERT, "Error: you specified both a time offset and a gst. Confused now!" );
current_options.usage();
exit(1);
}
if (timeOffset && lstStart)
{
FG_LOG( FG_EVENT, FG_ALERT, "Error: you specified both a time offset and a lst. Confused now!" );
current_options.usage();
exit(1);
}
if (gstStart && lstStart)
{
FG_LOG( FG_EVENT, FG_ALERT, "Error: you specified both a time offset and a lst. Confused now!" );
current_options.usage();
exit(1);
}
cur_time = time(NULL);
if (gstStart)
warp = gstStart - cur_time;
else if (lstStart) // I need to use the time zone info for this one, but I'll do that later.
// Until then, Gst and LST are the same
{
warp = lstStart - cur_time;
}
else if (timeOffset)
// printf ("Current greenwich mean time = %24s", asctime(gmtime(&cur_time)));
// printf ("Current local time = %24s", asctime(localtime(&cur_time)));
// time_t tmp = cur_time;
GeoCoord location(RAD_TO_DEG * f->get_Latitude(),
RAD_TO_DEG * f->get_Longitude());
GeoCoord* nearestTz = tzContainer->getNearest(location);
FGPath buffer( current_options.get_fg_root() );
buffer.append( "Timezone" );
buffer.append( nearestTz->getDescription() );
// printf("Using %s for timezone information\n", buffer);
zonename = strdup( buffer.c_str() );
show( buffer.c_str(), cur_time, 1);
//printf ("Current greenwich mean time = %24s", asctime(gmtime(&cur_time)));
//printf ("Current local time = %24s", asctime(localtime(&cur_time)));
currGMT = get_gmt(gmtime(&cur_time));
systemLocalTime = get_gmt(localtime(&cur_time));
aircraftLocalTime = get_gmt(fgLocaltime(&cur_time, buffer.c_str()));
//printf ("Current greenwich mean time = %24s", asctime(gmtime(&cur_time)));
//printf ("Current local time = %24s", asctime(localtime(&cur_time)));
//printf("LT = %d\n", computerLocalTime);
// Okay, in principle, this trick allows to calculate the
// difference between GMT and localtime, in seconds.
// printf("Gmt = %d, SLT = %d, (difference = %d)\n", currGMT, systemLocalTime, (currGMT - systemLocalTime));
// printf("Gmt = %d, ALT = %d, (difference = %d)\n", currGMT, aircraftLocalTime, (currGMT - aircraftLocalTime));
// exit(1);
// Okay, we now have six possible scenarios
switch (offsetType)
{
case fgOPTIONS::FG_TIME_SYS_OFFSET:
warp = timeOffset;
break;
case fgOPTIONS::FG_TIME_GMT_OFFSET:
warp = timeOffset - (currGMT - systemLocalTime);
break;
case fgOPTIONS::FG_TIME_LAT_OFFSET:
// warp = timeOffset - (currGMT - systemLocalTime +
// (currGMT - aircraftLocalTime));
warp = timeOffset - (aircraftLocalTime - systemLocalTime);
break;
case fgOPTIONS::FG_TIME_SYS_ABSOLUTE:
warp = timeOffset - cur_time;
//printf("warp = %d\n", warp);
break;
case fgOPTIONS::FG_TIME_GMT_ABSOLUTE:
warp = timeOffset - (currGMT - systemLocalTime) - cur_time;
break;
case fgOPTIONS::FG_TIME_LAT_ABSOLUTE:
warp = timeOffset - (aircraftLocalTime - systemLocalTime) -
cur_time;
break;
default:
printf("Unsupported type\n");
exit(1);
}
else
{
warp = 0;
}
warp_delta = 0;
pause = current_options.get_pause();
}

View file

@ -49,11 +49,18 @@
#include <FDM/flight.hxx>
#include "timezone.h"
#include "lowleveltime.h"
// Define a structure containing global time parameters
class FGTime {
private:
// tzContainer stores all the current Timezone control points/
TimezoneContainer* tzContainer;
//Store the current local timezone name;
char *zonename;
// Unix "calendar" time in seconds
time_t cur_time;
@ -111,7 +118,7 @@ public:
void togglePauseMode() { pause = !pause; };
// Initialize the time dependent variables
void init();
void init(FGInterface *f);
// Update the time dependent variables
void update(FGInterface *f);
@ -127,9 +134,23 @@ public:
// time_t get_start_gmt(int year);
time_t get_gmt(int year, int month, int day,
int hour, int minute, int second);
time_t get_gmt(struct tm* the_time);
char* format_time( const struct tm* p, char* buf );
long int fix_up_timezone( long int timezone_orig );
};
inline time_t FGTime::get_gmt(struct tm* the_time) // this is just a wrapper
{
//printf("Using: %24s as input\n", asctime(the_time));
return get_gmt(the_time->tm_year,
the_time->tm_mon,
the_time->tm_mday,
the_time->tm_hour,
the_time->tm_min,
the_time->tm_sec);
}
#endif // _FG_TIME_HXX

81
src/Time/geocoord.cxx Normal file
View file

@ -0,0 +1,81 @@
/* -*- Mode: C++ -*- *****************************************************
* geocoord.h
* Written by Durk Talsma. Started March 1998.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
**************************************************************************/
/*************************************************************************
*
* This file defines a small and simple class to store geocentric
* coordinates. Basically, class GeoCoord is intended as a base class for
* any kind of of object, that can be categorized according to its
* location on earth, be it navaids, or aircraft. This class for originally
* written for FlightGear, in order to store Timezone control points.
*
************************************************************************/
#include "geocoord.h"
GeoCoord::GeoCoord(const GeoCoord& other)
{
lat = other.lat;
lon = other.lon;
}
double GeoCoord::getAngle(const GeoCoord& other) const
{
Vector first( getX(), getY(), getZ());
Vector secnd(other.getX(), other.getY(), other.getZ());
double
dot = VecDot(first, secnd),
len1 = first.VecLen(),
len2 = secnd.VecLen(),
len = len1 * len2,
angle = 0;
//printf ("Dot: %f, len1: %f len2: %f\n", dot, len1, len2);
/*Vector pPos = prevPos - Reference->prevPos;
Vector pVel = prevVel - Reference->prevVel;*/
if ( ( (dot / len) < 1) && (dot / len > -1) && len )
angle = acos(dot / len);
return angle;
}
GeoCoord* GeoCoordContainer::getNearest(const GeoCoord& ref) const
{
float angle, maxAngle = 180;
GeoCoordVectorConstIterator i, nearest;
for (i = data.begin(); i != data.end(); i++)
{
angle = RAD_TO_DEG * (*i)->getAngle(ref);
if (angle < maxAngle)
{
maxAngle = angle;
nearest = i;
}
}
return *nearest;
}
GeoCoordContainer::~GeoCoordContainer()
{
GeoCoordVectorIterator i = data.begin();
while (i != data.end())
delete *i++;
}

98
src/Time/geocoord.h Normal file
View file

@ -0,0 +1,98 @@
/* -*- Mode: C++ -*- *****************************************************
* geocoord.h
* Written by Durk Talsma. Started July 1999.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
**************************************************************************/
/*************************************************************************
*
* This file defines a small and simple class to store geocentric
* coordinates. Basically, class GeoCoord is intended as a base class for
* any kind of of object, that can be categorized according to its
* location on earth, be it navaids, or aircraft. This class for originally
* written for FlightGear, in order to store Timezone control points.
*
************************************************************************/
#ifndef _GEOCOORD_H_
#define _GEOCOORD_H_
//#include <stl.h>
#include <math.h>
#include <string>
#include <iostream>
//#include <streambuf> // looks like streambuf does not exist on linux.
// But it looks like it isn't used anyways -:)
#include <vector>
using namespace std;
#include "mymath.h"
class GeoCoord
{
protected:
float lat;
float lon;
public:
GeoCoord() { lat = 0.0; lon = 0.0;};
GeoCoord(float la, float lo) { lat = la; lon = lo;};
GeoCoord(const GeoCoord& other);
virtual ~GeoCoord() {};
void set(float la, float lo) { lat = la; lon = lo; };
float getLat() const { return lat; };
float getLon() const { return lon; };
float getX() const { return cos(DEG_TO_RAD*lat) * cos(DEG_TO_RAD*lon); };
float getY() const { return cos(DEG_TO_RAD*lat) * sin(DEG_TO_RAD*lon); };
float getZ() const { return sin(DEG_TO_RAD*lat); };
double getAngle(const GeoCoord& other) const;
virtual void print() {} ;
virtual char *getDescription() {return 0;};
};
typedef vector<GeoCoord*> GeoCoordVector;
typedef vector<GeoCoord*>::iterator GeoCoordVectorIterator;
typedef vector<GeoCoord*>::const_iterator GeoCoordVectorConstIterator;
/************************************************************************
* GeoCoordContainer is a simple container class, that stores objects
* derived from GeoCoord. Basically, it is a wrapper around an STL vector,
* with some added functionality
***********************************************************************/
class GeoCoordContainer
{
protected:
GeoCoordVector data;
public:
GeoCoordContainer() {};
virtual ~GeoCoordContainer();
const GeoCoordVector& getData() const { return data; };
GeoCoord* getNearest(const GeoCoord& ref) const;
};
#endif // _GEO_COORD_H_

1127
src/Time/lowleveltime.cxx Normal file

File diff suppressed because it is too large Load diff

131
src/Time/lowleveltime.h Normal file
View file

@ -0,0 +1,131 @@
/* -*- Mode: C++ -*- *****************************************************
* lowleveltime.h
* Written by various people (I"ll look up the exact credits later)
* Modified by Durk Talsma, July 1999 for use in FlightGear
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
**************************************************************************/
/********************************************************************
* This file redefines some low-level Unix-like time functions for *
* use with FlightGear. Most notably, localtime() is adapted to use *
* a custom timezone, in order to get the 'local' time for a given *
* aircraft's position, and not only for the current location of the*
* computer running the sim. *
* *
* Software adapted from glibc functions, by Durk Talsma. Started *
* July, 17, 1999. *
********************************************************************/
#ifndef _LOWLEVELTIME_H_
#define _LOWLEVELTIME_H_
#include <time.h>
/* adapted from zdump.c */
void show (const char *zone, time_t t, int v);
/* adapted from <time.h> */
struct tm * fgLocaltime (const time_t *t, char *tzName);
/* Prototype for the internal function to get information based on TZ. */
extern struct tm *fgtz_convert (const time_t *t, int use_localtime,
struct tm *tp, char *tzName);
/* This structure contains all the information about a
timezone given in the POSIX standard TZ envariable. */
typedef struct
{
const char *name;
/* When to change. */
enum { J0, J1, M } type; /* Interpretation of: */
unsigned short int m, n, d; /* Month, week, day. */
unsigned int secs; /* Time of day. */
long int offset; /* Seconds east of GMT (west if < 0). */
/* We cache the computed time of change for a
given year so we don't have to recompute it. */
time_t change; /* When to change to this zone. */
int computed_for; /* Year above is computed for. */
} fgtz_rule;
/* tz_rules[0] is standard, tz_rules[1] is daylight. */
static fgtz_rule fgtz_rules[2];
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
char tzh_reserved[16]; /* reserved for future use */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
char tzh_timecnt[4]; /* coded number of transition times */
char tzh_typecnt[4]; /* coded number of local time types */
char tzh_charcnt[4]; /* coded number of abbr. chars */
};
/* Defined in mktime.c. */
extern const unsigned short int mon_yday[2][13];
#ifndef TZDIR
#define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */
#endif /* !defined TZDIR */
#ifndef TZDEFAULT
#define TZDEFAULT "localtime"
#endif /* !defined TZDEFAULT */
#define SECSPERMIN 60
#define MINSPERHOUR 60
#define HOURSPERDAY 24
#define DAYSPERWEEK 7
#define DAYSPERNYEAR 365
#define DAYSPERLYEAR 366
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
#define MONSPERYEAR 12
#define TM_SUNDAY 0
#define TM_MONDAY 1
#define TM_TUESDAY 2
#define TM_WEDNESDAY 3
#define TM_THURSDAY 4
#define TM_FRIDAY 5
#define TM_SATURDAY 6
#define TM_JANUARY 0
#define TM_FEBRUARY 1
#define TM_MARCH 2
#define TM_APRIL 3
#define TM_MAY 4
#define TM_JUNE 5
#define TM_JULY 6
#define TM_AUGUST 7
#define TM_SEPTEMBER 8
#define TM_OCTOBER 9
#define TM_NOVEMBER 10
#define TM_DECEMBER 11
#define TM_YEAR_BASE 1900
#define EPOCH_YEAR 1970
#define EPOCH_WDAY TM_THURSDAY
#endif

371
src/Time/mymath.cxx Executable file
View file

@ -0,0 +1,371 @@
/* -*- Mode: C++ -*- *****************************************************
* mymath.cc
* Written by Durk Talsma, around 1995/1996.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
**************************************************************************/
/********************************************************************
* This file defines a simple Vector and Matrix library. These were
* originally written for my (yet) unpublished planetarium / solar
* system simulator program. The are included here, because I have
* experience the code to calculate angles between vectors. I'm sure
* similar functions exist already somewhere else so I don't mind
* whether this gets eventually replaced by something more suitable
* The functions are based on a description in Tyler. A. (1994). C++
* Real-time 3D graphics. Sigma press, Wilmslow, England.
*
* The original versions were written under windows, hence the occasional
*::MessageBox() statements between conditional compile statements
*
********************************************************************/
#include "mymath.h"
const double PiOver180 = 1.74532925199433E-002;
const double Pix4dif3 = 4.1887902;
Vector::Vector(int size)
{
build(size);
for (int i = 0; i < nrData; i++)
data[i] = 0.00;
}
double Vector::VecLen()
{
double length = 0;
for (int i= 0; i < nrData; i++)
length += powl(data[i],2);
return sqrtl(length);
}
double VecDot(Vector first, Vector second)
{
/*double
result = ((first.xVal*second.xVal) +
(first.yVal*second.yVal) +
(first.zVal*second.zVal));
return result; */
double result = 0;
for (int i = 0; i < first.nrData; i++)
result += first.data[i] * second.data[i];
return result;
}
Vector VecCross(Vector first, Vector second)
{
/*return Vec3 ( (first.yVal*second.zVal - first.zVal*second.yVal),
(first.zVal*second.xVal - first.zVal*second.xVal),
(first.xVal*second.yVal - first.yVal*second.xVal) );
*/
#ifdef DEBUG
if ( (first.nrData != 4) || (first.nrData != second.nrData) )
{
::MessageBox(0, "Attempting to calculate Cross product with 2\n"
"unequally sized vectors in\n"
"Vector VecCross(Vector, Vector", "Error",
MB_OK);
exit(1);
}
#endif
double x = first.data[1] * second.data[2] - first.data[2]*second.data[1];
double y = first.data[2] * second.data[0] - first.data[0]*second.data[2];
double z = first.data[0] * second.data[1] - first.data[1]*second.data[0];
return Vector(x,y,z);
}
Vector operator- (Vector first, Vector second)
{
/*return Vec3( first.xVal - second.xVal,
first.yVal - second.yVal,
first.zVal - second.zVal );
*/
#ifdef DEBUG
if ( first.nrData != second.nrData )
{
::MessageBox(0, "Attempting to subtract 2 \n"
"unequally sized vectors in\n"
"Vector operator-(Vector, Vector", "Error",
MB_OK);
//exit(1);
return Vector(0);
}
#endif
double *temp = new double[first.nrData];
for (int i = 0; i < first.nrData; i++)
temp[i] = first.data[i] - second.data[i];
Vector result(first.nrData, temp);
delete [] temp;
return result;
}
Vector operator+ (Vector first, Vector second)
{
/*return Vec3( first.xVal + second.xVal,
first.yVal + second.yVal,
first.zVal + second.zVal );
*/
#ifdef DEBUG
if ( first.nrData != second.nrData )
{
::MessageBox(0, "Attempting to add 2\n"
"unequally sized vectors in\n"
"Vector operator+(Vector, Vector", "Error",
MB_OK);
exit(1);
}
#endif
double *temp = new double[first.nrData];
for (int i = 0; i < first.nrData; i++)
temp[i] = first.data[i] + second.data[i];
Vector result(first.nrData, temp);
delete [] temp;
return result;
}
Vector Vector::operator +=(Vector other)
{
#ifdef DEBUG
if ( first.nrData != second.nrData )
{
::MessageBox(0, "Attempting to add 2\n"
"unequally sized vectors in\n"
"Vector operator+(Vector, Vector", "Error",
MB_OK);
exit(1);
}
#endif
for (int i = 0; i < nrData; i++)
data[i] += other.data[i];
return *this;
}
Vector Vector::operator -=(Vector other)
{
#ifdef DEBUG
if ( first.nrData != second.nrData )
{
::MessageBox(0, "Attempting to add 2\n"
"unequally sized vectors in\n"
"Vector operator+(Vector, Vector", "Error",
MB_OK);
exit(1);
}
#endif
for (int i = 0; i < nrData; i++)
data[i] -= other.data[i];
return *this;
}
Vector operator* (Matrix mx, Vector vc)
{
int sizes[3];
sizes[0] = vc.nrData;
sizes[1] = mx.rows;
sizes[2] = mx.columns;
#ifdef DEBUG
if ( (sizes[0] != sizes[1]) || (sizes[0] != sizes[2]) )
{
char buffer[50];
sprintf(buffer, "Sizes don't match in function\n"
"Vector operator*(Matrix, Vector)\n"
"sizes are: %d, %d, %d", sizes[0], sizes[1],sizes[2]);
MessageBox(0, buffer, "Error", MB_OK | MB_ICONEXCLAMATION);
exit(1);
}
#endif
double* result = new double[sizes[0]];
int col, row;
for (col = 0; col < sizes[0]; col++)
{
result[col] = 0;
for (row = 0; row < sizes[0]; row++)
result[col] += vc[row] * mx[row][col];
}
Vector res(4, result);
/*
#ifdef DEBUG
char buffer[200];
sprintf(buffer, "return value of vector * matrix multiplication is\n"
"(%f, %f, %f, %f) ", result[0], result[1], result[2], result[3]);
::MessageBox(0, buffer, "Information", MB_OK);
#endif
*/
delete [] result;
return res;
}
Vector operator*(Vector v1, Vector v2)
{
int size1 = v1.nrData;
#ifdef DEBUG
int size2 = v2.nrData;
if(size1 != size2)
{
::MessageBox(0, "Vector sizes don't match in Vector operator*(Vector, Vector)",
"Error", MB_OK);
exit(1);
}
#endif
double *tempRes = new double[size1];
for (int i= 0; i < size1; i++)
tempRes[i] = v1[i] * v2[i];
Vector result(size1, tempRes);
delete tempRes;
return result;
}
Vector operator*(Vector vec, double d)
{
double* tempRes = new double[vec.nrData];
for (int i = 0; i < vec.nrData; i++)
tempRes[i] = vec[i] * d;
Vector result(vec.nrData, tempRes);
delete tempRes;
return result;
}
Vector operator/(Vector vec, double d)
{
double* tempRes = new double[vec.nrData];
for (int i = 0; i < vec.nrData; i++)
tempRes[i] = vec[i] / d;
Vector result(vec.nrData, tempRes);
delete tempRes;
return result;
}
ostream& operator << (ostream& os, Vector& vec)
{
os << /*setw(4) << */vec.nrData << '\t';
for (int i = 0; i < vec.nrData; i++)
os /*<< setw(25) */<< vec[i] << '\t';
return os;
}
istream& operator >> (istream& is, Vector& vec)
{
is >> vec.nrData;
if (vec.data)
delete [] vec.data;
vec.data = new double[vec.nrData];
for (int i = 0; i < vec.nrData; i++)
is >> vec.data[i];
return is;
}
ostream& Vector::binSave(ostream& os)
{
os.write((char*) &nrData, sizeof(int));
os.write((char*) data, nrData* sizeof(double));
return os;
}
/******************************************************************************
Matrix manipulation routines
******************************************************************************/
Matrix::Matrix(int r, int c, double*dta)
{
build(r,c);
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
data[i][j] = (*dta++);
}
Matrix::Matrix(int r, int c, double** dta)
{
build(r,c);
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
data[i][j] = dta[i][j];
}
Matrix::Matrix(int r, int c, Vector* dta)
{
build(r,c);
for (int i = 0; i < rows; i++)
data[i] = dta[i];
}
Matrix::Matrix(Matrix& other)
{
build (other.rows, other.columns);
for (int i = 0; i< rows; i++)
(*this)[i] = other[i];
}
void Matrix::build(int row, int col)
{
rows = row;
columns = col;
data = new Vector [rows];
for (int i = 0; i < rows; i++)
data[i].build(col);
}
Matrix& Matrix::operator =(Matrix& other)
{
rows = other.rows;
columns = other.columns;
for (int i = 0; i < rows; i++)
(*this)[i] = other[i];
return *this;
}
Vector Matrix::operator ()(int col)
{
Vector Col(rows);
for (int i = 0; i < rows; i++)
Col[i] = data[i][col];
return Col;
}
void Matrix::norm(int scale)
{
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
data[i][j] /= scale;
}

454
src/Time/mymath.h Executable file
View file

@ -0,0 +1,454 @@
/* -*- Mode: C++ -*- *****************************************************
* mymath.h
* Written by Durk Talsma, around 1995/1996.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
**************************************************************************/
/********************************************************************
* This file defines a simple Vector and Matrix library. These were
* originally written for my (yet) unpublished planetarium / solar
* system simulator program. The are included here, because I have
* experience the code to calculate angles between vectors. I'm sure
* similar functions exist already somewhere else so I don't mind
* whether this gets eventually replaced by something more suitable
* The functions are based on a description in Tyler. A. (1994). C++
* Real-time 3D graphics. Sigma press, Wilmslow, England.
*
* The original versions were written under windows, hence the occasional
*::MessageBox() statements between conditional compile statements
*
********************************************************************/
#ifndef _MY_MATH_H_
#define _MY_MATH_H__
#include <math.h>
#include <fstream>
#include <iomanip>
using namespace std;
#include <fg_constants.h>
extern const double PiOver180;
extern const double Pix4dif3;
class Matrix;
class Vector
{
private:
int nrData;
double* data;
public:
Vector();
Vector(int size);
Vector(int size, double* dta);
Vector(double x, double y, double z);
Vector(Vector& other);
Vector(istream& is);
~Vector();
void SetVal(double x, double y, double z);
void build(int);
Vector* GetVector();
double GetX();
double GetY();
double GetZ();
void AddX(double x);
void AddY(double y);
void AddZ(double z);
void SubtractX(double x);
void SubtractY(double y);
void SubtractZ(double z);
double VecLen();
Vector& operator = (Vector&);
double& operator[] (int);
int getDim();
ostream& binSave(ostream& os);
Vector operator +=(Vector other);
Vector operator -=(Vector other);
friend double VecDot(Vector first, Vector second);
friend Vector VecCross(Vector first, Vector second);
friend Vector operator-(Vector first, Vector second);
friend Vector operator+(Vector first, Vector second);
friend Vector operator*(Matrix mx, Vector vc);
friend Vector operator*(Vector v1, Vector v2);
friend Vector operator*(Vector vec, double d);
friend Vector operator/(Vector vec, double d);
friend ostream& operator << (ostream& os, Vector& vec);
friend istream& operator >> (istream& is, Vector& vec);
};
/*-----------------------------------------------------------------------------
nonmember friend functions
------------------------------------------------------------------------------*/
double VecDot(Vector first, Vector second);
Vector VecCross(Vector first, Vector second);
Vector operator-(Vector first, Vector second);
Vector operator+(Vector first, Vector second);
Vector operator*(Matrix mx, Vector vc);
Vector operator*(Vector v1, Vector v2);
Vector operator*(Vector vec, double d);
Vector operator/(Vector vec, double d);
ostream& operator << (ostream& os, Vector& vec);
istream& operator >> (istream& is, Vector& vec);
/*------------------------------------------------------------------------------
inline member functions
------------------------------------------------------------------------------*/
inline Vector::Vector()
{
nrData = 0;
data = 0;
}
inline void Vector::build(int size)
{
nrData = size;
data = new double[nrData];
#ifdef DEBUG
if (!data)
{
::MessageBox(0, "Error Allocating Memory for a new Vector", "Error",
MB_OK);
exit(1);
}
#endif
//for (int i = 0; i < nrData; i++)
// data[i] = 0.00;
}
inline Vector::Vector(int size, double* dta)
{
build(size);
memcpy(data, dta, nrData*sizeof(double));
}
inline Vector::Vector(Vector& other)
{
build(other.nrData);
memcpy(data,other.data,nrData*sizeof(double));
}
inline Vector::Vector(double x, double y, double z)
{
build(4); // one extra for matrix multiplication...
data[0] = x;
data[1] = y;
data[2] = z;
data[3] = 0.00;
}
inline Vector::Vector(istream& is)
{
is.read((char*) &nrData, sizeof(int));
data = new double[nrData];
is.read((char*) data, nrData * sizeof(double));
}
inline Vector::~Vector()
{
delete [] data;
}
inline void Vector::SetVal(double x, double y, double z)
{
#ifdef DEBUG
if (nrData != 4)
{
::MessageBox(0, "Attempt to assign data to a vector\n"
"With size unequal to 4 in function\n"
" Vector::Setval(double, double, double", "Error" , MB_OK);
exit(1);
}
#endif
data[0] = x,
data[1] = y;
data[2] = z;
data[3] = 0.00;
}
inline Vector* Vector::GetVector()
{
return this;
}
inline double Vector::GetX()
{
#ifdef DEBUG
if (nrData < 1)
{
::MessageBox(0, "Attempt to retrieve x-value of a vector\n"
"With size smaller than 1 in function\n"
" Vector::GetX();", "Error", MB_OK);
exit(1);
}
#endif
return data[0];
}
inline double Vector::GetY()
{
#ifdef DEBUG
if (nrData < 2)
{
::MessageBox(0, "Attempt to retrieve the y value of a vector\n"
"With size smaller than 2 in function\n"
" Vector::GetY();", "Error", MB_OK);
exit(1);
}
#endif
return data[1];
}
inline double Vector::GetZ()
{
#ifdef DEBUG
if (nrData < 3)
{
::MessageBox(0, "Attempt to retrieve the z value of a vector\n"
"With size smaller than 2 in function\n"
" Vector::GetZ();", "Error", MB_OK);
exit(1);
}
#endif
return data[2];
}
inline void Vector::AddX(double x)
{
#ifdef DEBUG
if (nrData < 1)
{
::MessageBox(0, "Attempt to chance x-value to a vector\n"
"With size smaller than 1 in function\n"
" Vector::AddX(double);", "Error", MB_OK);
exit(1);
}
#endif
data[0] += x;
}
inline void Vector::AddY(double y)
{
#ifdef DEBUG
if (nrData < 2)
{
::MessageBox(0, "Attempt to chance y-value to a vector\n"
"With size smaller than 2 in function\n"
" Vector::AddY(double);", "Error", MB_OK);
exit(1);
}
#endif
data[1] += y;
}
inline void Vector::AddZ(double z)
{
#ifdef DEBUG
if (nrData < 3)
{
::MessageBox(0, "Attempt to chance z-value to a vector\n"
"With size smaller than 3 in function\n"
" Vector::AddZ(double);", "Error", MB_OK);
exit(1);
}
#endif
data[2] += z;
}
inline void Vector::SubtractX(double x)
{
#ifdef DEBUG
if (nrData < 1)
{
::MessageBox(0, "Attempt to chance x-value to a vector\n"
"With size smaller than 1 in function\n"
" Vector::SubtractX(double);", "Error", MB_OK);
exit(1);
}
#endif
data[0] -= x;
}
inline void Vector::SubtractY(double y)
{
#ifdef DEBUG
if (nrData < 2)
{
::MessageBox(0, "Attempt to chance y-value to a vector\n"
"With size smaller than 2 in function\n"
" Vector::SubractY(double);", "Error", MB_OK);
exit(1);
}
#endif
data[1] -= y;
}
inline void Vector::SubtractZ(double z)
{
#ifdef DEBUG
if (nrData < 3)
{
::MessageBox(0, "Attempt to chance z-value to a vector\n"
"With size smaller than 3 in function\n"
" Vector::SubtractZ(double);", "Error", MB_OK);
exit(1);
}
#endif
data[2] -= z;
}
inline Vector& Vector::operator= (Vector& other)
{
if (data)
delete[] data;
build(other.nrData);
memcpy(data, other.data, nrData*sizeof(double));
return *this;
}
inline double& Vector::operator [](int index)
{
return *(data+index);
}
inline int Vector::getDim()
{
return nrData;
}
/*-----------------------------------------------------------------------------
Some generic conversion routines
------------------------------------------------------------------------------*/
float CosD(float angle);
float SinD(float angle);
float Radians(float angle);
int Round(float value);
/* ----------------------------------------------------------------------------
And their inlined implementation
------------------------------------------------------------------------------*/
inline float CosD(float angle)
{
return cos(Radians(angle));
}
inline float SinD(float angle)
{
return(Radians(angle));
}
inline float Radians(float angle)
{
return (angle*PiOver180);
}
inline int Round(float value)
{
return ( (int) (value+0.5));
}
/******************************************************************************
Matrix class
******************************************************************************/
class Matrix
{
protected:
int rows;
int columns;
Vector* data;
public:
Matrix();
Matrix(int r, int c);
Matrix(int r, int c, double* dta);
Matrix(int r, int c, double** dta);
Matrix(int r, int c, Vector*dta);
Matrix(Matrix&);
~Matrix();
void build(int r, int c);
Matrix& operator=(Matrix&);
Vector& operator[](int);
Vector operator ()(int);
int getrows();
int getcols();
void norm(int scal);
friend Vector operator*(Matrix mc, Vector vc);
};
/*------------------------------------------------------------------------------
inline Matrix routines
------------------------------------------------------------------------------*/
inline Matrix::Matrix()
{
rows = 0;
columns = 0;
data = 0;
}
inline Matrix::Matrix(int r, int c)
{
build(r, c);
}
inline Matrix::~Matrix()
{
delete [] data;
}
inline Vector& Matrix::operator[] (int row)
{
return data[row];
}
#endif // _MYMATH_H_

147
src/Time/timezone.cxx Normal file
View file

@ -0,0 +1,147 @@
/* -*- Mode: C++ -*- *****************************************************
* timezone.cc
* Written by Durk Talsma. Started July 1999.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
**************************************************************************/
/*************************************************************************
*
* Timezone is derived from geocoord, and stores the timezone centerpoint,
* as well as the countrycode and the timezone descriptor. The latter is
* used in order to get the local time.
*
************************************************************************/
#include <stdio.h>
#include "timezone.h"
Timezone::Timezone(float la, float lo, char* cc, char* desc) :
GeoCoord(la, lo)
{
countryCode = strdup(cc);
descriptor = strdup(desc);
}
/* Build a timezone object from a textline in zone.tab */
Timezone::Timezone(const char *infoString) :
GeoCoord()
{
int i = 0;
while (infoString[i] != '\t')
i++;
char buffer[128];
char latlon[128];
strncpy(buffer, infoString, i);
buffer[i] = 0;
countryCode = strdup(buffer);
i ++;
int start = i;
while (infoString[i] != '\t')
i++;
int size = i - start;
strncpy(latlon, (&infoString[start]), size);
latlon[size] = 0;
char sign;
sign = latlon[0];
strncpy(buffer, &latlon[1], 2);
lat = atof(buffer);
strncpy(buffer, &latlon[3], 2);
lat += (atof(buffer) / 60);
int nextPos;
if (strlen(latlon) > 12)
{
nextPos = 7;
strncpy(buffer, &latlon[5], 2);
lat += (atof(buffer) / 3600.0);
}
else
nextPos = 5;
if (sign == '-')
lat = -lat;
sign = latlon[nextPos];
nextPos++;
strncpy(buffer, &latlon[nextPos], 3);
lon = atof(buffer);
nextPos += 3;
strncpy(buffer, &latlon[nextPos], 2);
buffer[2] = 0;
lon += (atof(buffer) / 60);
if (strlen(latlon) > 12)
{
nextPos += 2;
strncpy(buffer, &latlon[nextPos], 2);
lon += (atof (buffer) / 3600.00);
}
if (sign == '-')
lon = -lon;
i ++;
start = i;
while (!((infoString[i] == '\t') || (infoString[i] == '\n')))
i++;
size = i - start;
strncpy(buffer, (&infoString[start]), size);
buffer[size] = 0;
descriptor = strdup(buffer);
}
/* the copy constructor */
Timezone::Timezone(const Timezone& other)
{
lat = other.getLat();
lon = other.getLon();
countryCode = strdup(other.countryCode);
descriptor = strdup(other.descriptor);
}
/********* Member functions for TimezoneContainer class ********/
TimezoneContainer::TimezoneContainer(const char *filename)
{
char buffer[256];
FILE* infile = fopen(filename, "r");
if (!(infile))
{
fprintf(stderr, "Unable to open file %s\n", filename);
exit(1);
}
else
{
while (1)
{
fgets(buffer, 256, infile);
if (feof(infile))
break;
for (int i = 0; i < 256; i++)
{
if (buffer[i] == '#')
buffer[i] = 0;
}
if (buffer[0])
{
data.push_back(new Timezone(buffer));
}
}
}
}
TimezoneContainer::~TimezoneContainer()
{
}

72
src/Time/timezone.h Normal file
View file

@ -0,0 +1,72 @@
/* -*- Mode: C++ -*- *****************************************************
* timezone.h
* Written by Durk Talsma. Started July 1999.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
**************************************************************************/
/*************************************************************************
*
* Timezone is derived from geocoord, and stores the timezone centerpoint,
* as well as the countrycode and the timezone descriptor. The latter is
* used in order to get the local time.
*
************************************************************************/
#ifndef _TIMEZONE_H_
#define _TIMEZONE_H_
#include "geocoord.h"
#include <stdio.h>
class Timezone : public GeoCoord
{
private:
char* countryCode;
char* descriptor;
public:
Timezone() :
GeoCoord()
{
countryCode = 0;
descriptor = 0;
};
Timezone(float la, float lo, char* cc, char* desc);
Timezone(const char *infoString);
Timezone(const Timezone &other);
virtual ~Timezone() { delete [] countryCode; delete [] descriptor; };
virtual void print() { printf("%s", descriptor);};
virtual char * getDescription() { return descriptor; };
};
/************************************************************************
* Timezone container is derived from GeoCoordContainer, and has some
* added functionality.
************************************************************************/
class TimezoneContainer : public GeoCoordContainer
{
public:
TimezoneContainer(const char *filename);
virtual ~TimezoneContainer();
};
#endif // _TIMEZONE_H_