コード例 #1
0
        protected override Intersection[] GetBaseIntersections(Ray ray)
        {
            var dir_cross_e2 = Tuple4.CrossProduct(ray.dir, E2);
            var det          = Tuple4.DotProduct(E1, dir_cross_e2);

            if (Constants.EpsilonZero(Math.Abs(det)))
            {
                return(null);
            }

            var f            = 1.0 / det;
            var p1_to_origin = Tuple4.Subtract(ray.origin, P1);
            var u            = f * Tuple4.DotProduct(p1_to_origin, dir_cross_e2);

            if ((u < 0.0) || (u > 1.0))
            {
                return(null);
            }

            var origin_cross_e1 = Tuple4.CrossProduct(p1_to_origin, E1);
            var v = f * Tuple4.DotProduct(ray.dir, origin_cross_e1);

            if ((v < 0.0) || ((u + v) > 1.0))
            {
                return(null);
            }

            var t = f * Tuple4.DotProduct(E2, origin_cross_e1);

            return(new Intersection[] { new Intersection(t, this) });
        }
コード例 #2
0
 public GradientPattern(IMatrix transformation, Tuple4 colorA, Tuple4 colorB)
     : base(transformation)
 {
     ColorA     = colorA;
     ColorB     = colorB;
     colorDelta = Tuple4.Subtract(ColorB, colorA);
 }
コード例 #3
0
        public void TupleSubtractTest()
        {
            var t1 = new Tuple4(1, 7, 3, TupleFlavour.Vector);
            var t2 = new Tuple4(4, 5, 6, TupleFlavour.Vector);

            var expected = new Tuple4(-3, 2, -3, TupleFlavour.Vector);

            Assert.Equal(expected, Tuple4.Subtract(t1, t2));
        }
コード例 #4
0
        public void Then_minus_points(string a, string b, double t1, double t2, double t3)
        {
            var c = Tuple4.Subtract(cache[a], cache[b]);

            Assert.True(Constants.EpsilonCompare(t1, c.X));
            Assert.True(Constants.EpsilonCompare(t2, c.Y));
            Assert.True(Constants.EpsilonCompare(t3, c.Z));
            Assert.True(c.IsPoint());
        }
コード例 #5
0
        public TriangleFigure(IMatrix transformation, IMaterial material, Tuple4 p1, Tuple4 p2, Tuple4 p3)
        {
            this.Material       = material;
            this.Transformation = transformation;

            this.P1     = p1;
            this.P2     = p2;
            this.P3     = p3;
            this.E1     = Tuple4.Subtract(p2, p1);
            this.E2     = Tuple4.Subtract(p3, p1);
            this.Normal = Tuple4.Normalize(Tuple4.CrossProduct(E2, E1));
        }
コード例 #6
0
        public Ray GetRay(double screenX, double screenY)
        {
            var xoffset = (screenX + 0.5) * PixleSize;
            var yoffset = (screenY + 0.5) * PixleSize;

            var worldX = tangx - xoffset;
            var worldY = tangy - yoffset;

            var pixel = MatrixOperations.Geometry3D.Transform(inverseTransform, new Tuple4(worldX, worldY, -1.0, TupleFlavour.Point));

            var direction = Tuple4.Normalize(Tuple4.Subtract(pixel, Origin));

            return(new Ray(Origin, direction));
        }
コード例 #7
0
        public TriangleWithNormalsFigure(IMatrix transformation, IMaterial material, Tuple4 p1, Tuple4 p2, Tuple4 p3, Tuple4 n1, Tuple4 n2, Tuple4 n3)
        {
            this.Material       = material;
            this.Transformation = transformation;

            this.P1 = p1;
            this.P2 = p2;
            this.P3 = p3;
            this.E1 = Tuple4.Subtract(p2, p1);
            this.E2 = Tuple4.Subtract(p3, p1);
            this.N1 = n1;
            this.N2 = n2;
            this.N3 = n3;
        }
