示例#1
0
 public BiconvexLens()
 {
     RefractiveIndex = Materials.Fixed.GLASS_CROWN_K7;
     apertureRadius = 2;
     curvatureRadius = 2.5;
     backSurface = new Sphere();
     frontSurface = new Sphere();
     UpdateSpheres();
 }
示例#2
0
        /// <summary>
        /// Creates and initializes a new instance of a complex lens.
        /// </summary>
        /// <param name="surfaces">List of element surfaces, ordered from
        /// back to front.</param>
        public ComplexLens(IList<ElementSurface> surfaces)
        {
            ElementSurfaces = surfaces;

            ElementSurface frontSurface = surfaces.LastOrDefault((surface) => surface.Surface is Sphere);
            frontSphericalSurface = (Sphere)frontSurface.Surface;
            frontSurfaceSinTheta = frontSphericalSurface.GetCapElevationAngleSine(frontSurface.ApertureRadius);
            frontSurfaceApertureRadius = frontSurface.ApertureRadius;

            ElementSurface backSurface = surfaces.FirstOrDefault((surface) => surface.Surface is Sphere);
            backSphericalSurface = (Sphere)backSurface.Surface;
            backSurfaceSinTheta = backSphericalSurface.GetCapElevationAngleSine(backSurface.ApertureRadius);
            backSurfaceApertureRadius = backSurface.ApertureRadius;

            MediumRefractiveIndex = Materials.Fixed.AIR;
            frontSurface.NextRefractiveIndex = MediumRefractiveIndex;
        }
示例#3
0
        public Window()
            : base(1280, 720, new GraphicsMode(32, 0, 0, 4), "OpenCAD")
        {
            stl = new STL("Models/elephant.stl", Color.Green, STLType.Binary);

            var s1 = new Sphere {Center = Vect3.Zero, Radius = 4};
            var s2 = new Sphere {Center = new Vect3(0,5,0), Radius = 4};
            var t1 = new Octree<Voxel>(Vect3.Zero, 32.0);
            var t2 = new Octree<Voxel>(Vect3.Zero, 32.0);

            Test2(t1, node => s1.Intersects(node.AABB));
            Test(t2, stl.Elements);

            _tree = t1.Union(t2);

            //_tree.Test(node => sphere.Intersects(node.AABB),maxLevel);
            //Test2(t, node => sphere.Intersects(node.AABB));

            //t[0].Clear();
            //t[0].Clear();
            //Test(_tree,stl.Elements);
            //create from stl
            //foreach (var tri in stl.Elements)
            //{
            //    Intersect(_tree, tri);
            //}

            VSync = VSyncMode.On;

            _camera = new Camera();
            Mouse.WheelChanged += (sender, args) =>
                {
                    _camera.View = _camera.View * Mat4.Translate(0, 0, args.DeltaPrecise * -10.0);
                    //_camera.Eye += new Vect3(0, 0, args.DeltaPrecise * -10.0);
                    // Console.WriteLine(_camera.Eye);
                };
        }
示例#4
0
        public void IntersectSphere()
        {
            Sphere sphere = new Sphere()
            {
                Radius = 2
            };
            double biggerSphereFactor = 3;

            Sampler sampler = new Sampler();
            int sampleCount = 64;
            int sqrtSampleCount = (int)Math.Sqrt(sampleCount);
            foreach (Vector2d sample in sampler.GenerateJitteredSamples(sqrtSampleCount))
            {
                // shoot rays at the sphere center from a bigger concontric sphere
                Vector3d unitSphereSample = Sampler.UniformSampleSphereWithEqualArea(sample, -1, 1);
                Vector3d sourcePos = biggerSphereFactor * sphere.Radius * unitSphereSample;
                Ray ray = new Ray(sourcePos, sphere.Center - sourcePos);
                Intersection intersection = sphere.Intersect(ray);
                Assert.NotNull(intersection);
                Vector3d intPos = intersection.Position;
                Console.WriteLine("Black, {0},", ray.ToLine());
                Console.WriteLine(String.Format("Red, {0},", intPos.ToPoint()));
            }
        }
