Exemple #1
0
        public virtual IntersectionInfo Intersection(Ray r)
        {
            double   epsilon = 0.01;
            Vector3D v       = new Vector3D(r.Origin.X - center.X, r.Origin.Y - center.Y, r.Origin.Z - center.Z);
            double   A       = r.Direction.LengthSquare;
            double   B       = VectorOperations.ScalarProduct(r.Direction, v);
            double   C       = v.LengthSquare - radius * radius;
            double   D       = B * B - A * C;

            if (D <= 0.0)
            {
                return(null);
            }

            double t1 = (-B - Math.Sqrt(D)) / A;
            double t2 = (-B + Math.Sqrt(D)) / A;
            double t  = t1;

            if (t2 <= epsilon)
            {
                return(null);
            }

            if (t1 <= epsilon)    //луч идет из шара
            {
                t = t2;
            }

            Point3D P = new Point3D(r.Origin.X + r.Direction.X * t,
                                    r.Origin.Y + r.Direction.Y * t,
                                    r.Origin.Z + r.Direction.Z * t); //первая точка пересечения

            Vector3D N = new Vector3D(center, P);                    //вектор нормали единичной длины

            N *= (1 / N.Length);
            if (t1 <= epsilon)    //луч идет из шара
            {
                N *= (-1.0);
            }

            return(new IntersectionInfo(P, N, material));
        }
Exemple #2
0
        public IntersectionInfo Intersection(Ray r)
        {
            Vector3D V = new Vector3D(r.Origin.X - center.X,
                                      r.Origin.Y - center.Y,
                                      r.Origin.Z - center.Z);

            double t = -VectorOperations.ScalarProduct(V, normal) / VectorOperations.ScalarProduct(r.Direction, normal);

            if (t <= epsilon || Double.IsNaN(t) || Double.IsInfinity(t))
            {
                return(null);
            }

            Point3D crossPoint = new Point3D(r.Origin.X + r.Direction.X * t,
                                             r.Origin.Y + r.Direction.Y * t,
                                             r.Origin.Z + r.Direction.Z * t);

            if (VectorOperations.Distance(crossPoint, center) > radius)
            {
                return(null);
            }

            return(new IntersectionInfo(crossPoint, normal, m));
        }
        public IntersectionInfo Intersection(Ray r)
        {
            Vector3D N = VectorOperations.VectorProduct(new Vector3D(A, B), new Vector3D(A, C));

            //нормаль определяет внешнюю и внутреннюю сторону треугольника
            N *= (1 / N.Length);
            Vector3D V = new Vector3D(r.Origin.X - A.X,
                                      r.Origin.Y - A.Y,
                                      r.Origin.Z - A.Z);
            double t = -VectorOperations.ScalarProduct(V, N) / VectorOperations.ScalarProduct(r.Direction, N);

            if (t <= epsilon || Double.IsNaN(t) || Double.IsInfinity(t))
            {
                return(null);
            }

            Point3D crossPoint = new Point3D(r.Origin.X + r.Direction.X * t,
                                             r.Origin.Y + r.Direction.Y * t,
                                             r.Origin.Z + r.Direction.Z * t);

            Vector3D OX = new Vector3D(A, B);
            Vector3D AC = new Vector3D(A, C);
            Vector3D AD = new Vector3D(A, crossPoint);
            Vector3D OY = VectorOperations.VectorProduct(N, OX);

            Line3D axis     = new Line3D(A, OX);
            Line3D ordinate = new Line3D(A, OY);

            double Bx = VectorOperations.Distance(ordinate, B);
            double By = 0;

            double Cx = VectorOperations.Distance(ordinate, C);

            if (VectorOperations.Cos(OX, AC) < 0)
            {
                Cx *= -1;
            }

            double Cy = VectorOperations.Distance(axis, C);

            if (VectorOperations.Cos(OY, AC) < 0)
            {
                Cy *= -1;
            }

            double Dx = VectorOperations.Distance(ordinate, crossPoint);

            if (VectorOperations.Cos(OX, AD) < 0)
            {
                Dx *= -1;
            }

            double Dy = VectorOperations.Distance(axis, crossPoint);

            if (VectorOperations.Cos(OY, AD) < 0)
            {
                Dy *= -1;
            }


            int s1 = Math.Sign(Bx * Dy - By * Dx);
            int s2 = Math.Sign((Cx - Bx) * (Dy - By) - (Cy - By) * (Dx - Bx));
            int s3 = Math.Sign(-Cx * (Dy - Cy) + Cy * (Dx - Cx));

            if (s1 == s2 && s1 == s3 && s2 == s3)
            {
                Material m = material_front;
                if (VectorOperations.Cos(N, r.Direction) >= -epsilon && (material_back != null))
                {
                    N *= (-1);
                    m  = material_back;
                }

                return(new IntersectionInfo(crossPoint, N, m));
            }

            return(null);
        }