diff --git a/inc/beamerProjection.h b/inc/beamerProjection.h
index 5989fd7a630515bd97033f36bc0fc68db1812edb..0da8db80b7ced86604aafd2585ef082caf9b7aa8 100644
--- a/inc/beamerProjection.h
+++ b/inc/beamerProjection.h
@@ -8,17 +8,20 @@
 class BeamerProjection{
     private:
         cv::Mat adjustingMatrix;
+        float topSandboxDistance = 1.0f;
 
-        cv::Point2i adjustPixel(int i, int j, float z, Camera *camera, cv::Point3f beamer_pos);
+        cv::Point2i findMatchingPixel(int i, int j, float z, Camera *camera, cv::Point3f beamer_pos);
+        void copyPixelsInto(cv::Point2i pixel_dst, cv::Mat &dst, cv::Point2i pixel_src, cv::Mat &src, cv::Rect base);
+        cv::Size getMatchingSize(cv::Mat &src, cv::Rect base);
 
     public:
         BeamerProjection();
 
-        void setAdjustingMatrix(cv::Mat matrix){ adjustingMatrix.setTo(matrix); }
+        void setAdjustingMatrix(cv::Mat matrix){ adjustingMatrix = matrix; }
         cv::Mat getAdjustingMatrix(){ return adjustingMatrix.clone(); }
 
         cv::Point2i rotatePixel(cv::Point2i pixel);
-        void adjustFrame(cv::Mat &depth, cv::Mat &src, cv::Mat &dst, Camera *camera, cv::Point3f beamer_pos);
+        void adjustFrame(cv::Mat depth, cv::Mat src, cv::Mat &dst, Camera *camera, cv::Point3f beamer_pos);
         void printAdjustingMatrix();
 
 };