示例#5
0
        protected static CSGInnerNode head()
        {
            CSGInnerNode root = new CSGInnerNode( SetOperation.Union );

              double[] skinColor = new double[] { 1, .8, .65 };
              double[] whiteColor = new double[] { 1, 1, 1 };
              double[] blackColor = new double[] { 0, 0, 0 };
              double[] blueColor = new double[] { 0, 0, 1 };
              double[] redColor = new double[] { 1, 0, 0 };

              CSGInnerNode hlava = new CSGInnerNode( SetOperation.Difference );
              root.InsertChild( hlava, Matrix4d.Identity );

              Sphere s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, skinColor );
              hlava.InsertChild( s, Matrix4d.Scale( 2.3 ) );

              // klobouk
              CSGInnerNode klobouk = new CSGInnerNode( SetOperation.Union );

              Cylinder klb = new Cylinder( -0.5, 0.5 );
              klb.SetAttribute( PropertyName.COLOR, blackColor );
              klobouk.InsertChild( klb, Matrix4d.Scale( 2, 2, 1.4 ) * Matrix4d.RotateX( Math.PI / 2 ) * Matrix4d.CreateTranslation( 0, 0.5, 0 ) );

              Cylinder ksilt = new Cylinder( -0.5, 0.5 );
              ksilt.SetAttribute( PropertyName.COLOR, blackColor );
              klobouk.InsertChild( ksilt, Matrix4d.Scale( 3, 3, .1 ) * Matrix4d.RotateX( Math.PI / 2 ) );

              root.InsertChild( klobouk, Matrix4d.CreateTranslation( 0, 1.25, 0 ) );

              // levy ocni dulek
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, skinColor );
              hlava.InsertChild( s, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateTranslation( -0.7, .3, -1.8 ) );

              // pravy ocni dulek
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, skinColor );
              hlava.InsertChild( s, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateTranslation( 0.7, .3, -1.8 ) );

              // prave oko
              CSGInnerNode oko = new CSGInnerNode( SetOperation.Union );
              root.InsertChild( oko, Matrix4d.CreateTranslation( 0.70, 0.3, -0.5 ) );

              Sphere bulva = new Sphere();
              bulva.SetAttribute( PropertyName.COLOR, whiteColor );
              oko.InsertChild( bulva, Matrix4d.Scale( 1.3 ) );

              Sphere cocka = new Sphere();
              cocka.SetAttribute( PropertyName.COLOR, blueColor );
              oko.InsertChild( cocka, Matrix4d.Scale( 0.3 ) * Matrix4d.CreateTranslation( 0, 0, -1.2 ) );

              // leve oko
              oko = new CSGInnerNode( SetOperation.Union );
              root.InsertChild( oko, Matrix4d.CreateTranslation( -0.70, 0.3, -0.5 ) );

              bulva = new Sphere();
              bulva.SetAttribute( PropertyName.COLOR, whiteColor );
              oko.InsertChild( bulva, Matrix4d.Scale( 1.3 ) );

              cocka = new Sphere();
              cocka.SetAttribute( PropertyName.COLOR, blueColor );
              oko.InsertChild( cocka, Matrix4d.Scale( 0.3 ) * Matrix4d.CreateTranslation( 0, 0, -1.2 ) );

              // nos
              Cylinder nos = new Cylinder( -0.5, 0.5 );
              nos.SetAttribute( PropertyName.COLOR, skinColor );
              root.InsertChild( nos, Matrix4d.Scale( 0.2, 0.2, 0.6 ) * Matrix4d.CreateTranslation( 0, 0, -2.65 ) );

              // usta
              CSGInnerNode usta = new CSGInnerNode( SetOperation.Xor );

              Cylinder horniRet = new Cylinder( -0.5, 0.5 );
              horniRet.SetAttribute( PropertyName.COLOR, redColor );
              usta.InsertChild( horniRet, Matrix4d.CreateTranslation( 0, -0.3, 0 ) );

              Cylinder dolniRet = new Cylinder( -0.5, 0.5 );
              dolniRet.SetAttribute( PropertyName.COLOR, redColor );
              usta.InsertChild( dolniRet, Matrix4d.CreateTranslation( 0, 0.3, 0 ) );

              root.InsertChild( usta, Matrix4d.Scale( 0.7, 0.3, 1 ) * Matrix4d.CreateTranslation( 0, -0.7, -1.85 ) );

              // vnitrek ust
              CSGInnerNode vnitrekUst = new CSGInnerNode( SetOperation.Intersection );
              horniRet = new Cylinder( -0.5, 0.5 );
              horniRet.SetAttribute( PropertyName.COLOR, blackColor );
              vnitrekUst.InsertChild( horniRet, Matrix4d.CreateTranslation( 0, -0.3, 0 ) );

              dolniRet = new Cylinder( -0.5, 0.5 );
              dolniRet.SetAttribute( PropertyName.COLOR, blackColor );
              vnitrekUst.InsertChild( dolniRet, Matrix4d.CreateTranslation( 0, 0.3, 0 ) );

              usta.InsertChild( vnitrekUst, Matrix4d.CreateTranslation( 0, 0, 0.1 ) );

              return root;
        }
示例#6
0
        /// <summary>
        /// Infinite plane with two spheres on it (one of them is transparent)
        /// </summary>
        public static void TwoSpheres( IRayScene sc )
        {
            Debug.Assert( sc != null );

              // CSG scene:
              CSGInnerNode root = new CSGInnerNode( SetOperation.Union );
              root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 1.0, 0.8, 0.1 }, 0.1, 0.6, 0.4, 128 ) );
              sc.Intersectable = root;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 };

              // Camera:
              sc.Camera = new StaticCamera( new Vector3d( 0.7, 0.5, -5.0 ),
                                    new Vector3d( 0.0, -0.18, 1.0 ),
                                    50.0 );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 0.8 ) );
              sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 4.0, -3.0 ), 1.2 ) );

              // --- NODE DEFINITIONS ----------------------------------------------------

              // Transparent sphere:
              Sphere s;
              s = new Sphere();
              PhongMaterial pm = new PhongMaterial( new double[] { 0.0, 0.2, 0.1 }, 0.05, 0.05, 0.1, 128 );
              pm.n = 1.6;
              pm.Kt = 0.9;
              s.SetAttribute( PropertyName.MATERIAL, pm );
              root.InsertChild( s, Matrix4d.Identity );

              // Opaque sphere:
              s = new Sphere();
              root.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 1.5, 0.2, 2.4 ) );

              // Infinite plane with checker:
              Plane pl = new Plane();
              pl.SetAttribute( PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 } );
              pl.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 0.6, 0.6, new double[] { 1.0, 1.0, 1.0 } ) );
              root.InsertChild( pl, Matrix4d.RotateX( -MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( 0.0, -1.0, 0.0 ) );
        }
