title: Ray Tracing Reflection,Reflecting on the the wrong side
body: <p>Hey i am currently writing a ray tracer and i am try to add reflections.
  I have two questions.Is my ray direction calculation correct because it does not seem wrong.My second question is how would i implement reflections because this is not working to good.</p>
  
  <p><img src="https://photos-2.dropbox.com/t/2/AAAbC8iQxR4CVYM86Ib1MBiEgeRo3CGxQRFWZmOm2yFDiQ/12/442986265/png/32x32/1/1443193200/0/2/TracedImage.png/CJnendMBIAEgAiADIAQgBSAGIAcoBw/YVE7pGb81Cq5t1FinyX09VSrnjBSziQxjz1wa19I578?size=1024x768&amp;size_mode=2" alt="Reflections"></p>
  
  <p>It seems like the reflections are reversed.</p>
  
  <p>Here is my code For Trace!</p>
  
  <pre><code>public class Tracer {
  
  public boolean Tracing;
  public Camera Cam;
  public int Width, Height;
  public BufferedImage Image;
  public Color BackGroundColor;
  public int StartX, StartY, EndX, EndY,RowCount,ColCount;
  public double AmbientLight;
  public double DiffuseLight;
  public int MaxReflectionCount;
  public ArrayList&lt;GeometricObject&gt; GeoObjects;
  public ArrayList&lt;LightObject&gt; LightObjects;
  
  public Tracer(Camera cam, int width, int height, BufferedImage image, Color backGroundColor, int startX, int startY, int endX, int endY, int rowCount, int colCount, double ambientLight, double diffuseLight, int maxReflectionCount, ArrayList&lt;GeometricObject&gt; geoObjects, ArrayList&lt;LightObject&gt; lightObjects) {
      super();
      Cam = cam;
      Width = width;
      Height = height;
      Image = image;
      BackGroundColor = backGroundColor;
      StartX = startX;
      StartY = startY;
      EndX = endX;
      EndY = endY;
      RowCount = rowCount;
      ColCount = colCount;
      AmbientLight = ambientLight;
      DiffuseLight = diffuseLight;
      MaxReflectionCount = maxReflectionCount;
      GeoObjects = geoObjects;
      LightObjects = lightObjects;
  }
  
  public void TracePixelFast(int x, int y) {
      Color color = new Color(BackGroundColor.r,BackGroundColor.g,BackGroundColor.b);
      for(int o = 0;o &lt; GeoObjects.size();o++){
          GeometricObject GO = GeoObjects.get(o);
          Ray r = new Ray(Cam.GetRayPos(Width, Height, x, y, 1, 1, RowCount, ColCount), Cam.GetRayDir(Width, Height, x, y, 1,1, RowCount, ColCount));
          double hit = GO.hit(r);
          if (hit != 0.0) {
              color = Cal_Pixel(x,y);
              Image.setRGB(x, y, color.toInt());
              break;
          }
      }
  }
  
  public void TracePixelSmooth(int x, int y) {
      Image.setRGB(x, y,Cal_Pixel(x,y).toInt());
  }
  
  public Color Cal_Pixel(int x,int y){
      Color color = new Color(BackGroundColor);
      Color colorh = new Color(BackGroundColor);
      Color bgc = new Color(BackGroundColor);
      int HIT = 0;
      int MISS = 0;
      for (int row = 0; row &lt; RowCount; row++) {
          for (int col = 0; col &lt; ColCount; col++) {
              double min = Double.MAX_VALUE;
              Ray r = new Ray(Cam.GetRayPos(Width, Height, x, y, row, col, RowCount, ColCount),Cam.GetRayDir(Width, Height, x, y, row, col, RowCount, ColCount));
              for (int o = 0; o &lt; GeoObjects.size(); o++) {
                  GeometricObject GO = GeoObjects.get(o);
                  double hit = GO.hit(r);
                  if (hit != 0.0 &amp;&amp; hit &lt; min) {
                      min = hit;
                      colorh = ShadePixel(0,GO, r, hit);
                      HIT++;
                  } else {
                      double min2 = Double.MAX_VALUE;
                      for (int o2 = 0; o2 &lt; GeoObjects.size(); o2++) {
                          if(o!=o2){
                          GeometricObject GO2 = GeoObjects.get(o2);
                          double hit2 = GO2.hit(r);
                          if (hit2 != 0.0 &amp;&amp; hit2 &lt; min2) {
                          min2 = hit2;
                          bgc = ShadePixel(0,GO2, r, hit2);
                          }
                       }
                      }
                      MISS++;
                  }
              }
          }
      }
      for(int h = 0;h &lt; HIT;h++){
          color.Add(colorh);
      }
      for(int m = 0;m &lt; MISS;m++){
          color.Add(bgc);
      }
      color.Divide(RowCount * ColCount);
      return color;
  }
  
  public Color ShadePixel(int ReflectionDepthCount,GeometricObject GO,Ray ray,double t){
      Normal normal = GO.Cal_Normal(ray, t);
      if(GO.Reflectivity &gt; 0){
      Color GoColor = new Color(Cal_Reflection(GO,ReflectionDepthCount, ray, normal));
      Color finalcolor = new Color(Cal_Light(GoColor, normal));
      return finalcolor;
      }else{;
          Color finalcolor = new Color(Cal_Light(GO.Color, normal));
          return finalcolor;  
      }
  }
  
  public Color ShadePixel_End(GeometricObject GO,Normal normal){
      Color GoColor = new Color(GO.Color);
      Color finalcolor = new Color(Cal_Light(GoColor, normal));
      return finalcolor;
  }
  
  public Color Cal_Light(Color color,Normal normal){
      ArrayList&lt;Color&gt; PixelShade = new ArrayList&lt;Color&gt;();
      Color Final = new Color();
      for(int l = 0;l &lt; LightObjects.size();l++){
          LightObject light = LightObjects.get(l);
          Vector3D r_Dir = light.Pos.Sub(normal.Origin);
          r_Dir.normalize();
          Ray raytolight = new Ray(normal.Origin,r_Dir);
          int WAS_HIT = 0;
          for(int o = 0;o &lt; GeoObjects.size();o++){
              GeometricObject NGO = GeoObjects.get(o);
              double hit = NGO.hit(raytolight);
              if (hit != 0.0) {
                 WAS_HIT = 1;
              }
          }
          PixelShade.add(light.ShadePixel(WAS_HIT, normal, r_Dir, color, AmbientLight, DiffuseLight));
      }
      for(int s = 0;s &lt; PixelShade.size();s++){
          Final.Add(PixelShade.get(s));
      }
      Final.Divide(PixelShade.size());
      return Final;
  }
  
    public Color Cal_Reflection(GeometricObject OriginalObject,int ReflectionDepthCount,Ray InRay,Normal normal){
      if(ReflectionDepthCount &lt;= MaxReflectionCount){
          GeometricObject LastGO  = null;
          Ray LastRay = null;
          double LastT = 0.0;
          double min = Double.MAX_VALUE;
          double Dir_Out_Dot = InRay.Direction.Dot(normal.Direction);
          Vector3D Dir_Out = normal.Direction.Mul(2).Mul(Dir_Out_Dot).Sub(InRay.Direction);
          Ray r = new Ray(normal.Origin,Dir_Out);
          for (int o = 0; o &lt; GeoObjects.size(); o++) {
              GeometricObject GO = GeoObjects.get(o);
              double hit = GO.hit(r);
              if (hit != 0.0 &amp;&amp; hit &lt; min) {
                  min = hit;
                  LastGO = GO;
                  LastRay = r;
                  LastT = hit;
              }
         }
  
          if(LastGO != null){
              Color Reflected = new Color(ShadePixel(ReflectionDepthCount, LastGO,LastRay, LastT));
              Color HitColor = new Color(LastGO.Color);
              Color FinalColor = new Color();
              Reflected.Mul(OriginalObject.Reflectivity);
              FinalColor.Add(HitColor);
              FinalColor.Add(Reflected);
              FinalColor.Divide(2);
              FinalColor.Add(OriginalObject.Color);
              FinalColor.Divide(2);
              return FinalColor;
          }
      }
      return OriginalObject.Color;
  }
  
  public void TraceArea(boolean SmoothTracing) {
      Tracing = true;
      if(SmoothTracing){
          for (int x = StartX; x &lt; EndX; x++) {
              for (int y = StartY; y &lt; EndY; y++) {
                  TracePixelSmooth(x,y);
              }
          }
      }else{
          for (int x = StartX; x &lt; EndX; x++) {
              for (int y = StartY; y &lt; EndY; y++) {
                  TracePixelFast(x,y);
              }
          }
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>This is my code for my Sphere.</p>
  
  <pre><code>public class Sphere extends GeometricObject{
  
  public Vector3D Center;
  public double Radius;
  
  public Sphere(Vector3D Center,Color Color,double Radius,double Reflectivity){
      this.Center = Center;
      this.Radius = Radius;
      this.Color = Color;
      this.Reflectivity = Reflectivity;
  }
  
  public double hit(Ray ray) {
      double a = ray.Direction.Dot(ray.Direction);
      double b = 2 * ray.Origin.Sub(Center).Dot(ray.Direction);
      double c = ray.Origin.Sub(Center).Dot(ray.Origin.Sub(Center))-Radius*Radius;
      double discreminant = b*b-4*a*c;
      if(discreminant &lt; 0.0f){
          return 0.0;
      }else{
          double t = (-b - Math.sqrt(discreminant))/(2*a);
          if(t &gt; 10E-9){
              return t;
          }else{
              return 0.0;
          }
      }
  }
  
  public Normal Cal_Normal(Ray ray,double t) {
      Vector3D NPos = new Vector3D(ray.Origin.x + ray.Direction.x*t,ray.Origin.y + ray.Direction.y*t,ray.Origin.z + ray.Direction.z*t);
      Vector3D NDir = NPos.Sub(Center).Div(Radius);
      return new Normal(NPos,NDir);
  }
  </code></pre>
  
  <p>}</p>
  
  <p>If you need more of my code just request it and i will upload it.
  And if you want to help me improve me reflection part of my ray tracer i would like it to look more like this.Only if you wish to pour you knowledge of ray tracing onto my poor broken soul!</p>
  
  <p><img src="https://upload.wikimedia.org/wikipedia/commons/9/93/Raytracing_reflection.png" alt="Picture Of Hope"></p>