// Vektor-Grundfunktionen fr TVector (c) Daniel Lichtenberger, 2/97


typedef struct {
 int x,y,z;
} TVector;

typedef struct {
 double x,y,z;
} TVector_Real;

typedef struct {
 short int x,y;
} TVector2D;

void ClearVector(TVector& v) {
 v.x = v.y = v.z = 0;
}

void NegVector(TVector& v) {
 v.x = -v.x;
 v.y = -v.y;
 v.z = -v.z;
}

void NegVector2D(TVector2D& v) {
 v.x = -v.x;
 v.y = -v.y;
}

void ClearVector2D(TVector2D& v) {
 v.x = v.y = 0;
}

int Wurzel(int z) {
int z2,erg;
 if (z <= 0) return(0);
 erg = z;
 do {
  z2 = erg;
  erg = (erg + z/z2) >> 1;
 } while (z2-erg > 1);
 return(erg);
}

void SetVector(int x,int y,int z,TVector *v) {
 v->x = x;
 v->y = y;
 v->z = z;
}

void CopyVector(TVector v1,TVector *v2) {
 v2->x = v1.x;
 v2->y = v1.y;
 v2->z = v1.z;
}

void CopyVector2D(TVector2D v1,TVector2D *v2) {
 v2->x = v1.x;
 v2->y = v1.y;
}

/* -------------------- TVector2D-Operator-Overrides */

TVector2D operator+(TVector2D t1,TVector2D t2) {
 TVector2D tmp;

 tmp.x = t1.x+t2.x;
 tmp.y = t1.y+t2.y;
 return tmp;
}

TVector2D operator-(TVector2D t1,TVector2D t2) {
 TVector2D tmp;

 tmp.x = t1.x-t2.x;
 tmp.y = t1.y-t2.y;
 return tmp;
}

TVector2D operator*(TVector2D t1,int c) {
 TVector2D tmp;

 tmp.x = t1.x*c;
 tmp.y = t1.y*c;
 return tmp;
}

/* -------------------- TVector-Operator-Overrides */

TVector operator+(TVector t1,TVector t2) {
 TVector tmp;

 tmp.x = t1.x+t2.x;
 tmp.y = t1.y+t2.y;
 tmp.z = t1.z+t2.z;
 return tmp;
}

TVector operator-(TVector t1,TVector t2) {
 TVector tmp;

 tmp.x = t1.x-t2.x;
 tmp.y = t1.y-t2.y;
 tmp.z = t1.z-t2.z;
 return tmp;
}

TVector operator/(TVector t1,int c) {
 TVector tmp;

 if (!c) {
  ClearVector(tmp);
  return tmp;
 }
 tmp.x = t1.x/c;
 tmp.y = t1.y/c;
 tmp.z = t1.z/c;
 return tmp;
}

TVector operator*(TVector t1,int c) {
 TVector tmp;

 tmp.x = t1.x*c;
 tmp.y = t1.y*c;
 tmp.z = t1.z*c;
 return tmp;
}

TVector operator>>(TVector t1,char rshift) {
 TVector tmp;

 tmp.x = t1.x >> rshift;
 tmp.y = t1.y >> rshift;
 tmp.z = t1.z >> rshift;
 return tmp;
}

TVector operator<<(TVector t1,char lshift) {
 TVector tmp;

 tmp.x = t1.x << lshift;
 tmp.y = t1.y << lshift;
 tmp.z = t1.z << lshift;
 return tmp;
}

void KreuzProdukt(TVector v1,TVector v2,TVector* v3) {
 v3->x = v1.y*v2.z-v2.y*v1.z;
 v3->y = -(v1.x*v2.z-v2.x*v1.z);
 v3->z = v1.x*v2.y-v2.x*v1.y;
}

int Betrag(TVector v) {
 int pyth;
 pyth = v.x*v.x+v.y*v.y+v.z*v.z;
 if (pyth > 0)
  return((int)sqrt(pyth));
 else return(1);
}

int CalcAngle(TVector v1,TVector v2) {  // Rckgabe als Arcuscosinus, mit fakt multipliziert

 return((int)((float)(v1.x*v2.x+v1.y*v2.y+v1.z*v2.z)/(Betrag(v1)*Betrag(v2))*fakt));
}