示例#7
0
        /// <summary>
        /// Test scene for Toruses by Jan Navratil, (c) 2012
        /// </summary>
        public static void Toroids( IRayScene sc )
        {
            Debug.Assert( sc != null );

              // CSG scene:
              CSGInnerNode root = new CSGInnerNode( SetOperation.Union );
              root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.7, 0.2, 16 ) );
              sc.Intersectable = root;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.15, 0.2 };

              // Camera:
              sc.Camera = new StaticCamera( new Vector3d( 0.0, 0.0, -10.0 ),
                                    new Vector3d( 0.0, -0.04, 1.0 ),
                                    60.0 );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 1.8 ) );
              sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 2.0 ) );

              // --- NODE DEFINITIONS ----------------------------------------------------

              Sphere s;
              Torus t;

              t = new Torus( 2.0, 1.0 );
              t.SetAttribute( PropertyName.COLOR, new double[] { 0, 0, 0.7 } );
              t.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 50, 20, new double[] { 0.9, 0.9, 0 } ) );
              root.InsertChild( t, Matrix4d.Scale( 0.8 ) * Matrix4d.CreateRotationX( 0.9 ) * Matrix4d.CreateTranslation( 2.7, 0.6, 0.0 ) );

              t = new Torus( 1.0, 1.5 );
              t.SetAttribute( PropertyName.COLOR, new double[] { 1, 0, 0 } );
              t.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 40, 40, new double[] { 0.8, 1.0, 1.0 } ) );

              CSGInnerNode donut = new CSGInnerNode( SetOperation.Difference );
              donut.InsertChild( t, Matrix4d.Identity );
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 0.5, 0.5, 0.5 } );
              s.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 100, 100, new double[] { 1, 0.5, 0 } ) );
              donut.InsertChild( s, Matrix4d.Scale( 3 ) * Matrix4d.CreateTranslation( 0, -3, 0 ) );
              root.InsertChild( donut, Matrix4d.CreateRotationX( 0.8 ) * Matrix4d.CreateTranslation( -2.5, 0.0, 0.0 ) );

              int number = 14;
              for ( int i = 0; i < number; i++ )
              {
            t = new Torus( 0.2, 0.01 + 0.185 * i / number );
            t.SetAttribute( PropertyName.COLOR, new double[] { 1, 1, 1 } );
            root.InsertChild( t, Matrix4d.CreateRotationX( 0.5 * i ) * Matrix4d.CreateTranslation( 10.0 * (1.0 * i / number) - 4.7, -2.5, 0 ) );
              }
        }
示例#8
0
        /// <summary>
        /// Hedgehog in the Cage - by Michal Wirth, (c) 2012
        /// </summary>
        public static void HedgehogInTheCage( IRayScene sc )
        {
            Debug.Assert( sc != null );

              // CSG scene:
              CSGInnerNode root = new CSGInnerNode( SetOperation.Union );
              root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.6, 0.2, 16 ) );
              sc.Intersectable = root;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.05, 0.05 };

              // Camera:
              sc.Camera = new StaticCamera( new Vector3d( 0.0, 2.0, -7.0 ),
                                    new Vector3d( 0.0, -0.32, 1.0 ),
                                    40.0 );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 0.8 ) );
              sc.Sources.Add( new PointLightSource( new Vector3d( -8.0, 5.0, -3.0 ), 1.0 ) );

              // --- NODE DEFINITIONS ----------------------------------------------------

              // cage
              CSGInnerNode cage = new CSGInnerNode( SetOperation.Difference );
              cage.SetAttribute( PropertyName.COLOR, new double[] { 0.70, 0.93, 0.20 } );

              // cylinder1
              CSGInnerNode cylinder1 = new CSGInnerNode( SetOperation.Intersection );
              Sphere s = new Sphere();
              cylinder1.InsertChild( s, Matrix4d.Scale( 1.0, 1000.0, 1.0 ) );
              s = new Sphere();
              cylinder1.InsertChild( s, Matrix4d.Scale( 1000.0, 1.5, 1000.0 ) );
              cage.InsertChild( cylinder1, Matrix4d.Identity );

              // cylinder2
              CSGInnerNode cylinder2 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              cylinder2.InsertChild( s, Matrix4d.Scale( 1.0, 1000.0, 1.0 ) );
              s = new Sphere();
              cylinder2.InsertChild( s, Matrix4d.Scale( 1000.0, 1.5, 1000.0 ) );
              cage.InsertChild( cylinder2, Matrix4d.Scale( 0.9 ) );

              // holeUpDown
              Sphere holeUpDown = new Sphere();
              cage.InsertChild( holeUpDown, Matrix4d.Scale( 0.5, 1000.0, 0.5 ) );

              // hole1
              CSGInnerNode hole1 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              hole1.InsertChild( s, Matrix4d.Scale( 1000.0, 1.1, 1000.0 ) );
              s = new Sphere();
              hole1.InsertChild( s, Matrix4d.Scale( 0.4, 1000.0, 1000.0 ) );
              cage.InsertChild( hole1, Matrix4d.Identity );

              // hole2
              CSGInnerNode hole2 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              hole2.InsertChild( s, Matrix4d.Scale( 1000.0, 1.1, 1000.0 ) );
              s = new Sphere();
              hole2.InsertChild( s, Matrix4d.Scale( 0.4, 1000.0, 1000.0 ) );
              cage.InsertChild( hole2, Matrix4d.RotateY( Math.PI / 3 ) );

              // hole3
              CSGInnerNode hole3 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              hole3.InsertChild( s, Matrix4d.Scale( 1000.0, 1.1, 1000.0 ) );
              s = new Sphere();
              hole3.InsertChild( s, Matrix4d.Scale( 0.4, 1000.0, 1000.0 ) );
              cage.InsertChild( hole3, Matrix4d.RotateY( Math.PI / -3 ) );

              // hedgehog
              CSGInnerNode hedgehog = new CSGInnerNode( SetOperation.Union );
              hedgehog.SetAttribute( PropertyName.COLOR, new double[] { 0.4, 0.05, 0.05 } );

              s = new Sphere();
              hedgehog.InsertChild( s, Matrix4d.Scale( 0.48 ) );

              // spine1
              CSGInnerNode spine1 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              spine1.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) );
              s = new Sphere();
              spine1.InsertChild( s, Matrix4d.Scale( 1.2 ) );
              hedgehog.InsertChild( spine1, Matrix4d.Identity );

              // spine2
              CSGInnerNode spine2 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              spine2.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) );
              s = new Sphere();
              spine2.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, 0.1, 0.0 ) );
              hedgehog.InsertChild( spine2, Matrix4d.RotateX( Math.PI / -3 ) );

              // spine3
              CSGInnerNode spine3 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              spine3.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) );
              s = new Sphere();
              spine3.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, -0.25, 0.0 ) );
              hedgehog.InsertChild( spine3, Matrix4d.RotateX( Math.PI / -3 ) * Matrix4d.RotateY( Math.PI * -0.4 ) );

              // spine4
              CSGInnerNode spine4 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              spine4.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) );
              s = new Sphere();
              spine4.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, 0.2, 0.0 ) );
              hedgehog.InsertChild( spine4, Matrix4d.RotateX( Math.PI / -3 ) * Matrix4d.RotateY( Math.PI * -0.8 ) );

              // spine5
              CSGInnerNode spine5 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              spine5.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) );
              s = new Sphere();
              spine5.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, -0.2, 0.0 ) );
              hedgehog.InsertChild( spine5, Matrix4d.RotateX( Math.PI / -3 ) * Matrix4d.RotateY( Math.PI * 0.4 ) );

              // spine6
              CSGInnerNode spine6 = new CSGInnerNode( SetOperation.Intersection );
              s = new Sphere();
              spine6.InsertChild( s, Matrix4d.Scale( 0.06, 1000.0, 0.06 ) );
              s = new Sphere();
              spine6.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 0.0, -0.25, 0.0 ) );
              hedgehog.InsertChild( spine6, Matrix4d.RotateX( Math.PI / -3 ) * Matrix4d.RotateY( Math.PI * 0.8 ) );

              // all
              CSGInnerNode all = new CSGInnerNode( SetOperation.Union );
              all.InsertChild( cage, Matrix4d.RotateY( 0.25 ) );
              all.InsertChild( hedgehog, Matrix4d.Rotate( new Vector3d( 0.0, 1.0, 1.0 ), 0.1 ) * Matrix4d.CreateTranslation( 0.0, -0.1, 0.0 ) );

              root.InsertChild( all, Matrix4d.RotateZ( 0.1 ) );
        }
