public void TestExampleBreastTomosynthesisMedialLateral()
        {
            var factory = new VolumeSliceFactory();

            var volume = MockVolumeReference.Create(
                new Size3D(1800, 2200, 56),
                new Vector3D(0.08f, 0.08f, 1),
                new Vector3D(0, 0, 0),
                new Matrix3D(new float[, ] {
                { 0, 1, 0 }, { 0, 0, 1 }, { 1, 0, 0 }
            }));

            var slices = factory.CreateSlices(volume);

            Assert.AreEqual(57, slices.Count, "SliceCount (right-oriented volume)");
            for (var n = 0; n < 57; ++n)
            {
                AssertVolumeSlice(slices[n], 2200, 1800, new Vector3D(n, 0, 0), new Vector3D(0, 1, 0), new Vector3D(0, 0, 1), 0.08f, 0.08f, 1, 1, "right-oriented volume @n={0}", n);
            }

            volume = MockVolumeReference.Create(
                new Size3D(1800, 2200, 56),
                new Vector3D(0.08f, 0.08f, 1),
                new Vector3D(0, 0, 0),
                new Matrix3D(new float[, ] {
                { 0, 1, 0 }, { 0, 0, 1 }, { -1, 0, 0 }
            }));

            slices = factory.CreateSlices(volume);
            Assert.AreEqual(57, slices.Count, "SliceCount (left-oriented volume)");
            for (var n = 0; n < 57; ++n)
            {
                AssertVolumeSlice(slices[56 - n], 2200, 1800, new Vector3D(-n, 0, 0), new Vector3D(0, 1, 0), new Vector3D(0, 0, 1), 0.08f, 0.08f, 1, 1, "left-oriented volume @n={0}", n);
            }
        }
		public void TestBasicIdentitySlicing()
		{
			var factory = new VolumeSliceFactory();

			var volume = MockVolumeReference.Create(
				new Size3D(200, 200, 100),
				new Vector3D(0.5f, 0.5f, 1),
				new Vector3D(0, 0, 0),
				Matrix3D.GetIdentity());

			var slice = factory.CreateSlice(volume, new Vector3D(50, 50, 50.5f));
			AssertVolumeSlice(slice, 200, 200, new Vector3D(0, 0, 50.5f), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, null, "single");

			var slices = factory.CreateSlices(volume);
			Assert.AreEqual(101, slices.Count, "SliceCount (full stack)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "full stack @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f));
			Assert.AreEqual(101, slices.Count, "SliceCount (ref pos)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "ref pos @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), 10);
			Assert.AreEqual(10, slices.Count, "SliceCount (exact count)");
			for (var n = 0; n < 10; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "exact count @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 59.5f));
			Assert.AreEqual(10, slices.Count, "SliceCount (exact multiple)");
			for (var n = 0; n < 10; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "exact multiple @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 60));
			Assert.AreEqual(10, slices.Count, "SliceCount (round down)");
			for (var n = 0; n < 10; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "round down @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 60.49f));
			Assert.AreEqual(11, slices.Count, "SliceCount (round up)");
			for (var n = 0; n < 11; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "round up @n={0}", n);
		}
        public void TestFixedSliceSpacingAndThickness()
        {
            const float sliceSpacing = 0.9f;
            var         factory      = new VolumeSliceFactory {
                SliceSpacing = sliceSpacing, SliceThickness = 1f
            };

            var volume = MockVolumeReference.Create(
                new Size3D(200, 200, 100),
                new Vector3D(0.5f, 0.5f, 1),
                new Vector3D(0, 0, 0),
                Matrix3D.GetIdentity());

            var slice = factory.CreateSlice(volume, new Vector3D(50, 50, 50.5f));

            AssertVolumeSlice(slice, 200, 200, new Vector3D(0, 0, 50.5f), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, null, "single");

            var slices = factory.CreateSlices(volume);

            Assert.AreEqual(112, slices.Count, "SliceCount (full stack)");
            for (var n = 0; n < 112; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 0.05f + n * sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "full stack @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f));
            Assert.AreEqual(112, slices.Count, "SliceCount (ref pos)");
            for (var n = 0; n < 112; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 0.05f + n * sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "ref pos @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), 10);
            Assert.AreEqual(10, slices.Count, "SliceCount (exact count)");
            for (var n = 0; n < 10; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n * sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "exact count @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 58.5f));
            Assert.AreEqual(10, slices.Count, "SliceCount (exact multiple)");
            for (var n = 0; n < 10; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n * sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "exact multiple @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 59));
            Assert.AreEqual(10, slices.Count, "SliceCount (round down)");
            for (var n = 0; n < 10; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n * sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "round down @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 59.49f));
            Assert.AreEqual(11, slices.Count, "SliceCount (round up)");
            for (var n = 0; n < 11; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n * sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "round up @n={0}", n);
            }
        }
        public void TestFixedPixelSpacingWithSliceExtentPixels()
        {
            var volume = MockVolumeReference.Create(
                new Size3D(200, 200, 100),
                new Vector3D(0.5f, 0.5f, 1),
                new Vector3D(0, 0, 0),
                Matrix3D.GetIdentity());

            var factory = new VolumeSliceFactory {
                ColumnSpacing = 1f, Columns = 80
            };

            var slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));

            Assert.AreEqual(101, slices.Count, "SliceCount (fixed column spacing)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 100, 80, new Vector3D(-5, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 1, 1, 1, 1, "fixed column spacing @n={0}", n);
            }

            factory = new VolumeSliceFactory {
                RowSpacing = 1f, Rows = 40
            };
            slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
            Assert.AreEqual(101, slices.Count, "SliceCount (fixed row spacing)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 40, 100, new Vector3D(0, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 1, 1, 1, 1, "fixed row spacing @n={0}", n);
            }

            factory = new VolumeSliceFactory {
                ColumnSpacing = 1f, RowSpacing = 1f, Columns = 80, Rows = 40
            };
            slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
            Assert.AreEqual(101, slices.Count, "SliceCount (fixed pixel spacing)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 40, 80, new Vector3D(-5, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 1, 1, 1, 1, "fixed pixel spacing @n={0}", n);
            }

            // the factory never generates anisotropic output unless explicitly requested
            factory = new VolumeSliceFactory {
                ColumnSpacing = 1f, RowSpacing = 0.5f, Columns = 80, Rows = 80
            };
            slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
            Assert.AreEqual(101, slices.Count, "SliceCount (explicit anisotropic spacing)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 80, 80, new Vector3D(-5, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 1, 1, 1, "explicit anisotropic spacing @n={0}", n);
            }
        }
        public void TestBasicIdentitySlicing()
        {
            var factory = new VolumeSliceFactory();

            var volume = MockVolumeReference.Create(
                new Size3D(200, 200, 100),
                new Vector3D(0.5f, 0.5f, 1),
                new Vector3D(0, 0, 0),
                Matrix3D.GetIdentity());

            var slice = factory.CreateSlice(volume, new Vector3D(50, 50, 50.5f));

            AssertVolumeSlice(slice, 200, 200, new Vector3D(0, 0, 50.5f), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, null, "single");

            var slices = factory.CreateSlices(volume);

            Assert.AreEqual(101, slices.Count, "SliceCount (full stack)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "full stack @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f));
            Assert.AreEqual(101, slices.Count, "SliceCount (ref pos)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "ref pos @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), 10);
            Assert.AreEqual(10, slices.Count, "SliceCount (exact count)");
            for (var n = 0; n < 10; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "exact count @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 59.5f));
            Assert.AreEqual(10, slices.Count, "SliceCount (exact multiple)");
            for (var n = 0; n < 10; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "exact multiple @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 60));
            Assert.AreEqual(10, slices.Count, "SliceCount (round down)");
            for (var n = 0; n < 10; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "round down @n={0}", n);
            }

            slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 60.49f));
            Assert.AreEqual(11, slices.Count, "SliceCount (round up)");
            for (var n = 0; n < 11; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "round up @n={0}", n);
            }
        }
        public void TestBasicObliqueSlicing()
        {
            const float root2     = 1.4142135623730950488016887242097f;
            const float halfRoot2 = root2 / 2;

            var volume = MockVolumeReference.Create(
                new Size3D(160, 200, 100),
                new Vector3D(0.625f, 0.5f, 1),
                new Vector3D(0, 0, 0),
                Matrix3D.GetIdentity());

            // case 1 - stack axis {0,0,1}, stack depth is 100
            {
                const int expectedSliceCount = 101;                 // 100 + 1

                var factory = new VolumeSliceFactory {
                    RowOrientationPatient = new Vector3D(1, 1, 0), ColumnOrientationPatient = new Vector3D(-1, 1, 0)
                };
                var slices = factory.CreateSlices(volume);
                Assert.AreEqual(expectedSliceCount, slices.Count, "SliceCount (case 1)");
                for (var n = 0; n < expectedSliceCount; ++n)
                {
                    const int expectedDimension = (int)(root2 * 200 + 0.5f);                    // 283
                    AssertVolumeSlice(slices[n], expectedDimension, expectedDimension, new Vector3D(50, -50, n), new Vector3D(halfRoot2, halfRoot2, 0), new Vector3D(-halfRoot2, halfRoot2, 0), 0.5f, 0.5f, 1, 1, "case 1 @n={0}", n);
                }
            }

            // case 2 - stack axis {-1,1,0}, stack depth is 100*root(2), computed spacing should be sqrt(0.625^2 + 0.5^2)=0.800...
            {
                const float expectedSpacing    = 0.795495f;              // spacing should really be 0.8, but apparently the floating point error caught up
                const int   expectedSliceCount = (int)(100 * root2 / expectedSpacing + 1.5);

                var factory = new VolumeSliceFactory {
                    RowOrientationPatient = new Vector3D(1, 1, 0), ColumnOrientationPatient = new Vector3D(0, 0, 1)
                };
                var slices = factory.CreateSlices(volume);
                Assert.AreEqual(expectedSliceCount, slices.Count, "SliceCount (case 2)");
                for (var n = 0; n < expectedSliceCount; ++n)
                {
                    const int expectedRows    = 200;
                    const int expectedColumns = (int)(root2 * 200 + 0.5f);                    // 283
                    AssertVolumeSlice(slices[n], expectedRows, expectedColumns, new Vector3D(-50.0625f + n * 0.5625f, 50.0625f - n * 0.5625f, 0), new Vector3D(halfRoot2, halfRoot2, 0), new Vector3D(0, 0, 1), 0.5f, 0.5f, expectedSpacing, expectedSpacing, "case 2 @n={0}", n);
                }
            }
        }
        public void TestFixedSliceExtentPixels()
        {
            var volume = MockVolumeReference.Create(
                new Size3D(200, 200, 100),
                new Vector3D(0.5f, 0.5f, 1),
                new Vector3D(0, 0, 0),
                Matrix3D.GetIdentity());

            var factory = new VolumeSliceFactory {
                Columns = 160, SliceWidth = 999999
            };

            var slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));

            Assert.AreEqual(101, slices.Count, "SliceCount (fixed width)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 160, new Vector3D(-5, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "fixed width @n={0}", n);
            }

            factory = new VolumeSliceFactory {
                Rows = 80, SliceHeight = 999999
            };
            slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
            Assert.AreEqual(101, slices.Count, "SliceCount (fixed height)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 80, 200, new Vector3D(0, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "fixed height @n={0}", n);
            }

            factory = new VolumeSliceFactory {
                Columns = 160, Rows = 80, SliceWidth = 999999, SliceHeight = 999999
            };
            slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
            Assert.AreEqual(101, slices.Count, "SliceCount (fixed size)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 80, 160, new Vector3D(-5, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "fixed size @n={0}", n);
            }
        }
		public void TestExampleBreastTomosynthesisMedialLateral()
		{
			var factory = new VolumeSliceFactory();

			var volume = MockVolumeReference.Create(
				new Size3D(1800, 2200, 56),
				new Vector3D(0.08f, 0.08f, 1),
				new Vector3D(0, 0, 0),
				new Matrix3D(new float[,] {{0, 1, 0}, {0, 0, 1}, {1, 0, 0}}));

			var slices = factory.CreateSlices(volume);
			Assert.AreEqual(57, slices.Count, "SliceCount (right-oriented volume)");
			for (var n = 0; n < 57; ++n)
				AssertVolumeSlice(slices[n], 2200, 1800, new Vector3D(n, 0, 0), new Vector3D(0, 1, 0), new Vector3D(0, 0, 1), 0.08f, 0.08f, 1, 1, "right-oriented volume @n={0}", n);

			volume = MockVolumeReference.Create(
				new Size3D(1800, 2200, 56),
				new Vector3D(0.08f, 0.08f, 1),
				new Vector3D(0, 0, 0),
				new Matrix3D(new float[,] {{0, 1, 0}, {0, 0, 1}, {-1, 0, 0}}));

			slices = factory.CreateSlices(volume);
			Assert.AreEqual(57, slices.Count, "SliceCount (left-oriented volume)");
			for (var n = 0; n < 57; ++n)
				AssertVolumeSlice(slices[56 - n], 2200, 1800, new Vector3D(-n, 0, 0), new Vector3D(0, 1, 0), new Vector3D(0, 0, 1), 0.08f, 0.08f, 1, 1, "left-oriented volume @n={0}", n);
		}
		public void TestFixedPixelSpacingWithSliceExtentPixels()
		{
			var volume = MockVolumeReference.Create(
				new Size3D(200, 200, 100),
				new Vector3D(0.5f, 0.5f, 1),
				new Vector3D(0, 0, 0),
				Matrix3D.GetIdentity());

			var factory = new VolumeSliceFactory {ColumnSpacing = 1f, Columns = 80};

			var slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
			Assert.AreEqual(101, slices.Count, "SliceCount (fixed column spacing)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 100, 80, new Vector3D(-5, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 1, 1, 1, 1, "fixed column spacing @n={0}", n);

			factory = new VolumeSliceFactory {RowSpacing = 1f, Rows = 40};
			slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
			Assert.AreEqual(101, slices.Count, "SliceCount (fixed row spacing)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 40, 100, new Vector3D(0, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 1, 1, 1, 1, "fixed row spacing @n={0}", n);

			factory = new VolumeSliceFactory {ColumnSpacing = 1f, RowSpacing = 1f, Columns = 80, Rows = 40};
			slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
			Assert.AreEqual(101, slices.Count, "SliceCount (fixed pixel spacing)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 40, 80, new Vector3D(-5, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 1, 1, 1, 1, "fixed pixel spacing @n={0}", n);

			// the factory never generates anisotropic output unless explicitly requested
			factory = new VolumeSliceFactory {ColumnSpacing = 1f, RowSpacing = 0.5f, Columns = 80, Rows = 80};
			slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
			Assert.AreEqual(101, slices.Count, "SliceCount (explicit anisotropic spacing)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 80, 80, new Vector3D(-5, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 1, 1, 1, "explicit anisotropic spacing @n={0}", n);
		}
		public void TestFixedSliceExtentPixels()
		{
			var volume = MockVolumeReference.Create(
				new Size3D(200, 200, 100),
				new Vector3D(0.5f, 0.5f, 1),
				new Vector3D(0, 0, 0),
				Matrix3D.GetIdentity());

			var factory = new VolumeSliceFactory {Columns = 160, SliceWidth = 999999};

			var slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
			Assert.AreEqual(101, slices.Count, "SliceCount (fixed width)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 200, 160, new Vector3D(-5, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "fixed width @n={0}", n);

			factory = new VolumeSliceFactory {Rows = 80, SliceHeight = 999999};
			slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
			Assert.AreEqual(101, slices.Count, "SliceCount (fixed height)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 80, 200, new Vector3D(0, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "fixed height @n={0}", n);

			factory = new VolumeSliceFactory {Columns = 160, Rows = 80, SliceWidth = 999999, SliceHeight = 999999};
			slices = factory.CreateSlices(volume, new Vector3D(35, 75, 50));
			Assert.AreEqual(101, slices.Count, "SliceCount (fixed size)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 80, 160, new Vector3D(-5, 55, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "fixed size @n={0}", n);
		}
		public void TestFixedSliceSpacingAndThickness()
		{
			const float sliceSpacing = 0.9f;
			var factory = new VolumeSliceFactory {SliceSpacing = sliceSpacing, SliceThickness = 1f};

			var volume = MockVolumeReference.Create(
				new Size3D(200, 200, 100),
				new Vector3D(0.5f, 0.5f, 1),
				new Vector3D(0, 0, 0),
				Matrix3D.GetIdentity());

			var slice = factory.CreateSlice(volume, new Vector3D(50, 50, 50.5f));
			AssertVolumeSlice(slice, 200, 200, new Vector3D(0, 0, 50.5f), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, null, "single");

			var slices = factory.CreateSlices(volume);
			Assert.AreEqual(112, slices.Count, "SliceCount (full stack)");
			for (var n = 0; n < 112; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 0.05f + n*sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "full stack @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f));
			Assert.AreEqual(112, slices.Count, "SliceCount (ref pos)");
			for (var n = 0; n < 112; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 0.05f + n*sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "ref pos @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), 10);
			Assert.AreEqual(10, slices.Count, "SliceCount (exact count)");
			for (var n = 0; n < 10; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n*sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "exact count @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 58.5f));
			Assert.AreEqual(10, slices.Count, "SliceCount (exact multiple)");
			for (var n = 0; n < 10; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n*sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "exact multiple @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 59));
			Assert.AreEqual(10, slices.Count, "SliceCount (round down)");
			for (var n = 0; n < 10; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n*sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "round down @n={0}", n);

			slices = factory.CreateSlices(volume, new Vector3D(50, 50, 50.5f), new Vector3D(50, 50, 59.49f));
			Assert.AreEqual(11, slices.Count, "SliceCount (round up)");
			for (var n = 0; n < 11; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, 50.5f + n*sliceSpacing), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, sliceSpacing, "round up @n={0}", n);
		}
		public void TestBasicObliqueSlicing()
		{
			const float root2 = 1.4142135623730950488016887242097f;
			const float halfRoot2 = root2/2;

			var volume = MockVolumeReference.Create(
				new Size3D(160, 200, 100),
				new Vector3D(0.625f, 0.5f, 1),
				new Vector3D(0, 0, 0),
				Matrix3D.GetIdentity());

			// case 1 - stack axis {0,0,1}, stack depth is 100
			{
				const int expectedSliceCount = 101; // 100 + 1

				var factory = new VolumeSliceFactory {RowOrientationPatient = new Vector3D(1, 1, 0), ColumnOrientationPatient = new Vector3D(-1, 1, 0)};
				var slices = factory.CreateSlices(volume);
				Assert.AreEqual(expectedSliceCount, slices.Count, "SliceCount (case 1)");
				for (var n = 0; n < expectedSliceCount; ++n)
				{
					const int expectedDimension = (int) (root2*200 + 0.5f); // 283
					AssertVolumeSlice(slices[n], expectedDimension, expectedDimension, new Vector3D(50, -50, n), new Vector3D(halfRoot2, halfRoot2, 0), new Vector3D(-halfRoot2, halfRoot2, 0), 0.5f, 0.5f, 1, 1, "case 1 @n={0}", n);
				}
			}

			// case 2 - stack axis {-1,1,0}, stack depth is 100*root(2), computed spacing should be sqrt(0.625^2 + 0.5^2)=0.800...
			{
				const float expectedSpacing = 0.795495f; // spacing should really be 0.8, but apparently the floating point error caught up
				const int expectedSliceCount = (int) (100*root2/expectedSpacing + 1.5);

				var factory = new VolumeSliceFactory {RowOrientationPatient = new Vector3D(1, 1, 0), ColumnOrientationPatient = new Vector3D(0, 0, 1)};
				var slices = factory.CreateSlices(volume);
				Assert.AreEqual(expectedSliceCount, slices.Count, "SliceCount (case 2)");
				for (var n = 0; n < expectedSliceCount; ++n)
				{
					const int expectedRows = 200;
					const int expectedColumns = (int) (root2*200 + 0.5f); // 283
					AssertVolumeSlice(slices[n], expectedRows, expectedColumns, new Vector3D(-50.0625f + n*0.5625f, 50.0625f - n*0.5625f, 0), new Vector3D(halfRoot2, halfRoot2, 0), new Vector3D(0, 0, 1), 0.5f, 0.5f, expectedSpacing, expectedSpacing, "case 2 @n={0}", n);
				}
			}
		}
		public void TestBasicOrthogonalSlicing()
		{
			var volume = MockVolumeReference.Create(
				new Size3D(160, 200, 100),
				new Vector3D(0.625f, 0.5f, 1),
				new Vector3D(0, 0, 0),
				Matrix3D.GetIdentity());

			var factory = new VolumeSliceFactory {RowOrientationPatient = new Vector3D(1, 0, 0), ColumnOrientationPatient = new Vector3D(0, 1, 0)};
			var slices = factory.CreateSlices(volume);
			Assert.AreEqual(101, slices.Count, "SliceCount (axial)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "axial @n={0}", n);

			factory = new VolumeSliceFactory {RowOrientationPatient = new Vector3D(1, 0, 0), ColumnOrientationPatient = new Vector3D(0, -1, 0)};
			slices = factory.CreateSlices(volume);
			Assert.AreEqual(101, slices.Count, "SliceCount (axial reverse)");
			for (var n = 0; n < 101; ++n)
				AssertVolumeSlice(slices[100 - n], 200, 200, new Vector3D(0, 100, n), new Vector3D(1, 0, 0), new Vector3D(0, -1, 0), 0.5f, 0.5f, 1, 1, "axial reverse @n={0}", n);

			factory = new VolumeSliceFactory {RowOrientationPatient = new Vector3D(1, 0, 0), ColumnOrientationPatient = new Vector3D(0, 0, -1)};
			slices = factory.CreateSlices(volume);
			Assert.AreEqual(201, slices.Count, "SliceCount (coronal)");
			for (var n = 0; n < 201; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, n*0.5f, 100), new Vector3D(1, 0, 0), new Vector3D(0, 0, -1), 0.5f, 0.5f, 0.5f, 0.5f, "coronal @n={0}", n);

			factory = new VolumeSliceFactory {RowOrientationPatient = new Vector3D(1, 0, 0), ColumnOrientationPatient = new Vector3D(0, 0, 1)};
			slices = factory.CreateSlices(volume);
			Assert.AreEqual(201, slices.Count, "SliceCount (coronal reverse)");
			for (var n = 0; n < 201; ++n)
				AssertVolumeSlice(slices[200 - n], 200, 200, new Vector3D(0, n*0.5f, 0), new Vector3D(1, 0, 0), new Vector3D(0, 0, 1), 0.5f, 0.5f, 0.5f, 0.5f, "coronal reverse @n={0}", n);

			factory = new VolumeSliceFactory {RowOrientationPatient = new Vector3D(0, 1, 0), ColumnOrientationPatient = new Vector3D(0, 0, 1)};
			slices = factory.CreateSlices(volume);
			Assert.AreEqual(161, slices.Count, "SliceCount (sagittal)");
			for (var n = 0; n < 161; ++n)
				AssertVolumeSlice(slices[n], 200, 200, new Vector3D(n*0.625f, 0, 0), new Vector3D(0, 1, 0), new Vector3D(0, 0, 1), 0.5f, 0.5f, 0.625f, 0.625f, "sagittal @n={0}", n);

			factory = new VolumeSliceFactory {RowOrientationPatient = new Vector3D(0, 1, 0), ColumnOrientationPatient = new Vector3D(0, 0, -1)};
			slices = factory.CreateSlices(volume);
			Assert.AreEqual(161, slices.Count, "SliceCount (sagittal reverse)");
			for (var n = 0; n < 161; ++n)
				AssertVolumeSlice(slices[160 - n], 200, 200, new Vector3D(n*0.625f, 0, 100), new Vector3D(0, 1, 0), new Vector3D(0, 0, -1), 0.5f, 0.5f, 0.625f, 0.625f, "sagittal reverse @n={0}", n);
		}
示例#14
0
        public void TestBasicOrthogonalSlicing()
        {
            var volume = MockVolumeReference.Create(
                new Size3D(160, 200, 100),
                new Vector3D(0.625f, 0.5f, 1),
                new Vector3D(0, 0, 0),
                Matrix3D.GetIdentity());

            var factory = new VolumeSliceFactory {
                RowOrientationPatient = new Vector3D(1, 0, 0), ColumnOrientationPatient = new Vector3D(0, 1, 0)
            };
            var slices = factory.CreateSlices(volume);

            Assert.AreEqual(101, slices.Count, "SliceCount (axial)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, 0, n), new Vector3D(1, 0, 0), new Vector3D(0, 1, 0), 0.5f, 0.5f, 1, 1, "axial @n={0}", n);
            }

            factory = new VolumeSliceFactory {
                RowOrientationPatient = new Vector3D(1, 0, 0), ColumnOrientationPatient = new Vector3D(0, -1, 0)
            };
            slices = factory.CreateSlices(volume);
            Assert.AreEqual(101, slices.Count, "SliceCount (axial reverse)");
            for (var n = 0; n < 101; ++n)
            {
                AssertVolumeSlice(slices[100 - n], 200, 200, new Vector3D(0, 100, n), new Vector3D(1, 0, 0), new Vector3D(0, -1, 0), 0.5f, 0.5f, 1, 1, "axial reverse @n={0}", n);
            }

            factory = new VolumeSliceFactory {
                RowOrientationPatient = new Vector3D(1, 0, 0), ColumnOrientationPatient = new Vector3D(0, 0, -1)
            };
            slices = factory.CreateSlices(volume);
            Assert.AreEqual(201, slices.Count, "SliceCount (coronal)");
            for (var n = 0; n < 201; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(0, n * 0.5f, 100), new Vector3D(1, 0, 0), new Vector3D(0, 0, -1), 0.5f, 0.5f, 0.5f, 0.5f, "coronal @n={0}", n);
            }

            factory = new VolumeSliceFactory {
                RowOrientationPatient = new Vector3D(1, 0, 0), ColumnOrientationPatient = new Vector3D(0, 0, 1)
            };
            slices = factory.CreateSlices(volume);
            Assert.AreEqual(201, slices.Count, "SliceCount (coronal reverse)");
            for (var n = 0; n < 201; ++n)
            {
                AssertVolumeSlice(slices[200 - n], 200, 200, new Vector3D(0, n * 0.5f, 0), new Vector3D(1, 0, 0), new Vector3D(0, 0, 1), 0.5f, 0.5f, 0.5f, 0.5f, "coronal reverse @n={0}", n);
            }

            factory = new VolumeSliceFactory {
                RowOrientationPatient = new Vector3D(0, 1, 0), ColumnOrientationPatient = new Vector3D(0, 0, 1)
            };
            slices = factory.CreateSlices(volume);
            Assert.AreEqual(161, slices.Count, "SliceCount (sagittal)");
            for (var n = 0; n < 161; ++n)
            {
                AssertVolumeSlice(slices[n], 200, 200, new Vector3D(n * 0.625f, 0, 0), new Vector3D(0, 1, 0), new Vector3D(0, 0, 1), 0.5f, 0.5f, 0.625f, 0.625f, "sagittal @n={0}", n);
            }

            factory = new VolumeSliceFactory {
                RowOrientationPatient = new Vector3D(0, 1, 0), ColumnOrientationPatient = new Vector3D(0, 0, -1)
            };
            slices = factory.CreateSlices(volume);
            Assert.AreEqual(161, slices.Count, "SliceCount (sagittal reverse)");
            for (var n = 0; n < 161; ++n)
            {
                AssertVolumeSlice(slices[160 - n], 200, 200, new Vector3D(n * 0.625f, 0, 100), new Vector3D(0, 1, 0), new Vector3D(0, 0, -1), 0.5f, 0.5f, 0.625f, 0.625f, "sagittal reverse @n={0}", n);
            }
        }