コード例 #8
0
        public virtual HitResult[] AllHits(Tuple4 origin, Tuple4 dir)
        {
            var intersections = GetIntersections(new Ray(origin, dir));

            if (intersections == null)
            {
                return(new HitResult[] { HitResult.NoHit });
            }

            var result = new HitResult[intersections.Length];

            for (int i = 0; i < intersections.Length; ++i)
            {
                var figure         = intersections[i].figure;
                var distance       = intersections[i].t;
                var pointOnSurface = Tuple4.Geometry3D.MovePoint(origin, dir, distance); // orig + dir*dist
                // TODO: Remove this cast to BaseFigure
                (var surfaceNormal, var objectPoint) = ((BaseFigure)figure).GetTransformedNormal(figure, pointOnSurface, intersections[i].u, intersections[i].v);
                var eyeVector = Tuple4.Negate(dir);
                var isInside  = false;
                if (Tuple4.DotProduct(surfaceNormal, eyeVector) < 0)
                {
                    isInside      = true;
                    surfaceNormal = Tuple4.Negate(surfaceNormal);
                }
                var pointOverSurface  = Tuple4.Add(pointOnSurface, Tuple4.Scale(surfaceNormal, Constants.Epsilon));
                var pointUnderSurface = Tuple4.Subtract(pointOnSurface, Tuple4.Scale(surfaceNormal, Constants.Epsilon));
                var reflectionVector  = Tuple4.Reflect(dir, surfaceNormal);

                result[i] = new HitResult(true,
                                          figure,
                                          distance,
                                          intersections[i].u,
                                          intersections[i].v,
                                          objectPoint,
                                          pointOnSurface,
                                          pointOverSurface,
                                          pointUnderSurface,
                                          surfaceNormal,
                                          eyeVector,
                                          reflectionVector,
                                          isInside);
            }

            return(result);
        }
コード例 #9
0
        private Tuple4 CalculateRefractedColorAt(HitResult hit, double refractiveIndexEntering, double refractiveIndexExiting, int remaining)
        {
            if (!hit.IsHit || remaining <= 0)
            {
                return(colors.Black);
            }

            var material = hit.Figure.Material;

            if (Constants.EpsilonZero(material.Transparency))
            {
                return(colors.Black);
            }

            // Calculations are based on Snell's law

            var ration = refractiveIndexEntering / refractiveIndexExiting;
            var cosI   = Tuple4.DotProduct(hit.EyeVector, hit.SurfaceNormal);

            // sin(t) * sin(t) = (ration * ration) * (1 - cos(I) * cos(I))
            var sinTheta2 = ration * ration * (1 - cosI * cosI);

            if (sinTheta2 > 1.0)
            {
                // Total internal reflection
                return(colors.Black);
            }

            var cosTheta = Math.Sqrt(1 - sinTheta2);
            var dir      = Tuple4.Subtract(Tuple4.Scale(hit.SurfaceNormal, ration * cosI - cosTheta),
                                           Tuple4.Scale(hit.EyeVector, ration));

            var refractedRay   = new Ray(hit.PointUnderSurface, dir);
            var refractedColor = CastRay(refractedRay, remaining - 1);

            return(Tuple4.Scale(refractedColor, material.Transparency));
        }
コード例 #10
0
        public Tuple4 GetShadedColor(Tuple4 objectPoint, IMaterial material, Tuple4 eyeVector, Tuple4 pointOnSurface, Tuple4 surfaceNormal)
        {
            var lightDirection = Tuple4.Normalize(Tuple4.Subtract(location, pointOnSurface));

            return(DirectionLightCommon.GetShadedColor(objectPoint, material, colors.White, lightDirection, intensity, eyeVector, pointOnSurface, surfaceNormal));
        }
コード例 #11
0
 public double GetLightDistance(Tuple4 from)
 {
     return(Tuple4.Subtract(location, from).Length());
 }
コード例 #12
0
 public Tuple4 GetLightDirection(Tuple4 from)
 {
     return(Tuple4.Normalize(Tuple4.Subtract(location, from)));
 }