示例#9
0
        /// <summary>
        /// Six national flags (in artistic style) - by Jakub Vlcek, (c) 2012
        /// </summary>
        public static void Flags( IRayScene sc )
        {
            Debug.Assert( sc != null );

              // CSG scene:
              CSGInnerNode flags = new CSGInnerNode( SetOperation.Union );
              flags.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              flags.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.5, 0.5, 0.5 }, 0.2, 0.7, 0.1, 16 ) );
              sc.Intersectable = flags;
              Sphere s;
              Cube c;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.05, 0.05 };

              // Camera:
              sc.Camera = new StaticCamera( new Vector3d( 0.0, 0.0, -10.0 ),
                                    new Vector3d( 0.0, 0.0, 1.0 ),
                                    60.0 );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 0.8 ) );
              sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 1.0 ) );
              sc.Sources.Add( new PointLightSource( new Vector3d( 5.0, 3.0, -3.0 ), 1.0 ) );

              // --- NODE DEFINITIONS ----------------------------------------------------

              // Latvian flag (intersection, difference and xor):
              CSGInnerNode latvia = new CSGInnerNode( SetOperation.Intersection );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 } );
              latvia.InsertChild( c, Matrix4d.Scale( 4.0, 2.0, 0.4 ) * Matrix4d.CreateTranslation( -2.0, -1.0, 0.0 ) );
              CSGInnerNode latviaFlag = new CSGInnerNode( SetOperation.Xor );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 } );
              latviaFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 2.0, 2.0 ) );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } );
              latviaFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.2, 0.5, 0.5 ) );
              latvia.InsertChild( latviaFlag, Matrix4d.Identity );
              flags.InsertChild( latvia, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateRotationX( Math.PI / 8 ) * Matrix4d.CreateTranslation( -3.5, 1.5, 0.0 ) );

              // Czech flag (difference):
              CSGInnerNode czech = new CSGInnerNode( SetOperation.Difference );
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 0.2, 0.2, 0.2 } );
              czech.InsertChild( s, Matrix4d.Identity );
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } );
              czech.InsertChild( s, Matrix4d.CreateTranslation( 0.0, 0.8, -1.0 ) );
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } );
              czech.InsertChild( s, Matrix4d.CreateTranslation( 0.0, -0.8, -1.1 ) );
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } );
              czech.InsertChild( s, Matrix4d.CreateTranslation( -1.0, 0.0, -0.8 ) );
              flags.InsertChild( czech, Matrix4d.Scale( 1.6, 1.0, 1.0 ) * Matrix4d.CreateRotationY( Math.PI / 8 ) *
                                Matrix4d.CreateTranslation( 4.0, -1.5, 0.0 ) );

              // Croatian flag (union, intersection):
              CSGInnerNode croatianFlag = new CSGInnerNode( SetOperation.Union );
              CSGInnerNode croatianSign = new CSGInnerNode( SetOperation.Intersection );
              CSGInnerNode checkerBoard = new CSGInnerNode( SetOperation.Union );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } );
              c.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 10.0, 10.0, new double[] { 1.0, 1.0, 1.0 } ) );
              croatianSign.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 2.0, 2.0, 0.4 ) );
              CSGInnerNode sign = new CSGInnerNode( SetOperation.Union );
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } );
              sign.InsertChild( s, Matrix4d.Identity );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } );
              sign.InsertChild( c, Matrix4d.Scale( 1.8 ) * Matrix4d.CreateTranslation( -0.9, 0.1, -0.9 ) );
              croatianSign.InsertChild( sign, Matrix4d.Scale( 0.5, 0.33, 0.5 ) * Matrix4d.CreateTranslation( 0.44, -0.5, 0.0 ) );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } );
              croatianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 0.6, 0.6 ) *
                                   Matrix4d.RotateX( Math.PI / 4 ) * Matrix4d.CreateTranslation( 0.5, 1.0, 1.0 ) );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } );
              croatianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 0.6, 0.6 ) *
                                   Matrix4d.RotateX( Math.PI / 4 ) * Matrix4d.CreateTranslation( 0.5, 0.3, 1.0 ) );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } );
              croatianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 0.6, 0.6 ) *
                                   Matrix4d.RotateX( Math.PI / 4 ) * Matrix4d.CreateTranslation( 0.5, -0.4, 1.0 ) );
              croatianFlag.InsertChild( croatianSign, Matrix4d.Scale( 0.8 ) * Matrix4d.CreateTranslation( 0.4, 0.5, 0.0 ) );
              flags.InsertChild( croatianFlag, Matrix4d.Scale( 0.8 ) * Matrix4d.CreateRotationY( Math.PI / 8 ) * Matrix4d.CreateTranslation( -0.4, 1.5, 1.0 ) );

              // Brazilian flag (union):
              CSGInnerNode brazilianFlag = new CSGInnerNode( SetOperation.Union );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.8, 0.0 } );
              brazilianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 2.0, 0.2 ) );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 0.0 } );
              brazilianFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.CreateRotationZ( Math.PI / 4 ) *
                                    Matrix4d.Scale( 2.0, 1.0, 0.4 ) );
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } );
              brazilianFlag.InsertChild( s, Matrix4d.Scale( 0.5 ) * Matrix4d.CreateTranslation( 0.0, 0.0, 0.0 ) );
              flags.InsertChild( brazilianFlag, Matrix4d.Scale( 0.9 ) * Matrix4d.RotateY( -Math.PI / 8 ) * Matrix4d.CreateTranslation( 0.0, -1.8, 1.0 ) );

              // Finnish flag (intersection and difference):
              CSGInnerNode finlandFlag = new CSGInnerNode( SetOperation.Difference );
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } );
              finlandFlag.InsertChild( s, Matrix4d.Scale( 2.0, 1.0, 0.5 ) * Matrix4d.CreateTranslation( 0.0, 0.0, 0.3 ) );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } );
              finlandFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.2, 0.5, 0.5 ) );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } );
              finlandFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 0.5, 4.2, 0.5 ) * Matrix4d.CreateTranslation( -0.5, 0.0, 0.0 ) );
              flags.InsertChild( finlandFlag, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateTranslation( 3.5, 1.5, 0.0 ) );

              // Cuban flag (union and intersection):
              CSGInnerNode cubanFlag = new CSGInnerNode( SetOperation.Union );
              for ( int i = 0; i < 5; i++ )
              {
            c = new Cube();
            if ( i % 2 == 0 )
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.0, 1.0 } );
            else
              c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 1.0, 1.0 } );
            cubanFlag.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 4.0, 0.4, 0.4 ) *
                                  Matrix4d.CreateTranslation( new Vector3d( 0.0, 0.0 - i * 0.4, 0.8 - i * 0.2 ) ) );
              }
              CSGInnerNode wedge = new CSGInnerNode( SetOperation.Intersection );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } );
              wedge.InsertChild( c, Matrix4d.CreateTranslation( -0.5, -0.5, -0.5 ) * Matrix4d.Scale( 2.0, 2.0, 2.0 ) *
                            Matrix4d.CreateRotationZ( Math.PI / 4 ) );
              c = new Cube();
              c.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.0, 0.0 } );
              wedge.InsertChild( c, Matrix4d.Scale( 4.0 ) * Matrix4d.CreateTranslation( 0.0, -2.0, -2.0 ) );
              cubanFlag.InsertChild( wedge, Matrix4d.Scale( 0.7 ) * Matrix4d.CreateTranslation( -2.0001, -0.8, 0.4999 ) );
              flags.InsertChild( cubanFlag, Matrix4d.Scale( 0.7 ) * Matrix4d.RotateY( Math.PI / 8 ) * Matrix4d.CreateTranslation( -4.0, -1.0, 0.0 ) );
        }
