00001 /*
00002 File: Vec4.cc
00003
00004 Function: Implements Vec4.h
00005
00006 Author(s): Andrew Willmott
00007
00008 Copyright: (c) 1995-2000, Andrew Willmott
00009
00010 Notes:
00011
00012 */
00013
00014
00015 #include "vl/Vec4.h"
00016 #include <ctype.h>
00017 #include <iomanip.h>
00018
00019
00020 TVec4 &TVec4::MakeUnit(Int n, TVReal k)
00021 {
00022 if (n == 0)
00023 { elt[0] = k; elt[1] = vl_zero; elt[2] = vl_zero; elt[3] = vl_zero; }
00024 else if (n == 1)
00025 { elt[0] = vl_zero; elt[1] = k; elt[2] = vl_zero; elt[3] = vl_zero; }
00026 else if (n == 2)
00027 { elt[0] = vl_zero; elt[1] = vl_zero; elt[2] = k; elt[3] = vl_zero; }
00028 else if (n == 3)
00029 { elt[0] = vl_zero; elt[1] = vl_zero; elt[2] = vl_zero; elt[3] = k; }
00030 else
00031 _Error("(Vec4::MakeUnit) illegal unit vector");
00032
00033 return(SELF);
00034 }
00035
00036 Bool TVec4::operator == (const TVec4 &a) const
00037 {
00038 return(elt[0] == a[0] && elt[1] == a[1] && elt[2] == a[2] && elt[3] == a[3]);
00039 }
00040
00041 Bool TVec4::operator != (const TVec4 &a) const
00042 {
00043 return(elt[0] != a[0] || elt[1] != a[1] || elt[2] != a[2] || elt[3] != a[3]);
00044 }
00045
00046 TVec4 cross(const TVec4 &a, const TVec4 &b, const TVec4 &c)
00047 {
00048 TVec4 result;
00049 // XXX can this be improved? Look at assembly.
00050 #define ROW(i) a[i], b[i], c[i]
00051 #define DET(i,j,k) dot(TVec3(ROW(i)), cross(TVec3(ROW(j)), TVec3(ROW(k))))
00052
00053 result[0] = DET(1,2,3);
00054 result[1] = -DET(0,2,3);
00055 result[2] = DET(0,1,3);
00056 result[3] = -DET(0,1,2);
00057
00058 return(result);
00059
00060 #undef ROW
00061 #undef DET
00062 }
00063
00064 TVec3 proj(const TVec4 &v)
00065 {
00066 TVec3 result;
00067
00068 Assert(v[3] != 0, "(Vec4/proj) last elt. is zero");
00069
00070 result[0] = v[0] / v[3];
00071 result[1] = v[1] / v[3];
00072 result[2] = v[2] / v[3];
00073
00074 return(result);
00075 }
00076
00077
00078 ostream &operator << (ostream &s, const TVec4 &v)
00079 {
00080 Int w = s.width();
00081
00082 return(s << '[' << v[0] << ' ' << setw(w) << v[1] << ' '
00083 << setw(w) << v[2] << ' ' << setw(w) << v[3] << ']');
00084 }
00085
00086 istream &operator >> (istream &s, TVec4 &v)
00087 {
00088 TVec4 result;
00089 Char c;
00090
00091 // Expected format: [1 2 3 4]
00092
00093 while (s >> c && isspace(c))
00094 ;
00095
00096 if (c == '[')
00097 {
00098 s >> result[0] >> result[1] >> result[2] >> result[3];
00099
00100 if (!s)
00101 {
00102 cerr << "Error: Expected number while reading vector\n";
00103 return(s);
00104 }
00105
00106 while (s >> c && isspace(c))
00107 ;
00108
00109 if (c != ']')
00110 {
00111 s.clear(ios::failbit);
00112 cerr << "Error: Expected ']' while reading vector\n";
00113 return(s);
00114 }
00115 }
00116 else
00117 {
00118 s.clear(ios::failbit);
00119 cerr << "Error: Expected '[' while reading vector\n";
00120 return(s);
00121 }
00122
00123 v = result;
00124 return(s);
00125 }
00126