diff --git a/inc/camera.h b/inc/camera.h
index 71c9490cc8553cb5fafe7e7add4ccc8892500fb8..067f0c8c2af0bb95eabf80fa5241e29734b99bfc 100644
--- a/inc/camera.h
+++ b/inc/camera.h
@@ -25,7 +25,12 @@ class Camera{
         Camera();
         ~Camera();
 
-        cv::Mat getDepthFrame(){ return cv::Mat(cv::Size(depth_frame->get_width(), depth_frame->get_height()), CV_16UC1, (void *)depth_frame->get_data(), cv::Mat::AUTO_STEP); };
+        cv::Mat getDepthFrame(){
+            cv::Mat meters;
+            cv::Mat values = cv::Mat(cv::Size(depth_frame->get_width(), depth_frame->get_height()), CV_16UC1, (void *)depth_frame->get_data(), cv::Mat::AUTO_STEP);
+            values.convertTo(meters,CV_32FC1, depth_frame->get_units());
+            return meters;
+        };
         cv::Mat getColorFrame(){ return cv::Mat(cv::Size(color_frame->get_width(), color_frame->get_height()), CV_8UC3, (void *)color_frame->get_data(), cv::Mat::AUTO_STEP); };
         void setCroppingMask(cv::Rect mask){ croppingMask = mask; };
         cv::Rect getCroppingMask(){ return croppingMask; };
diff --git a/inc/sandbox.h b/inc/sandbox.h
index 99e39976b47e94eca98faf36a70c65aadbac7f55..2e69baeff0020af7a2a1c2dea7354e11a35989a7 100644
--- a/inc/sandbox.h
+++ b/inc/sandbox.h
@@ -23,7 +23,7 @@ class Sandbox{
 
         cv::Mat getColorFrame();
         cv::Mat getDepthFrame();
-        void adjustProjection(cv::Mat &frame);
+        cv::Mat adjustProjection(cv::Mat frame);
         void showImage(cv::Mat &image);
         int loadConfig();
         int loadConfigFrom(char *path);
diff --git a/src/components/beamerProjection.cpp b/src/components/beamerProjection.cpp
index aaf9ea1fcb7fb75b2dc6efce34a03d82518a7d15..8513b54f8fd49aaae793bc1e6ccad4084bf667f2 100644
--- a/src/components/beamerProjection.cpp
+++ b/src/components/beamerProjection.cpp
@@ -2,7 +2,7 @@
 
 
 BeamerProjection::BeamerProjection(){
-    adjustingMatrix = cv::getRotationMatrix2D(cv::Point(0, 0), 0, 1);
+    //adjustingMatrix = cv::getRotationMatrix2D(cv::Point(0, 0), 0, 1);
 }
 
 
@@ -14,47 +14,100 @@ cv::Point2i BeamerProjection::rotatePixel(cv::Point2i pixel){
 }
 
 
-cv::Point2i BeamerProjection::adjustPixel(int i, int j, float z, Camera *camera, cv::Point3f beamer_pos){
 
-    //pixel to point 3d
-    float coord[2] = {static_cast<float>(j), static_cast<float>(i)};
-    cv::Point3f p = camera->deprojectPixelToPoint(coord, z / 1000.0);
-    //calcul vector point to beamer
-    cv::Vec3f dir(beamer_pos.x - p.x, beamer_pos.y - p.y, beamer_pos.z - p.z);
-    float prop = (0.99 - p.z) / dir[2];
-    p.x += dir[0] * prop;
-    p.y += dir[1] * prop;
-    p.z += dir[2] * prop;
-    //point 3d to pixel
-    return camera->projectPointToPixel(p);
-}
+void BeamerProjection::adjustFrame(cv::Mat depth, cv::Mat src, cv::Mat &dst, Camera *camera, cv::Point3f beamer_pos){
+
+    cv::Rect mask = camera->getCroppingMask();
+    cv::Size dst_size = dst.size();
+    cv::resize(src, src, dst.size());
 
+    // resize the frames to be a multiple of the camera size :
+    //      src.size = n * camera.depth.size , where n is uint > 0
+    cv::resize(src, src, getMatchingSize(src, mask));
+    cv::resize(dst, dst, src.size());
+    //src.copyTo(dst);
 
-void BeamerProjection::adjustFrame(cv::Mat &depth, cv::Mat &src, cv::Mat &dst, Camera *camera, cv::Point3f beamer_pos){
+    // Browse the depth frame matching the cropping mask
+    // while adapting pixels's position to the beamer's position
+    for (int j = 0; j < mask.height; j++){
+        for (int i = 0; i < mask.width; i++){
 
-    int nbChannel = src.channels();
-    //transformation on all pixel
-    //int64_t t1 = getTickCount();
-    for (int i = 0; i < src.rows; i++)
-    {
-        for (int j = 0; j < src.cols; j++)
-        {
-            cv::Point pixelIJ(j, i);
+            // coordinates of the pixel relative to the orginial image taken from the camera
+            int base_x = mask.x+i;
+            int base_y = mask.y+j;
+            float z = depth.at<float>(j,i);
+            
+            // pixels based on the original depth frame taken from the camera
+            cv::Point2i pixel = findMatchingPixel( base_x, base_y, z, camera, beamer_pos );
             
-            cv::Point pixel = adjustPixel(i, j, static_cast<float>(depth.at<uint16_t>(pixelIJ)), camera, beamer_pos);
-            if (pixel.x < dst.cols && pixel.y < dst.rows && pixel.x >= 0 && pixel.y >= 0)
-            {
-                if (nbChannel == 1)
-                    dst.at<char>(pixel) = src.at<char>(pixelIJ);
-                else if (nbChannel == 3)
-                    dst.at<cv::Vec3b>(pixel) = src.at<cv::Vec3b>(pixelIJ);
+            // pixel relative to the cropping mask
+            pixel.x -= mask.x;
+            pixel.y -= mask.y;
+
+            if( (0<=pixel.x && pixel.x<mask.width) && (0<=pixel.y && pixel.y<mask.height) ){
+                // src and dst must be of same size
+                copyPixelsInto(pixel, dst, cv::Point2i(i,j), src, mask);
             }
         }
     }
-    //cout << "temps de calcul: " << (getTickCount() - t1) / getTickFrequency() << endl;
+
+    cv::resize(src, src, dst_size);
     cv::warpAffine(dst, dst, adjustingMatrix, dst.size());
-    cv::dilate(dst, dst, cv::Mat(), cv::Point(-1, -1), 2, 1, 1);
-    cv::erode(dst, dst, cv::Mat(), cv::Point(-1, -1), 2, 1, 1);
+}
+
+cv::Size BeamerProjection::getMatchingSize(cv::Mat &src, cv::Rect base){
+    cv::Size bigSize;
+    bigSize.width = (src.size().width % base.width == 0) ? src.size().width : src.size().width - (src.size().width % base.width) + base.width;
+    bigSize.height = (src.size().height % base.height == 0) ? src.size().height : src.size().height - (src.size().height % base.height) + base.height;
+    return bigSize;
+}
+
+// pixels coordinates are relative to the camera depth frame
+void BeamerProjection::copyPixelsInto(cv::Point2i pixel_dst, cv::Mat &dst, cv::Point2i pixel_src, cv::Mat &src, cv::Rect base){
+
+    if( src.size().width == dst.size().width && src.size().height == dst.size().height ){
+
+        // determines the size of the square of pixels to copy from the source matching the position of the pixel of the depth frame
+        // (since src and dst are multiple of the depth frame's size)
+        int ratio_w = src.size().width / base.width;
+        int ratio_h = src.size().height / base.height;
+
+        for(int j=0; j<ratio_h; j++){
+            for (int i=0; i<ratio_w; i++){
+
+                int x_dst = pixel_dst.x * ratio_w + i;
+                int y_dst = pixel_dst.y * ratio_h + j;
+                int x_src = pixel_src.x * ratio_w + i;
+                int y_src = pixel_src.y * ratio_h + j;
+
+                dst.at<cv::Vec3b>(y_dst, x_dst) = src.at<cv::Vec3b>(y_src, x_src);
+            }
+        }
+    }
+}
+
+/*
+    C : Camera position
+    B : Beamer position
+    P : Point computed by camera depth
+    
+    Where
+        CP : distance from camera to point (value of depth_frame)
+        CB : distance from camera to beamer (beamer's position is relative to the camera)
+*/
+cv::Point2i BeamerProjection::findMatchingPixel(int i, int j, float z, Camera *camera, cv::Point3f CB){
+   
+    float pixel[2] = {static_cast<float>(i), static_cast<float>(j)};
+    cv::Point3f CP = camera->deprojectPixelToPoint(pixel, z);
+    cv::Point3f BP = CB - CP;
+    //float alpha = (topSandboxDistance - CP.z) / BP.z;
+    float BAz = CB.z + BP.z;
+    float BEz = topSandboxDistance - CB.z;
+    float alpha = BEz / BAz;
+    cv::Point3f V = (alpha * BP);
+    cv::Point3f CV = V + CB;
+
+    return camera->projectPointToPixel(CV);
 }
 
 
diff --git a/src/components/camera.cpp b/src/components/camera.cpp
index 7fcbb1073ae67dd9b89a379ef1d916cfd9f4194b..13970cd71be043b79572b7d5b73b7ca0832cfca0 100644
--- a/src/components/camera.cpp
+++ b/src/components/camera.cpp
@@ -89,7 +89,7 @@ void Camera::capture(){
     }
 }
 
-// match a pixel of depth frame to color frame
+// get the coordinates of the pixel matching the point relative to the real world
 cv::Point2i Camera::projectPointToPixel(cv::Point3f point3D){
 
     float point[3] = {point3D.x, point3D.y, point3D.z};
@@ -99,12 +99,12 @@ cv::Point2i Camera::projectPointToPixel(cv::Point3f point3D){
     return cv::Point2i(pixel[0], pixel[1]);
 }
 
-// match a pixel of color frame to depth frame
-cv::Point3f Camera::deprojectPixelToPoint(float coord[], float z1){
+// get  the point relative to the real world matching the coordinates of the pixel
+cv::Point3f Camera::deprojectPixelToPoint(float coord[], float z){
 
     float p[3];
     rs2_intrinsics intr = depth_frame->get_profile().as<rs2::video_stream_profile>().get_intrinsics();
-    rs2_deproject_pixel_to_point(p, &intr, coord, z1);
+    rs2_deproject_pixel_to_point(p, &intr, coord, z);
     return cv::Point3f(p[0], p[1], p[2]);
 }
 
diff --git a/src/lib/sandbox.cpp b/src/lib/sandbox.cpp
index 2ebfa1a1dd1f6133ea458cb3d9d3c49206abe3fd..e19e74418b58d67aaa377ad0946aff946500aff2 100644
--- a/src/lib/sandbox.cpp
+++ b/src/lib/sandbox.cpp
@@ -16,51 +16,33 @@ Sandbox::Sandbox(){
 
 cv::Mat Sandbox::getColorFrame(){
     camera.capture();
-    return camera.getColorFrame();
+    return camera.getColorFrame()(camera.getCroppingMask());
 }
 
 cv::Mat Sandbox::getDepthFrame(){
     camera.capture();
-    return camera.getDepthFrame();
+    return camera.getDepthFrame()(camera.getCroppingMask());
 }
 
 
-void Sandbox::adjustProjection(cv::Mat &frame){
-
-    static cv::Mat frameBeamer = cv::Mat(cv::Size(beamer.getWidth(), beamer.getHeight()), CV_8UC3);
+cv::Mat Sandbox::adjustProjection(cv::Mat frame){
     
     cv::Mat depth = getDepthFrame();
-    cv::Mat imageCalibrate = cv::Mat(depth.size(), CV_8UC3, cv::Scalar(0, 0, 0));
-    
-    cv::resize(frame, frame, depth.size());
-
+    cv::Mat imageCalibrate = cv::Mat(cv::Size(beamer.getWidth(), beamer.getHeight()), CV_8UC3, cv::Scalar(0, 0, 0));
     projection.adjustFrame(depth, frame, imageCalibrate, &camera, beamer.getPosition());
-    //flip to align frame with beamer
-    //cv::flip(imageCalibrate, imageCalibrate, 1);
-    //cv::flip(imageCalibrate, imageCalibrate, 0);
-    cv::resize(imageCalibrate(camera.getCroppingMask()), frameBeamer, frameBeamer.size());
-    frameBeamer.copyTo(frame);
 
-/*
-    cv::Mat image = *frame;
-    cv::Mat depth = getDepthFrame();
-    cv::Size beamerResolution = cv::Size(beamer.getWidth(), beamer.getHeight());
-    cv::Mat imageCalibrate(beamerResolution, CV_8UC3, cv::Scalar(0, 0, 0));
+    // frame after process
+    cv::dilate(imageCalibrate, imageCalibrate, cv::Mat(), cv::Point(-1, -1), 2, 1, 1);
+    cv::erode(imageCalibrate, imageCalibrate, cv::Mat(), cv::Point(-1, -1), 2, 1, 1);
     
-    cv::resize(depth, depth, beamerResolution);
-    cv::resize(image, image, beamerResolution);
-    projection.adjustFrame(depth, image, imageCalibrate, camera, beamer.getPosition());
-
-    imageCalibrate.copyTo(*frame);
-    return frame;
-*/
+    return imageCalibrate;
 }
 
 void Sandbox::showImage(cv::Mat &image){
 
     initWindowsFullScreen(defaultWindowsName);
-    adjustProjection(image);
-    cv::imshow(defaultWindowsName, image);
+    cv::Mat res = adjustProjection(image);
+    cv::imshow(defaultWindowsName, res);
 }
 
 int Sandbox::loadConfigFrom(char *path){
diff --git a/src/tools/sandboxConfig.cpp b/src/tools/sandboxConfig.cpp
index bfa736caef0a34541f9119f2e4210926c1a1bb22..a88493df546967e996526351ffebc2297239d085 100644
--- a/src/tools/sandboxConfig.cpp
+++ b/src/tools/sandboxConfig.cpp
@@ -162,11 +162,16 @@ int SandboxConfig::loadAdjustingMatrixFrom(char *path, BeamerProjection *project
         for (int j=0; j<width; j++){
             matrix.at<float>(i,j) = values.at(v_i);
             v_i++;
+            std::cout << matrix.at<float>(i,j) << " ";
         }
+        std::cout << std::endl;
     }
-
+    
+    
+    std::cout << "load matrix" << std::endl;
     projection->setAdjustingMatrix(matrix);
 
+    std::cout << "Ok matrix" << std::endl;
     return 0;
 }