示例#10
0
        /// <summary>
        /// Simple scene containing five colored spheres.
        /// </summary>
        public static void FiveBalls( IRayScene sc )
        {
            Debug.Assert( sc != null );

              // CSG scene:
              CSGInnerNode root = new CSGInnerNode( SetOperation.Union );
              root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.5, 0.5, 0.5 }, 0.1, 0.6, 0.3, 16 ) );
              sc.Intersectable = root;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.05, 0.05 };

              // Camera:
              sc.Camera = new StaticCamera( new Vector3d( 0.0, 0.0, -10.0 ),
                                    new Vector3d( 0.0, 0.0, 1.0 ),
                                    60.0 );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 0.8 ) );
              sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 1.0 ) );

              // --- NODE DEFINITIONS ----------------------------------------------------

              // sphere 1:
              Sphere s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.6, 0.0 } );
              root.InsertChild( s, Matrix4d.Identity );

              // sphere 2:
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 0.2, 0.9, 0.5 } );
              root.InsertChild( s, Matrix4d.CreateTranslation( -2.2, 0.0, 0.0 ) );

              // sphere 3:
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 0.1, 0.3, 1.0 } );
              root.InsertChild( s, Matrix4d.CreateTranslation( -4.4, 0.0, 0.0 ) );

              // sphere 4:
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1.0, 0.2, 0.2 } );
              root.InsertChild( s, Matrix4d.CreateTranslation( 2.2, 0.0, 0.0 ) );

              // sphere 5:
              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 0.1, 0.4, 0.0 } );
              s.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 80.0, 40.0, new double[] { 1.0, 0.8, 0.2 } ) );
              root.InsertChild( s, Matrix4d.CreateTranslation( 4.4, 0.0, 0.0 ) );
        }
