1 #ifndef QUADRIC_HXX
  2 #define QUADRIC_HXX
  3 
  4 #include "Primitive.hxx"
  5 #include "Box.hxx"
  6 
  7 class Quadric : public Primitive
  8 {
  9 	float a, b, c, d, e, f, g, h, i, j,
 10 	      alpha, beta, gamma, p, radicand, t[2];
 11 	int   num;
 12 public:
 13 	Quadric(float a, float b, float c, float d, float e, float f, float g, 
 14 	        float h, float i, float j, Shader *shader, PhotonDistributor *photon_distributor)
 15 		: Primitive(shader, photon_distributor),a(a),b(b),c(c),d(d),e(e),f(f),g(g),h(h),i(i),j(j)
 16 	{};
 17 
 18 	virtual ~Quadric(){};
 19 
 20 	virtual bool Intersect(Ray &ray)
 21 	{
 22 		alpha =       a * ray.dir.x * ray.dir.x
 23 		      +       b * ray.dir.y * ray.dir.y
 24 		      +       c * ray.dir.z * ray.dir.z
 25 		      +       d * ray.dir.x * ray.dir.y
 26 		      +       e * ray.dir.x * ray.dir.z
 27 		      +       f * ray.dir.y * ray.dir.z;
 28 
 29 		beta  = 2.0 * a * ray.org.x * ray.dir.x
 30 		      + 2.0 * b * ray.org.y * ray.dir.y
 31 		      + 2.0 * c * ray.org.z * ray.dir.z
 32 		      +       d * ray.org.x * ray.dir.y
 33 		      +       d * ray.org.y * ray.dir.x
 34 		      +       e * ray.org.x * ray.dir.z
 35 		      +       e * ray.org.z * ray.dir.x
 36 		      +       f * ray.org.y * ray.dir.z
 37 		      +       f * ray.org.z * ray.dir.y
 38 		      +       g *             ray.dir.x
 39 		      +       h *             ray.dir.y
 40 		      +       i *             ray.dir.z;
 41 
 42 		gamma =       a * ray.org.x * ray.org.x
 43 		      +       b * ray.org.y * ray.org.y
 44 		      +       c * ray.org.z * ray.org.z
 45 		      +       d * ray.org.x * ray.org.y
 46 		      +       e * ray.org.x * ray.org.z
 47 		      +       f * ray.org.y * ray.org.z
 48 		      +       g * ray.org.x
 49 		      +       h * ray.org.y
 50 		      +       i * ray.org.z
 51  		      +       j;
 52 
 53 		// Apply the p-q-Formula:
 54 		p        = beta / (2.0 * alpha);
 55 		radicand = p * p - gamma / alpha;
 56 
 57 		if (radicand >= 0.0)
 58 		{
 59 			// We have two solutions. The Sqrt is only calculated once:
 60 			radicand = sqrt(radicand);
 61 			t[0]     = -p + radicand;
 62 			t[1]     = -p - radicand;
 63 
 64 			// Check the closer intersection point and take it if necessary
 65 			num = t[1] < t[0];
 66 			if (t[num] < ray.t && t[num] > Epsilon)
 67 			{
 68 				ray.t = t[num];
 69 				ray.hit = this;
 70 				return true;
 71 			}
 72 
 73 			// Check the farer intersection point and take it if necessary
 74 			num = !num;
 75 			if (t[num] < ray.t && t[num] > Epsilon)
 76 			{
 77 				ray.t = t[num];
 78 				ray.hit = this;
 79 				return true;
 80 			}
 81 		}
 82 
 83 		// We could not find any intersection point
 84 		return false;
 85 	};
 86 
 87 	virtual Vec3f GetNormal(Ray &ray)
 88 	{
 89 		Vec3f p      = ray.org + ray.t * ray.dir;
 90 		Vec3f normal = Vec3f(2 * a * p.x + d * p.y + e * p.z + g,
 91 		                     2 * b * p.y + d * p.x + f * p.z + h,
 92 		                     2 * c * p.z + e * p.x + f * p.y + i);
 93 		Normalize(normal);
 94 		return normal;
 95 	};
 96 
 97 	virtual Box CalcBounds()
 98 	{
 99 		// Return real bounding boxes later on (TODO)
100 		return Box();
101 	}
102 };
103 
104 #endif


syntax highlighted by Code2HTML, v. 0.9.1