int CalcAngle2(TVector v1,TVector v2,int betrag1,int betrag2) {  
 if ((!betrag1) || (!betrag2)) return(0);
 return(((v1.x*v2.x+v1.y*v2.y+v1.z*v2.z) << faktshift)/(betrag1*betrag2));
}

/* --------------- TVector_Real-Operator-Overrides */

TVector_Real operator+(TVector_Real t1,TVector_Real t2) {
 TVector_Real tmp;

 tmp.x = t1.x+t2.x;
 tmp.y = t1.y+t2.y;
 tmp.z = t1.z+t2.z;
 return tmp;
}

TVector_Real operator-(TVector_Real t1,TVector_Real t2) {
 TVector_Real tmp;

 tmp.x = t1.x-t2.x;
 tmp.y = t1.y-t2.y;
 tmp.z = t1.z-t2.z;
 return tmp;
}

TVector_Real operator/(TVector_Real t1,double c) {
 TVector_Real tmp;
 if (c == 0) return tmp;
 tmp.x = t1.x/c;
 tmp.y = t1.y/c;
 tmp.z = t1.z/c;
 return tmp;
}

TVector_Real operator*(TVector_Real t1,double c) {
 TVector_Real tmp;

 tmp.x = t1.x*c;
 tmp.y = t1.y*c;
 tmp.z = t1.z*c;
 return tmp;
}

void KreuzProdukt_Real(TVector_Real v1,TVector_Real v2,TVector_Real* v3) {
 v3->x = v1.y*v2.z-v2.y*v1.z;
 v3->y = -(v1.x*v2.z-v2.x*v1.z);
 v3->z = v1.x*v2.y-v2.x*v1.y;
}

double Betrag_Real(TVector_Real v) {
double pyth;
 pyth = v.x*v.x+v.y*v.y+v.z*v.z;
 if (pyth != 0) return(sqrt(pyth));
 else return(1);
}

void v_RotateX(TVector v1,int rotangle,TVector *v2) {
TVector v;
int mycos,mysin;
 mycos = costable[rotangle];
 mysin = sintable[rotangle];
 v2->x = v1.x;
 v2->y = ((v1.y*mycos) - (v1.z*mysin)) >> faktshift;
 v2->z = ((v1.y*mysin) + (v1.z*mycos)) >> faktshift;
}

void v_RotateY(TVector v1,int rotangle,TVector& v2) {
TVector v;
int mycos,mysin;
 mycos = costable[rotangle];
 mysin = sintable[rotangle];
 v2.x = ((v1.x*mycos) + (v1.z*mysin)) >> faktshift;
 v2.y = v1.y;
 v2.z = (-(v1.x*mysin) + (v1.z*mycos)) >> faktshift;
}

void v_RotateZ(TVector v1,int rotangle,TVector *v2) {
TVector v;
int mycos,mysin;
 mycos = costable[rotangle];
 mysin = sintable[rotangle];
 v2->x = ((v1.x*mycos) - (v1.y*mysin)) >> faktshift;
 v2->y = ((v1.x*mysin) + (v1.y*mycos)) >> faktshift;
 v2->z = v1.z;
}

#if 0
 
void v_RotateXYZ(TVector v1,int a,int b,int c,TVector *v2) { // Der Vektor wird um alle 3 Achsen gleichzeitig rotiert, a = Winkel x-Achse, b: y-Achse, c: z-Achse

int sinx,cosx,siny,cosy,sinz,cosz,i,j;
 sinx = sintable[a]; cosx = costable[a];
 siny = sintable[b]; cosy = costable[b];
 sinz = sintable[c]; cosz = costable[c];
 v2->x = (v1.x*((cosy*cosz) >> (faktshift*2)) + v1.y*((sinx*siny*cosz)-cosx*sinz)) >> (faktshift*3) + (v1.z*(cosx*siny*cosz+sinx*sinz)) >> faktshift;

 v2->x = v1.x*((cosy*cosz) >> (faktshift*2));
 i = (((sinx*siny) >> (faktshift*2))*cosz)>>faktshift - (cosx*sinz) >> (faktshift*2);
 v2->x += v1.x*i;
 i = 

 v2->y = (v1.x*(cosy*sinz
}
#endif