示例#11
0
        protected static CSGInnerNode test6Spheres( SetOperation op )
        {
            // scene:
              CSGInnerNode root = new CSGInnerNode( op );

              Sphere s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 1 } );
              root.InsertChild( s, Matrix4d.Scale( 2 ) );

              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 0.5, 0.8, 0.2 } );
              root.InsertChild( s, Matrix4d.CreateTranslation( 0, 0, -2 ) );

              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 0 } );
              root.InsertChild( s, Matrix4d.CreateTranslation( 0, 1, -0.5 ) );

              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 0 } );
              root.InsertChild( s, Matrix4d.CreateTranslation( 1, 0, -0.5 ) );

              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 0 } );
              root.InsertChild( s, Matrix4d.CreateTranslation( 0, -1, -0.5 ) );

              s = new Sphere();
              s.SetAttribute( PropertyName.COLOR, new double[] { 1, 0.3, 0 } );
              root.InsertChild( s, Matrix4d.CreateTranslation( -1, 0, -0.5 ) );

              return root;
        }
示例#12
0
		/// <summary>
		/// Read collision file from file<para/>
		/// Чтение файлов коллизий из файла
		/// </summary>
		/// <param name="filename">File name<para/>Имя файла</param>
		public CollisionFile(string filename) {
			if (!File.Exists(filename)) {
				throw new FileNotFoundException("[CollisionFile] File not found: "+Path.GetFileName(filename), filename);
			}

			// Opening reader
			// Открытие ридера
			Collisions = new List<Group>();
			BinaryReader f = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read), Encoding.ASCII);

			// Read all the models
			// Чтение всех моделей
			while (f.BaseStream.Position<f.BaseStream.Length-1) {

				// Reading header
				// Чтение заголовка
				string header = new string(f.ReadChars(4));
				if (header != "COLL") {
					throw new Exception("[CollisionFile] Unknown collision format: "+header);
				}
				f.BaseStream.Position += 4;

				// Creating new group
				// Создание новой группы
				Group c = new Group();
				
				// Reading collision head
				// Чтение оглавления файла
				c.Name = f.ReadVCString(22).ToLower();
				c.ID = f.ReadUInt16();

				// Reading bounds
				// Чтение габаритов
				c.BoundsRadius = f.ReadSingle();
				c.BoundsCenter = f.ReadVCVector();
				c.BoundsMin = f.ReadVCVector();
				c.BoundsMax = f.ReadVCVector();

				// Reading objects
				// Чтение объектов
				int numSpheres = f.ReadInt32();
				if (numSpheres>0) {
					// Spheres
					// Сферы
					c.Spheres = new Sphere[numSpheres];
					for (int i = 0; i < numSpheres; i++) {
						Sphere s = new Sphere();
						s.Radius = f.ReadSingle();
						s.Center = f.ReadVCVector();
						s.ReadParams(f);
						c.Spheres[i] = s;
					}
				}

				// Skip unknown index
				// Пропуск неизвестного числа
				f.BaseStream.Position += 4;

				int numBoxes = f.ReadInt32();
				if (numBoxes>0) {
					// Boxes
					// Боксы
					c.Boxes = new Box[numBoxes];
					for (int i = 0; i < numBoxes; i++) {
						Box b = new Box();
						b.Min = f.ReadVCVector();
						b.Max = f.ReadVCVector();
						b.ReadParams(f);
						c.Boxes[i] = b;
					}
				}

				int numVerts = f.ReadInt32();
				if (numVerts>0) {
					// Vertices and triangles
					// Вершины и треугольники
					c.Vertices = new Vector3[numVerts];
					for (int i = 0; i < numVerts; i++) {
						c.Vertices[i] = f.ReadVCVector();
					}

					// Reading trimeshes
					// Чтение тримешей
					int indexCount = f.ReadInt32();
					List<int>[] indices = new List<int>[SurfaceMaterialsCount];
					int meshCount = 0;
					for (int i = 0; i < indexCount; i++) {
						// Reading single tri
						// Чтение треугольника
						int v0 = f.ReadInt32();
						int v1 = f.ReadInt32();
						int v2 = f.ReadInt32();
						int mat = f.ReadByte();
						f.BaseStream.Position += 3;

						// Determining surf
						// Поиск поверхности
						if (indices[mat]==null) {
							indices[mat] = new List<int>();
							meshCount++;
						}
						indices[mat].AddRange(new int[]{ v0, v1, v2 });
					}

					// Storing trimeshes
					// Сохранение тримешей
					c.Meshes = new Trimesh[meshCount];
					int p = 0;
					for (int i = 0; i < indices.Length; i++) {
						if (indices[i]!=null) {
							c.Meshes[p] = new Trimesh() {
								Flags = 0,
								Material = (byte)i,
								Indices = indices[i].ToArray()
							};
							p++;
						}
					}
				}else{
					// Skip indices - they are empty
					// Пропуск индексов - они пустые
					f.BaseStream.Position += 4;
				}

				// Store mesh
				// Сохранение меша
				if (c.Spheres != null || c.Boxes != null || c.Meshes !=null) {
					Collisions.Add(c);
				}

				// Give prior to main thread
				// Отдаём предпочтение основному потоку
				System.Threading.Thread.Sleep(0);
			}

			// Closing reader
			// Закрытие потока
			f.Close();
		}
