#ifndef __DSC_H #define __DSC_H typedef unsigned long DWORD; typedef unsigned char BYTE; class Vector { public: double x, y, z; static Vector MakeFrom(double x, double y, double z); Vector Plus(Vector b); Vector Minus(Vector b); Vector Negated(void); Vector Cross(Vector b); double Dot(Vector b); Vector Normal(int which); Vector RotatedAbout(Vector axis, double theta); double Magnitude(void); Vector WithMagnitude(double s); Vector ScaledBy(double s); // Call a rotation matrix [ u' v' n' ]'; this returns the first and // second rows, where that matrix is generated by the given quaternion // a + bi + cj + dk static Vector RotationU(double a, double b, double c, double d); static Vector RotationV(double a, double b, double c, double d); }; class Point2d { public: double x, y; Point2d Plus(Point2d b); Point2d Minus(Point2d b); Point2d ScaledBy(double s); double DistanceTo(Point2d p); double DistanceToLine(Point2d p0, Point2d dp, bool segment); }; template class IdList { public: T *elem; int elems; int elemsAllocated; H AddAndAssignId(T *t) { int i; DWORD id = 0; for(i = 0; i < elems; i++) { id = max(id, elem[i].h.v); } t->h.v = (id + 1); Add(t); return t->h; } void Add(T *t) { if(elems >= elemsAllocated) { elemsAllocated = (elemsAllocated + 32)*2; elem = (T *)MemRealloc(elem, elemsAllocated*sizeof(elem[0])); if(!elem) oops(); } elem[elems] = *t; elems++; } T *FindById(H h) { T *t = FindByIdNoOops(h); if(!t) { dbp("failed to look up item %16lx, searched %d items", h.v, elems); oops(); } return t; } T *FindByIdNoOops(H h) { int i; for(i = 0; i < elems; i++) { if(elem[i].h.v == h.v) { return &(elem[i]); } } return NULL; } void ClearTags(void) { int i; for(i = 0; i < elems; i++) { elem[i].tag = 0; } } void Tag(H h, int tag) { int i; for(i = 0; i < elems; i++) { if(elem[i].h.v == h.v) { elem[i].tag = tag; } } } void RemoveTagged(void) { int src, dest; dest = 0; for(src = 0; src < elems; src++) { if(elem[src].tag) { // this item should be deleted } else { if(src != dest) { elem[dest] = elem[src]; } dest++; } } elems = dest; // and elemsAllocated is untouched, because we didn't resize } void MoveSelfInto(IdList *l) { memcpy(l, this, sizeof(*this)); elemsAllocated = elems = 0; elem = NULL; } void Clear(void) { elemsAllocated = elems = 0; if(elem) free(elem); elem = NULL; } }; class NameStr { public: char str[20]; inline void strcpy(char *in) { memcpy(str, in, min(strlen(in)+1, sizeof(str))); str[sizeof(str)-1] = '\0'; } }; #endif