diff --git a/raytrace.cpp b/raytrace.cpp
index 192ee6567d42ae93987b8979b347609f952d5a4e..3e172b939908dfca7ce43765c01f7adf3723a6af 100644
--- a/raytrace.cpp
+++ b/raytrace.cpp
@@ -3,6 +3,15 @@
 //=============================================================================================
 #include "framework.h"
 
+mat4 TMatrix4(mat4 m) {
+    return mat4(
+            m.rows[0].x, m.rows[1].x, m.rows[2].x, m.rows[3].x,
+            m.rows[0].y, m.rows[1].y, m.rows[2].y, m.rows[3].y,
+            m.rows[0].z, m.rows[1].z, m.rows[2].z, m.rows[3].z,
+            m.rows[0].w, m.rows[1].w, m.rows[2].w, m.rows[3].w
+        );
+}
+
 enum MaterialType {
     ROUGH, REFLECTIVE
 };
@@ -100,11 +109,35 @@ struct Quadric : public Intersectable {
 
     virtual vec3 gradf(vec4 r) { //r.w = 1
         vec4 g = r * Q * 2;
-        return vec3(g.x, g.y, g.z);
+        return normalize(vec3(g.x, g.y, g.z));
+    }
+
+    void Translate(vec3 t) {
+        mat4 m = TranslateMatrix(-1 * t); //inverse matrix of the transformation
+        Q = m * Q * TMatrix4(m);
+    }
+
+    void Translate(float x, float y, float z) {
+        Translate(vec3(x, y, z));
+    }
+
+    void Scale(vec3 s) {
+        mat4 m = ScaleMatrix(vec3(1/s.x, 1/s.y, 1/s.z)); //inverse matrix of the transformation
+        Q = m * Q * TMatrix4(m);
+    }
+
+    void Scale(float x, float y, float z){
+        Scale(vec3(x,y,z));
+    }
+
+    void Rotate(float angle, vec3 w) {
+        mat4 m = RotationMatrix(-1 * angle, w); //inverse matrix of the transformation
+        Q = m * Q * TMatrix4(m);
     }
 
     Hit intersect(const Ray &ray) {
         Hit hit;
+
         vec4 S(ray.start.x, ray.start.y, ray.start.z, 1);
         vec4 D(ray.dir.x, ray.dir.y, ray.dir.z, 0);
 
@@ -136,7 +169,7 @@ struct Quadric : public Intersectable {
         else if(t2CutOff) hit.t = t1;
         else hit.t = (t2 > 0) ? t2 : t1;
 
-        hit.position = ray.start + ray.dir * hit.t;
+        hit.position = ray.start + ray.dir * hit.t; //+ translate;
         hit.normal = gradf(vec4(hit.position.x, hit.position.y, hit.position.z, 1));
         hit.material = material;
         return hit;
@@ -154,6 +187,35 @@ struct Ellipsoid : public Quadric {
             vec4(0.0f, 0.0f, 1 / c / c, 0.0f),
             vec4(0.0f, 0.0f, 0.0f, -1.0f)
         );
+
+    }
+};
+
+struct Paraboloid : public Quadric {
+    float a, b;
+
+    Paraboloid(float _a, float _b, Material *_material): a(_a), b(_b) {
+        material = _material;
+        Q = mat4(
+                1/a/a, 0.0f,  0.0f, 0.0f,
+                0.0f , 1/b/b, 0.0f, 0.0f,
+                0.0f, 0.0f,   0.0f, 0.0f,
+                0.0f, 0.0f,   1.0f, 0.0f
+            );
+    }
+};
+
+struct Hyperboloid : public Quadric {
+    float a, b, c;
+
+    Hyperboloid(float _a, float _b, float _c, Material *_material): a(_a), b(_b), c(_c) {
+        material = _material;
+        Q = mat4(
+                1/a/a, 0.0f,  0.0f,  0.0f,
+                0.0f,  1/b/b, 0.0f,  0.0f,
+                0.0f,  0.0f,  -1/c/c, 0.0f,
+                0.0f, 0.0f,   0.0f,  -1.0f
+        );
     }
 };
 
@@ -197,7 +259,7 @@ struct Plane : public Quadric {
     }
 
     vec3 gradf(vec4 r) override {
-        return n + vec3(r.x, r.y, r.z);
+        return n;
     }
 };
 