示例#13
0
        public LensRayTransferFunction.Parameters ConvertSurfaceRayToParameters(
            Ray ray,
            Vector3d canonicalNormal, double surfaceSinTheta,
            Sphere sphericalSurface, ElementSurface surface)
        {
            //Console.WriteLine("ray->parameters");
            // - convert origin
            //   *- transform to hemispherical coordinates
            //     - find out if it is on the surface
            //   *- scale with respect to the spherical cap
            //   *- normalize
            Vector3d unitSpherePos = (ray.Origin - sphericalSurface.Center) * sphericalSurface.RadiusInv;
            unitSpherePos.Z *= canonicalNormal.Z;
            //Console.WriteLine("unit sphere position: {0}", unitSpherePos);
            Vector2d originParametric = Sampler.SampleSphereWithUniformSpacingInverse(
                unitSpherePos, surfaceSinTheta, 1);

            // - convert direction
            //   *- transform from camera space to local frame
            //     *- compute normal at origin

            //Console.WriteLine("ray origin: {0}", ray.Origin);
            Vector3d normalLocal = surface.SurfaceNormalField.GetNormal(ray.Origin);
            normalLocal.Normalize(); // TODO: check if it is unnecessary
            //Console.WriteLine("local normal: {0}", normalLocal);
            //     *- create rotation quaternion from canonical normal to local
            //       normal
            Vector3d direction = ray.Direction;
            //Console.WriteLine("local direction: {0}", direction);
            if (surface.Convex)
            {
                direction = -direction;
            }
            Vector3d rotationAxis = Vector3d.Cross(canonicalNormal, normalLocal);

            //Console.WriteLine("rotation axis: {0}", rotationAxis);
            if (rotationAxis.Length > 0)
            {
                double angle = Math.Acos(Vector3d.Dot(normalLocal, canonicalNormal));
                //Console.WriteLine("angle: {0}", angle);
                double positionPhi = originParametric.Y;
                // first transformed to the frame of the local normal
                //Console.WriteLine("position phi: {0}", positionPhi);
                Matrix4d rotMatrix = Matrix4d.CreateFromAxisAngle(rotationAxis, -angle);
                // then rotate the local direction around Z using the position phi
                rotMatrix = rotMatrix * Matrix4d.CreateRotationZ(2 * Math.PI * -positionPhi);
                direction = Vector3d.Transform(direction, rotMatrix);
            }
            //Console.WriteLine("abs. direction: {0}", direction);

            //   *- transform to hemispherical coordinates
            //     - find out if it is within the local hemisphere
            double sinTheta = direction.Z / canonicalNormal.Z;
            double dirTheta = Math.Asin(sinTheta);

            double cosTheta = Math.Sqrt(1 - sinTheta * sinTheta);
            double dirPhi = Math.Atan2(direction.Y, direction.X);
            if (dirPhi < 0)
            {
                // map [-PI; PI] to [0; 2*PI]
                dirPhi += 2 * Math.PI;
            }
            //   *- normalize
            Vector2d directionParametric = new Vector2d(
                dirTheta / (0.5 * Math.PI),
                dirPhi / (2 * Math.PI));

            //Console.WriteLine("position parameters: {0}", new Vector2d(
            //    originParametric.X, originParametric.Y));

            return new LensRayTransferFunction.Parameters(
                originParametric.X, originParametric.Y,
                directionParametric.X, directionParametric.Y);
        }
示例#14
0
        /// <summary>
        /// Convert a ray with origin at the back or front lens surface from
        /// its parametric representation.
        /// </summary>
        /// <param name="position">Position on lens surface in parameteric
        /// representation (normalized hemispherical coordinates).</param>
        /// <param name="direction">Direction of the ray with respect to the
        /// local frame in parameteric representation (normalized hemispherical
        /// coordinates).
        /// </param>
        /// <param name="canonicalNormal">Normal of the lens surface
        /// hemisphere (typically (0,0,1) for the back surface or (0,0,-1) for
        /// the front surface).</param>
        /// <param name="surfaceSinTheta">Sine of the surface spherical cap
        /// theta angle.</param>
        /// <param name="sphericalSurface">Lens surface represented as a
        /// sphere.</param>
        /// <param name="surface">Lens surface with its normal field.</param>
        /// <returns>Ray corresponding to its parametric representation.
        /// </returns>
        public Ray ConvertParametersToSurfaceRay(
            LensRayTransferFunction.Parameters parameters,
            Vector3d canonicalNormal, double surfaceSinTheta,
            Sphere sphericalSurface, ElementSurface surface)
        {
            //Console.WriteLine("parameters->ray");

            //Console.WriteLine("position parameters: {0}", parameters.Position);
            // uniform spacing sampling for LRTF sampling
            Vector3d unitSpherePos = Sampler.SampleSphereWithUniformSpacing(
                parameters.Position, surfaceSinTheta, 1);
            //Console.WriteLine("unit sphere position: {0}", unitSpherePos);
            unitSpherePos.Z *= canonicalNormal.Z;

            Vector3d lensPos = sphericalSurface.Center + sphericalSurface.Radius * unitSpherePos;
            //Console.WriteLine("ray origin: {0}", lensPos);

            // - get normal N at P
            Vector3d normalLocal = surface.SurfaceNormalField.GetNormal(lensPos);
            // - compute direction D from spherical coordinates (wrt normal Z = (0,0,+/-1))
            double theta = 0.5 * Math.PI * parameters.DirectionTheta;
            double phi = 2 * Math.PI * parameters.DirectionPhi;
            double cosTheta = Math.Cos(theta);
            Vector3d directionZ = new Vector3d(
                Math.Cos(phi) * cosTheta,
                Math.Sin(phi) * cosTheta,
                Math.Sin(theta) * canonicalNormal.Z);
            // - rotate D from Z to N frame
            //   - using a (normalized) quaternion Q
            //   - N and Z should be assumed to be already normalized
            //   - more efficient method: Efficiently building a matrix to
            //     rotate one vector to another [moller1999]

            normalLocal.Normalize(); // TODO: check if it is unnecessary
            //Console.WriteLine("abs. direction: {0}", directionZ);
            //Console.WriteLine("local normal: {0}", normalLocal);
            Vector3d rotationAxis = Vector3d.Cross(canonicalNormal, normalLocal);
            //Console.WriteLine("rotation axis: {0}", rotationAxis);

            Vector3d rotatedDir = directionZ;
            if (rotationAxis.Length > 0)
            {
                double angle = Math.Acos(Vector3d.Dot(canonicalNormal, normalLocal));
                //Console.WriteLine("angle: {0}", angle);
                // first the local direction must be rotated around using the position phi!
                //Console.WriteLine("position phi: {0}", parameters.PositionPhi);
                Matrix4d rotMatrix = Matrix4d.CreateRotationZ(2 * Math.PI * parameters.PositionPhi);
                // only then can be transformed to the frame of the local normal
                rotMatrix = rotMatrix * Matrix4d.CreateFromAxisAngle(rotationAxis, angle);
                rotatedDir = Vector3d.Transform(directionZ, rotMatrix);
            }
            if (surface.Convex)
            {
                rotatedDir = -rotatedDir;
            }
            //Console.WriteLine("local direction: {0}", rotatedDir);

            Ray result = new Ray(lensPos, rotatedDir);
            return result;
        }
