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