private double[] IntersectRaySphere(DoublePoint3D cameraPosition, DoublePoint3D viewVector, Sphere sphere)
        {
            var oc = cameraPosition - sphere.Center;     //vector from camera to sphere center

            var a = viewVector.ScalMultiply(viewVector); //viewVector length
            var b = 2 * oc.ScalMultiply(viewVector);
            var c = oc.ScalMultiply(oc) - sphere.Radius * sphere.Radius;

            var discriminant = b * b - 4 * a * c;

            if (discriminant < 0)
            {
                return new double[] { Inf, Inf }
            }
            ;

            var root1 = (-b + Math.Sqrt(discriminant)) / (2 * a);
            var root2 = (-b - Math.Sqrt(discriminant)) / (2 * a);

            return(new double[] { root1, root2 });
        }
 private DoublePoint3D ReflectRay(DoublePoint3D fallingVector, DoublePoint3D normalVector)
 {
     return(2 * normalVector * normalVector.ScalMultiply(fallingVector) - fallingVector);
 }
        private float ComputeLightning(DoublePoint3D intersectPoint, DoublePoint3D normalVector, DoublePoint3D vector, int specular)
        {
            var result   = 0f;
            var interval = new double[] { 0.001, Inf };

            foreach (LightSource light in LightSources)
            {
                if (light.ToString().Contains("Ambient"))
                {
                    result += light.Intense;
                }
                else
                {
                    DoublePoint3D lightVector;
                    if (light.ToString().Contains("Point"))
                    {
                        lightVector = (light as PointLight).Coord - intersectPoint;
                    }
                    else
                    {
                        lightVector = (light as DirectLight).Vector;
                    }

                    //Shadows
                    Closest shadow       = ClosestIntersection(intersectPoint, lightVector, interval);
                    float   transparency = 1;
                    while (shadow.Object != -1)
                    {
                        if ((GraphicalObjects[shadow.Object].Transparency == 0) || (transparency == 0))
                        {
                            transparency = 0;
                            break;
                        }
                        transparency *= GraphicalObjects[shadow.Object].Transparency;
                        shadow        = ClosestIntersection(intersectPoint + shadow.Point * lightVector, lightVector, interval);
                    }
                    if (transparency == 0)
                    {
                        continue;
                    }

                    //Diffusal Illumination
                    var scal = normalVector.ScalMultiply(lightVector);
                    if (scal > 0)
                    {
                        result += (float)(light.Intense * scal / (normalVector.Length() * lightVector.Length()));
                    }

                    //Specular Illumination
                    if (specular != -1)
                    {
                        var refleclectedVector = ReflectRay(lightVector, normalVector);
                        scal = refleclectedVector.ScalMultiply(vector);
                        if (scal > 0)
                        {
                            result += (float)(transparency * (light.Intense * Math.Pow(scal / (refleclectedVector.Length() * vector.Length()), specular)));
                        }
                    }
                }
            }

            return(result);
        }