示例#15
0
        public static ComplexLens CreateBiconvexLens(
            double curvatureRadius,
            double apertureRadius,
            double thickness)
        {
            var surfaces = new List<ComplexLens.ElementSurface>();
            Sphere backSphere = new Sphere()
            {
                Radius = curvatureRadius,
            };
            backSphere.Center = backSphere.GetCapCenter(apertureRadius, -Vector3d.UnitZ);
            backSphere.Center += new Vector3d(0, 0, thickness);
            surfaces.Add(new ComplexLens.ElementSurface()
            {
                ApertureRadius = apertureRadius,
                NextRefractiveIndex = Materials.Fixed.GLASS_CROWN_K7,
                Surface = backSphere,
                SurfaceNormalField = backSphere,
                Convex = true
            });
            Sphere frontSphere = new Sphere()
            {
                Radius = curvatureRadius,
            };
            frontSphere.Center = frontSphere.GetCapCenter(apertureRadius, Vector3d.UnitZ);
            surfaces.Add(new ComplexLens.ElementSurface()
            {
                ApertureRadius = apertureRadius,
                Surface = frontSphere,
                SurfaceNormalField = frontSphere,
                Convex = false
            });

            ComplexLens lens = new ComplexLens(surfaces);
            return lens;
        }
示例#16
0
        /// <summary>
        /// Creates a new instance of a complex lens using a definition of
        /// elements.
        /// </summary>
        /// <remarks>
        /// The first and last surfaces have to be spherical. TODO: this is
        /// needed only for simpler sampling. In general planar surfaces or
        /// stops could be sampled too.
        /// </remarks>
        /// <param name="surfaceDefs">List of definitions of spherical or
        /// planar element surfaces or stops. Ordered from front to back.
        /// Must not be empty or null.
        /// </param>
        /// <param name="mediumRefractiveIndex">Index of refraction of medium
        /// outside the lens. It is assumed there is one medium on the scene
        /// side, senzor side and inside the lens.</param>
        /// <returns>The created complex lens instance.</returns>
        public static ComplexLens Create(
            IList<SphericalElementSurfaceDefinition> surfaceDefs,
            double mediumRefractiveIndex,
            double scale)
        {
            var surfaces = new List<ElementSurface>();

            var surfaceDefsReverse = surfaceDefs.Reverse().ToList();
            // scale the lens if needed
            if (Math.Abs(scale - 1.0) > epsilon)
            {
                surfaceDefsReverse = surfaceDefsReverse.Select(surface => surface.Scale(scale)).ToList();
            }
            // thickness of the whole lens (from front to back apex)
            // (without the distance to the senzor - backmost surface def.)
            double lensThickness = surfaceDefsReverse.Skip(1).Sum(def => def.Thickness);
            double elementBasePlaneShiftZ = lensThickness;

            double lastCapHeight = 0;
            double capHeight = 0;

            // definition list is ordered from front to back, working list
            // must be ordered from back to front, so a conversion has to be
            // performed
            int defIndex = 0;
            foreach (var definition in surfaceDefsReverse)
            {
                if (defIndex > 0)
                {
                    elementBasePlaneShiftZ -= definition.Thickness;
                }

                ElementSurface surface = new ElementSurface();
                surface.ApertureRadius = 0.5 * definition.ApertureDiameter;
                if (defIndex + 1 < surfaceDefsReverse.Count)
                {
                    surface.NextRefractiveIndex = surfaceDefsReverse[defIndex + 1].NextRefractiveIndex;
                }
                else
                {
                    surface.NextRefractiveIndex = mediumRefractiveIndex;
                }
                if (definition.CurvatureRadius.HasValue)
                {
                    // spherical surface
                    double radius = definition.CurvatureRadius.Value;
                    // convexity reverses when converting from front-to-back
                    // back-to-front ordering
                    surface.Convex = radius < 0;
                    Sphere sphere = new Sphere()
                    {
                        Radius = Math.Abs(radius)
                    };
                    sphere.Center = Math.Sign(radius) *
                        sphere.GetCapCenter(surface.ApertureRadius, Vector3d.UnitZ);
                    capHeight = Math.Sign(radius) * sphere.GetCapHeight(sphere.Radius, surface.ApertureRadius);
                    elementBasePlaneShiftZ -= lastCapHeight - capHeight;
                    sphere.Center += new Vector3d(0, 0, elementBasePlaneShiftZ);
                    surface.Surface = sphere;
                    surface.SurfaceNormalField = sphere;
                }
                else
                {
                    // planar surface
                    // both media are the same -> circular stop
                    // else -> planar element surface
                    surface.NextRefractiveIndex = definition.NextRefractiveIndex;
                    surface.Convex = true;
                    capHeight = 0;
                    elementBasePlaneShiftZ -= lastCapHeight - capHeight;
                    Circle circle = new Circle()
                    {
                        Radius = 0.5 * definition.ApertureDiameter,
                        Z = elementBasePlaneShiftZ,
                    };

                    surface.Surface = circle;
                    surface.SurfaceNormalField = circle;
                }
                lastCapHeight = capHeight;
                surfaces.Add(surface);
                defIndex++;
            }

            //DEBUG
            //foreach (var surface in surfaces)
            //{
            //    Console.WriteLine("{0}, {1}, {2}", surface.ApertureRadius,
            //        surface.Convex, surface.NextRefractiveIndex);
            //}

            ComplexLens lens = new ComplexLens(surfaces)
            {
                MediumRefractiveIndex = mediumRefractiveIndex
            };
            return lens;
        }