@@ -244,7 +306,7 @@ class Scene {
     vec3 La;
 public:
     void build() {
-        vec3 eye = vec3(0, 3, 3), vup = vec3(0, 0, 1), lookat = vec3(0, 0, 0);
+        vec3 eye = vec3(0, 3.0f, 3.0f), vup = vec3(0, 0, 1), lookat = vec3(0, 0, 0);
         float fov = 80 * M_PI / 180;
         camera.set(eye, lookat, vup, fov);
 
@@ -263,31 +325,39 @@ public:
         Material *materialSilver = new ReflectiveMaterial(nSilver, kSilver);
         vec3 kd2(0.2f, 0.2f, 0.4f);
         Material *materialCylinder = new RoughMaterial(kd2, ks, 50);
+        vec3 kd3(0.2f, 0.4f, 0.2f);
+        Material *materialVial = new RoughMaterial(kd3, ks, 50);
 
         //BULDING THE ROOM
-        Ellipsoid* roomEllipsoid = new Ellipsoid(2.0f, 2.0f, 1, materialGold);
-        objects.push_back(roomEllipsoid);
+        Ellipsoid* roomEllipsoid = new Ellipsoid(2.0f, 2.0f, 1, materialRoom);
 
         //cutting the hole at the top
         Plane* topHolePlane = new Plane(vec3(0.0f, 0.0f, 0.95f), vec3(0.0f, 0.0f, 1.0f), materialCylinder);
         roomEllipsoid->intersectors.push_back(topHolePlane);
 
-        Plane* floorPlane = new Plane(vec3(0.0f, 0.0f, 0.0f),vec3(0.0f, 0.0f, 1.0f), materialCylinder);
-        objects.push_back(floorPlane);
-        printf("%f", floorPlane->f(vec4(0,0,0,1)));
-
-        //objects.push_back(new Sphere(vec3(0,0,0), 1.0f, materialCylinder));
-
-        Quadric* cylinder = new Cylinder(0.05f, 0.05f, materialCylinder);
+        // BULDING THE BLUE CYLINDER
+        Quadric* cylinder = new Cylinder(0.4f, 0.4f, materialCylinder);
         cylinder->intersectors.push_back(new Plane(vec3(0.0f,0.0f,0.3f), vec3(0.0f,0.0f,1.0f), materialRoom));
-//        cylinder->intersectors.push_back(floorPlane);
-        objects.push_back(cylinder);
-
-
-//        objects.push_back(new Sphere(vec3(0,0,0), 0.1f, materialCylinder));
+        cylinder->Scale(0.8, 0.8, 1.0f);
+        cylinder->Translate(vec3(0.5f,-0.7f,0.0f));
 
+        // BUILDING THE GOLDEN PARABOLOID
+        Quadric* paraboloid = new Paraboloid(0.7f, 0.85f, materialGold);
+        paraboloid->Translate(-0.75f, -0.45f, 0.0f);
 
+        //BULILDING THE GREEN VIAL
+        Quadric* vial = new Hyperboloid(0.5f, 0.5f, 0.65f, materialVial);
+        vial->intersectors.push_back(new Plane(vec3(0.0f, 0.0f, 0.25f),vec3(0.0f, 0.0f,1.0f), materialRoom));
+        vial->Scale(0.3f, 0.3f, 0.6f);
+        vial->Scale(0.75f, 0.75f, 1.0f);
+        vial->Translate(0.8f, 0.3f, 0.0f);
 
+        // INSERTING THE OBJECTS INTO THE ROOM
+        objects.push_back(roomEllipsoid);
+        objects.push_back(cylinder);
+        objects.push_back(paraboloid);
+        objects.push_back(vial);
+        //objects.push_back(new Sphere(vec3(0,0,0), 0.1f, materialCylinder));
     }
 
     void render(std::vector<vec4> &image) {
@@ -419,8 +489,6 @@ void onInitialization() {
     glViewport(0, 0, windowWidth, windowHeight);
     scene.build();
 
-
-
     long timeStart = glutGet(GLUT_ELAPSED_TIME);
     std::vector<vec4> image(windowWidth * windowHeight);
     scene.render(image);