Cross() public static method

public static Cross ( Vector3D, lhs, Vector3D, rhs ) : Vector3D,
lhs Vector3D,
rhs Vector3D,
return Vector3D,
Exemplo n.º 1
0
		/// <summary>
		/// Calculates the angle subtended by two line segments that meet at a vertex.
		/// </summary>
		/// <param name="start">The end of one of the line segments.</param>
		/// <param name="vertex">The vertex of the angle formed by the two line segments.</param>
		/// <param name="end">The end of the other line segment.</param>
		/// <returns>The angle subtended by the two line segments in degrees.</returns>
		public static double SubtendedAngle(PointF start, PointF vertex, PointF end)
		{
			Vector3D vertexPositionVector = new Vector3D(vertex.X, vertex.Y, 0);
			Vector3D a = new Vector3D(start.X, start.Y, 0) - vertexPositionVector;
			Vector3D b = new Vector3D(end.X, end.Y, 0) - vertexPositionVector;

			float dotProduct = a.Dot(b);

			Vector3D crossProduct = a.Cross(b);

			float magA = a.Magnitude;
			float magB = b.Magnitude;

			if (FloatComparer.AreEqual(magA, 0F) || FloatComparer.AreEqual(magB, 0F))
				return 0;

			double cosTheta = dotProduct/magA/magB;

			// Make sure cosTheta is within bounds so we don't
			// get any errors when we take the acos.
			if (cosTheta > 1.0f)
				cosTheta = 1.0f;

			if (cosTheta < -1.0f)
				cosTheta = -1.0f;

			double theta = Math.Acos(cosTheta)*(crossProduct.Z == 0 ? 1 : -Math.Sign(crossProduct.Z));
			double thetaInDegrees = theta/Math.PI*180;

			return thetaInDegrees;
		}
Exemplo n.º 2
0
        public static double DistanceLineLine( Vector3D n1, Vector3D p1, Vector3D n2, Vector3D p2 )
        {
            // Check to make sure that neither of the normal vectors are degenerate.
            if( Tolerance.Zero( n1.MagSquared() ) || Tolerance.Zero( n2.MagSquared() ) )
                return double.NaN;

            Vector3D plane = n1.Cross( n2 );

            //	Case where the lines are parallel (magnitude of the cross product will be 0).
            if( Tolerance.Zero( plane.MagSquared() ) )
                return DistancePointLine( n1, p1, p2 );

            return DistancePointPlane( plane, p1, p2 );
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns the two intersection points of two great circles.
        /// gc1 and gc2 are the great circle normal vectors.
        /// Fails if the input circles are the same.
        /// </summary>
        public static bool IntersectionGCGC( Vector3D gc1, Vector3D gc2, out Vector3D i1, out Vector3D i2 )
        {
            i1 = i2 = Vector3D.DneVector();

            // Direction vector of the intersection point of the two great circles.
            // NOTE there are actually two antipodal intersection points, +-I
            Vector3D I = gc1.Cross( gc2 );
            if( !I.Normalize() )
                return false;

            i1 = I;
            i2 = -I;
            return true;
        }
Exemplo n.º 4
0
        /// <summary>
        /// NOTE: Not general, and assumes some things we know about this problem domain, 
        /// e.g. that c1 and c2 live on the same sphere of radius 1, and have two intersection points.
        /// </summary>
        public static void IntersectionCircleCircle( Vector3D sphereCenter, Circle3D c1, Circle3D c2, out Vector3D i1, out Vector3D i2 )
        {
            // Spherical analogue of our flat circle-circle intersection.
            // Spherical pythagorean theorem for sphere where r=1: cos(hypt) = cos(A)*cos(B)

            Circle3D clone1 = c1.Clone(), clone2 = c2.Clone();
            //clone1.Center -= sphereCenter;
            //clone2.Center -= sphereCenter;

            // Great circle (denoted by normal vector), and distance between the centers.
            Vector3D gc = clone2.Normal.Cross( clone1.Normal );
            double d = clone2.Normal.AngleTo( clone1.Normal );
            double r1 = clone1.Normal.AngleTo( clone1.PointOnCircle );
            double r2 = clone2.Normal.AngleTo( clone2.PointOnCircle );

            // Calculate distances we need.  So ugly!
            // http://www.wolframalpha.com/input/?i=cos%28r1%29%2Fcos%28r2%29+%3D+cos%28x%29%2Fcos%28d-x%29%2C+solve+for+x
            double t1 = Math.Pow( Math.Tan( d / 2 ), 2 );
            double t2 = Math.Cos( r1 ) / Math.Cos( r2 );
            double t3 = Math.Sqrt( (t1 + 1) * (t1 * t2 * t2 + 2 * t1 * t2 + t1 + t2 * t2 - 2 * t2 + 1) ) - 2 * t1 * t2;
            double x = 2 * Math.Atan( t3 / (t1 * t2 + t1 - t2 + 1) );
            double y = Math.Acos( Math.Cos( r1 ) / Math.Cos( x ) );

            i1 = clone1.Normal;
            i1.RotateAboutAxis( gc, x );
            i2 = i1;

            // Perpendicular to gc through i1.
            Vector3D gc2 = i1.Cross( gc );
            i1.RotateAboutAxis( gc2, y );
            i2.RotateAboutAxis( gc2, -y );
            i1 += sphereCenter;
            i2 += sphereCenter;

            /*
            // It would be nice to do the spherical analogue of circle-circle intersections, like here:
            // http://mathworld.wolfram.com/Circle-CircleIntersection.html
            // But I don't want to jump down that rabbit hole and am going to sacrifice some speed to use
            // my existing euclidean function.

            // Stereographic projection to the plane.  XXX - Crap, circles may become lines, and this isn't being handled well.
            Circle3D c1Plane = H3Models.BallToUHS( clone1 );
            Circle3D c2Plane = H3Models.BallToUHS( clone2 );
            if( 2 != Euclidean2D.IntersectionCircleCircle( c1Plane.ToFlatCircle(), c2Plane.ToFlatCircle(), out i1, out i2 ) )
                throw new System.Exception( "Expected two intersection points" );
            i1 = H3Models.UHSToBall( i1 ); i1 += sphereCenter;
            i2 = H3Models.UHSToBall( i2 ); i2 += sphereCenter;
            */
        }
Exemplo n.º 5
0
        /// <summary>
        /// Given a curvature tensor, finds principal directions and curvatures.
        /// </summary>
        /// <param name="u">The u vector.</param>
        /// <param name="v">The v vector.</param>
        /// <param name="ku">ku.</param>
        /// <param name="kuv">kuv.</param>
        /// <param name="kv">kv.</param>
        /// <param name="normalNew">The new normal.</param>
        /// <param name="pDirMax">The maximum principle curvature direction.</param>
        /// <param name="pDirMin">The minimum principle curvature direction.</param>
        /// <param name="kMax">The maximum principle curvature.</param>
        /// <param name="kMin">The minimum principle curvature.</param>
        public static void DiagonalizeCurvature(Vector3D u, Vector3D v, double ku, double kuv, double kv, Vector3D normalNew,
            out Vector3D pDirMax, out Vector3D pDirMin, out double kMax, out double kMin)
        {
            Vector3D uRotated, vRotated;

            RotateCoordinateSystem(u, v, normalNew, out uRotated, out vRotated);

            double c = 1.0 ;
            double s = 0.0 ;
            double t = 0.0 ;

            // Jacobi rotation to diagonalize
            if (kuv != 0.0f)
            {
                double h = 0.5f * (kv - ku) / kuv;

                if (h < 0.0f)
                {
                    t = 1.0f / (h - (float)Math.Sqrt(1.0f + h * h));
                }
                else
                {
                    t = 1.0f / (h + (float)Math.Sqrt(1.0f + h * h));
                }

                c = 1.0f / (float)Math.Sqrt(1.0f + t * t);
                s = t * c;
            }

            kMax = ku - t * kuv;
            kMin = kv + t * kuv;

            if (Math.Abs(kMax) >= Math.Abs(kMin))
            {
                pDirMax = c * uRotated - s * vRotated;
            }
            else
            {
                double temp = kMin;
                kMin = kMax;
                kMax = temp;
                pDirMax = s * uRotated + c * vRotated;
            }

            pDirMin =  normalNew.Cross(pDirMax);
        }
Exemplo n.º 6
0
        // 内心
        public void ComputeIncircleCenter(out Vector3D center, out double radius)
        {
            center = Vector3D.Zero;
            radius = 0;
            double a, b, c;

            c = ComputeEdgeLength(1);
            b = ComputeEdgeLength(3);
            a = ComputeEdgeLength(2);

            center.x = (a * this.A.x + b * this.B.x + c * this.C.x) / (a + b + c);
            center.y = (a * this.A.y + b * this.B.y + c * this.C.y) / (a + b + c);
            center.z = (a * this.A.z + b * this.B.z + c * this.C.z) / (a + b + c);

            radius = center.Cross(C - A).Length();

        }
Exemplo n.º 7
0
		public void TestCross()
		{
			Vector3D v1 = new Vector3D(2.2F, -6.1F, 7.4F);
			Vector3D v2 = new Vector3D(-3.8F, 3.7F, 4.1F);
			Vector3D result = new Vector3D(-52.39F, -37.14F, -15.04F);

			Assert.IsTrue(Vector3D.AreEqual(v1.Cross(v2), result));
		}
Exemplo n.º 8
0
 public static Circle3D OrthogonalCircle( Vector3D v1, Vector3D v2 )
 {
     Vector3D center;
     double rad;
     OrthogonalCircle( v1, v2, out center, out rad );
     Vector3D normal = v1.Cross( v2 );
     return new Circle3D { Center = center, Normal = normal, Radius = rad };
 }
Exemplo n.º 9
0
			private static Matrix ImageOrientationPatientToMatrix(ImageOrientationPatient orientation)
			{
				Vector3D xOrient = new Vector3D((float) orientation.RowX, (float) orientation.RowY, (float) orientation.RowZ);
				Vector3D yOrient = new Vector3D((float) orientation.ColumnX, (float) orientation.ColumnY, (float) orientation.ColumnZ);
				Vector3D zOrient = xOrient.Cross(yOrient);

				Matrix orientationMatrix = Math3D.OrientationMatrixFromVectors(xOrient, yOrient, zOrient);
				return orientationMatrix;
			}
Exemplo n.º 10
0
        /// <summary>
        /// Projects a curvature tensor from an old basis to a new one.
        /// </summary>
        /// <param name="uOld">Old u.</param>
        /// <param name="vOld">Old v.</param>
        /// <param name="kuOld">Old ku.</param>
        /// <param name="kuvOld">Old kuv.</param>
        /// <param name="kvOld">Old kv.</param>
        /// <param name="uNew">New u</param>
        /// <param name="vNew">New v.</param>
        /// <param name="kuNew">New ku.</param>
        /// <param name="kuvNew">New kuv.</param>
        /// <param name="kvNew">New kv.</param>
        public static void ProjectCurvature(Vector3D uOld, Vector3D vOld, float kuOld, float kuvOld, float kvOld, Vector3D uNew, Vector3D vNew,
            out float kuNew, out float kuvNew, out float kvNew)
        {
            Vector3D uNewRotated, vNewRotated;

            RotateCoordinateSystem(uNew, vNew,  uOld.Cross(vOld), out uNewRotated, out vNewRotated);

            float u1 =(float) uNewRotated.Dot(uOld);
            float v1 = (float)uNewRotated.Dot(vOld);
            float u2 = (float)vNewRotated.Dot(uOld);
            float v2 = (float)vNewRotated.Dot(vOld);

            kuNew  = kuOld * u1 * u1 + kuvOld * (2.0f    * u1 * v1) + kvOld * v1 * v1;
            kuvNew = kuOld * u1 * u2 + kuvOld * (u1 * v2 + u2 * v1) + kvOld * v1 * v2;
            kvNew  = kuOld * u2 * u2 + kuvOld * (2.0f    * u2 * v2) + kvOld * v2 * v2;
        }
Exemplo n.º 11
0
 /// <summary>
 /// Calculate the sine of the angle between two vectors.
 /// </summary>
 private static double SinAngle( Vector3D p1, Vector3D p2 )
 {
     double sinA = (p1.Cross( p2 )).Abs() / (p1.Abs() * p2.Abs());
     return Clamp( sinA );
 }
Exemplo n.º 12
0
 /// <summary>
 /// Return the normal of the great circle defined by the two vectors. 
 /// Return false if we fail to get the normal (happens if p1 = p2).
 /// </summary>
 static bool GetGCNormal( Vector3D p1, Vector3D p2, out Vector3D normal )
 {
     normal = p1.Cross( p2 );
     if( !normal.Normalize() )
     {
         normal = Vector3D.DneVector();
         return false;
     }
     return true;
 }
        public static IPresentationImage PresentationImageFromPositionOrientation(
            ImagePositionPatient imagePositionPatient,
            ImageOrientationPatient imageOrientationPatient,
            IDisplaySet displaySet,
            string frameOfReferenceUid)
        {
            var point = new Vector3D(
                (float) imagePositionPatient.X,
                (float) imagePositionPatient.Y,
                (float) imagePositionPatient.Z);

            if (displaySet != null)
            {
                var firstSop = displaySet.PresentationImages.OfType<IImageSopProvider>().FirstOrDefault();
                // Match Frame of Reference UID, if present
                if (firstSop == null || string.IsNullOrEmpty(frameOfReferenceUid) ||
                    string.IsNullOrEmpty(firstSop.Frame.FrameOfReferenceUid) || frameOfReferenceUid == firstSop.Frame.FrameOfReferenceUid)
                {
                    foreach (IPresentationImage image in displaySet.PresentationImages)
                    {
                        var sop = image as IImageSopProvider;
                        if (sop != null)
                        {
                            Vector3D planeRow = new Vector3D(
                                (float) sop.Frame.ImageOrientationPatient.RowX,
                                (float) sop.Frame.ImageOrientationPatient.RowY,
                                (float) sop.Frame.ImageOrientationPatient.RowZ).Normalize();
                            Vector3D planeColumn = new Vector3D(
                                (float) sop.Frame.ImageOrientationPatient.ColumnX,
                                (float) sop.Frame.ImageOrientationPatient.ColumnY,
                                (float) sop.Frame.ImageOrientationPatient.ColumnZ).Normalize();
                            Vector3D planeNormal = planeRow.Cross(planeColumn);

                            var planePosition = new Vector3D(
                                (float) sop.Frame.ImagePositionPatient.X,
                                (float) sop.Frame.ImagePositionPatient.Y,
                                (float) sop.Frame.ImagePositionPatient.Z);
                            if (PointIsInPlane(point, planeNormal, planePosition))
                                return image;
                        }
                    }
                }
            }

            return null;
        }
Exemplo n.º 14
0
        public IList<Vector3D> ComputeCurve(
            Vector3D start, 
            Vector3D stop, 
            double granularity)
        {
            if (granularity <= 0.0)
            {
                throw new ArgumentOutOfRangeException("granularity", "Granularity must be greater than zero.");
            }

            Vector3D normal = start.Cross(stop).Normalize();
            double theta = start.AngleBetween(stop);
            int n = Math.Max((int)(theta / granularity) - 1, 0);
            
            List<Vector3D> positions = new List<Vector3D>(2 + n);

            positions.Add(start);

            for (int i = 1; i <= n; ++i)
            {
                double phi = (i * granularity);

                positions.Add(ScaleToGeocentricSurface(start.RotateAroundAxis(normal, phi)));
            }

            positions.Add(stop);

            return positions;
        }
Exemplo n.º 15
0
        /// <summary>
        /// Used to get the perpendicular to the polyline at a point p2, given adjacent points.
        /// </summary>
        private static Vector3D CurvePerp( Vector3D p1, Vector3D p2, Vector3D p3 )
        {
            // Just use p1 and p3 for now, close to the 3 point rule.
            // http://math.depaul.edu/mash/optnum.pdf

            Vector3D perpendicular = p1.Cross( p3 );
            //Vector3D perpendicular = axis.Cross( new Vector3D( 0, 0, 1 ) );
            if( !perpendicular.Normalize() )
            {
                // This can happen if p1 and p3 are collinear with origin.
                Vector3D axis = p1 - p3;
                perpendicular = axis.Cross( new Vector3D( 0, 1, 0 ) );
                perpendicular.Normalize();
            }

            return perpendicular;
        }
Exemplo n.º 16
0
        /// <summary>
        /// A class containing static methods for computing curvature on a mesh.
        /// </summary>
        public static PrincipalCurvature DiagonalizeCurvature(UV src, KUV srcK, Vector3D dstNormal)
        {
            UV rotated = Transform.RotateCoordinateSystem(src, dstNormal);

            double c = 1.0;
            double s = 0.0;
            double t = 0.0;

            // Jacobi rotation to diagonalize
            if (srcK.UV != 0.0f)
            {
                double h = 0.5f * (srcK.V - srcK.U) / srcK.UV;

                if (h < 0.0f)
                {
                    t = 1.0f / (h - Math.Sqrt(1.0f + h * h));
                }
                else
                {
                    t = 1.0f / (h + Math.Sqrt(1.0f + h * h));
                }

                c = 1.0f / Math.Sqrt(1.0f + t * t);
                s = t * c;
            }

            PrincipalCurvature pc = new PrincipalCurvature();

            pc.max = srcK.U - t * srcK.UV;
            pc.min = srcK.V + t * srcK.UV;

            if (Math.Abs(pc.max) >= Math.Abs(pc.min))
            {
                pc.maxDir = c * rotated.U - s * rotated.V;
            }
            else
            {
                double temp = pc.min;
                pc.min = pc.max;
                pc.max = temp;
                pc.maxDir = s * rotated.U + c * rotated.V;
            }

            pc.minDir = dstNormal.Cross(pc.maxDir);

            return pc;
        }
Exemplo n.º 17
0
        /// <summary>
        /// Rotates a 3D coordinate system to match a specified normal.
        /// </summary>
        /// <param name="uOld">Old u.</param>
        /// <param name="vOld">Old v.</param>
        /// <param name="normalNew">The normal to match.</param>
        /// <param name="uNew">New u.</param>
        /// <param name="vNew">New v.</param>
        public static void RotateCoordinateSystem(Vector3D uOld, Vector3D vOld, Vector3D normalNew,
            out Vector3D uNew, out Vector3D vNew)
        {
            Vector3D normalOld =  uOld.Cross(vOld);
            float normalsDot =(float)  normalOld.Dot(normalNew);

            if (normalsDot <= -1.0f)
            {
                uNew = uOld * -1;
                vNew = vOld * -1; ;
            }
            else
            {
                Vector3D perpOld = normalNew - normalsDot * normalOld;
                Vector3D dPerp = 1.0f / (1.0f + normalsDot) * (normalOld + normalNew);

                uNew = uOld - dPerp *  uOld.Dot(perpOld);
                vNew = vOld - dPerp *  vOld.Dot(perpOld);
            }
        }
Exemplo n.º 18
0
		/// <summary>
		/// Gets the unit normal vector describing the specified image plane in patient coordinates.
		/// </summary>
		/// <returns>The unit normal vector, or null if the <see cref="Frame"/>'s position information is invalid.</returns>
		public static Vector3D GetNormalVector(ImageOrientationPatient imageOrientationPatient)
		{
			if (imageOrientationPatient.IsNull)
				return null;

			var left = new Vector3D((float) imageOrientationPatient.RowX, (float) imageOrientationPatient.RowY, (float) imageOrientationPatient.RowZ);
			var normal = left.Cross(new Vector3D((float) imageOrientationPatient.ColumnX, (float) imageOrientationPatient.ColumnY, (float) imageOrientationPatient.ColumnZ));
			return FloatComparer.AreEqual(normal.Magnitude, 0) ? Vector3D.Null : normal.Normalize();
		}
Exemplo n.º 19
0
		/// <summary>
		/// Allows specification of the slice plane, through point, and extent via two points in patient space
		/// </summary>
		public static VolumeSlicerParams Create(IVolumeHeader volume, Vector3D sourceOrientationColumnPatient, Vector3D sourceOrientationRowPatient,
		                                               Vector3D startPointPatient, Vector3D endPointPatient)
		{
			Vector3D sourceOrientationNormalPatient = sourceOrientationColumnPatient.Cross(sourceOrientationRowPatient);
			Vector3D normalLinePatient = (endPointPatient - startPointPatient).Normalize();
			Vector3D normalPerpLinePatient = sourceOrientationNormalPatient.Cross(normalLinePatient);

			Vector3D slicePlanePatientX = normalLinePatient;
			Vector3D slicePlanePatientY = sourceOrientationNormalPatient;
			Vector3D slicePlanePatientZ = normalPerpLinePatient;

			Matrix slicePlanePatientOrientation = Math3D.OrientationMatrixFromVectors(slicePlanePatientX, slicePlanePatientY, slicePlanePatientZ);

			Matrix _resliceAxes = volume.RotateToVolumeOrientation(slicePlanePatientOrientation);
			Vector3D lineMiddlePointPatient = new Vector3D(
				(startPointPatient.X + endPointPatient.X)/2,
				(startPointPatient.Y + endPointPatient.Y)/2,
				(startPointPatient.Z + endPointPatient.Z)/2);

			VolumeSlicerParams slicerParams = new VolumeSlicerParams(_resliceAxes);

			slicerParams.SliceThroughPointPatient = new Vector3D(lineMiddlePointPatient);
			slicerParams.SliceExtentXMillimeters = (endPointPatient - startPointPatient).Magnitude;

			return slicerParams;
		}
Exemplo n.º 20
0
        public static Matrix3D ComputeRotationRodrigues(Vector3D first, Vector3D second, int step)
        {

            Vector3D cross = first.Cross(second);

            double sin = cross.Length();
            double cos = first.Dot(second);

            //if (cos > 0.99)
            //{
            //    return Matrix3D.IdentityMatrix();
            //}


            double angle = Math.Acos(cos);

            cos = Math.Cos(angle / step);
            sin = Math.Sin(angle / step);

            cross = cross.Normalize();
            double x = cross.x;
            double y = cross.y;
            double z = cross.z;

            Matrix3D result = Matrix3D.IdentityMatrix();


            //result[0, 0] = cos+(1-cos)*x*x;
            //result[0, 1] = x * y*(1 - cos) - z * sin;
            //result[0, 2] = y* sin+x*z*(1-cos);
            //result[1, 0] = z * sin + x * y * (1 - cos);
            //result[1, 1] = cos + y * y * (1 - cos);
            //result[1, 2] = -x * sin + y * z * (1 - cos);
            //result[2, 0] = -y * sin + x * z * (1 - cos);
            //result[2, 1] = x * sin + y * z * (1 - cos);
            //result[2, 2] =cos + z* z * (1 - cos);



            //result[0, 0] = cos*(y*y+z*z) +   x * x;
            //result[0, 1] = x * y * (1 - cos) - z * sin;
            //result[0, 2] = y * sin + x * z * (1 - cos);
            //result[1, 0] = z * sin + x * y * (1 - cos);
            //result[1, 1] = cos*(x*x+z*z) + y * y ;
            //result[1, 2] = -x * sin + y * z * (1 - cos);
            //result[2, 0] = -y * sin + x * z * (1 - cos);
            //result[2, 1] = x * sin + y * z * (1 - cos);
            //result[2, 2] = cos*(x*x+y*y) + z * z  ;

            result[0, 0] = cos * (1 - x * x) + x * x;
            result[0, 1] = x * y * (1 - cos) - z * sin;
            result[0, 2] = y * sin + x * z * (1 - cos);
            result[1, 0] = z * sin + x * y * (1 - cos);
            result[1, 1] = cos * (1 - y * y) + y * y;
            result[1, 2] = -x * sin + y * z * (1 - cos);
            result[2, 0] = -y * sin + x * z * (1 - cos);
            result[2, 1] = x * sin + y * z * (1 - cos);
            result[2, 2] = cos * (1 - z * z) + z * z;

            // result = result.Transpose();
            return result;
        }
Exemplo n.º 21
0
		public void TestObliqueSkewedSource()
		{

			{
				// perfectly rectangular cuboid, oblique source
				var row = new Vector3D(1, 2, 3);
				var column = new Vector3D(7, 10, -9);
				var stack = row.Cross(column);

				var orientation = new DataSetOrientation(row, column, stack);
				TestVolume(VolumeFunction.Void, orientation.Initialize, null);
			}

			{
				// based on a real breast tomo MLO source - perfectly valid, and oblique w.r.t normal gantry-oriented calculations
				var row = new Vector3D(0, 1, 0);
				var column = new Vector3D(1, 0, 1);
				var stack = new Vector3D(-100, 0, 100);

				var orientation = new DataSetOrientation(row, column, stack);
				TestVolume(VolumeFunction.Void, orientation.Initialize, null);
			}

			{
				// column orientation skewed by 30 degreees from normal
				const double skewAngle = 30*_degreesInRadians;

				var row = new Vector3D(1, 2, 3);
				var column = new Vector3D(7, 10, -9);
				var stack = (float) Math.Cos(skewAngle)*row.Cross(column).Normalize() - (float) Math.Sin(skewAngle)*column.Normalize();

				var orientation = new DataSetOrientation(row, column, stack);
				TestVolume(VolumeFunction.Void, orientation.Initialize, null);
			}

			{
				// column orientation skewed by -30 degreees from normal
				const double skewAngle = -30*_degreesInRadians;

				var row = new Vector3D(1, 2, 3);
				var column = new Vector3D(7, 10, -9);
				var stack = (float) Math.Cos(skewAngle)*row.Cross(column).Normalize() - (float) Math.Sin(skewAngle)*column.Normalize();

				var orientation = new DataSetOrientation(row, column, stack);
				TestVolume(VolumeFunction.Void, orientation.Initialize, null);
			}

			try
			{
				// row orientation skewed by 30 degreees from normal
				const double skewAngle = 30*_degreesInRadians;

				var row = new Vector3D(1, 2, 3);
				var column = new Vector3D(7, 10, -9);
				var stack = (float) Math.Cos(skewAngle)*row.Cross(column).Normalize() - (float) Math.Sin(skewAngle)*row.Normalize();

				var orientation = new DataSetOrientation(row, column, stack);
				TestVolume(VolumeFunction.Void, orientation.Initialize, null);

				Assert.Fail("Expected an exception of type {0}", typeof (UnsupportedGantryTiltAxisException));
			}
			catch (UnsupportedGantryTiltAxisException) {}

			try
			{
				// row orientation skewed by -30 degreees from normal
				const double skewAngle = -30*_degreesInRadians;

				var row = new Vector3D(1, 2, 3);
				var column = new Vector3D(7, 10, -9);
				var stack = (float) Math.Cos(skewAngle)*row.Cross(column).Normalize() - (float) Math.Sin(skewAngle)*row.Normalize();

				var orientation = new DataSetOrientation(row, column, stack);
				TestVolume(VolumeFunction.Void, orientation.Initialize, null);

				Assert.Fail("Expected an exception of type {0}", typeof (UnsupportedGantryTiltAxisException));
			}
			catch (UnsupportedGantryTiltAxisException) {}

			try
			{
				// column orientation skewed by -30 degreees from normal, then further row skewed by 20 degrees
				const double skewAngle1 = -30*_degreesInRadians;
				const double skewAngle2 = 20*_degreesInRadians;

				var row = new Vector3D(1, 2, 3);
				var column = new Vector3D(7, 10, -9);
				var temp = (float) Math.Cos(skewAngle1)*row.Cross(column).Normalize() - (float) Math.Sin(skewAngle1)*column.Normalize();
				var stack = (float) Math.Cos(skewAngle2)*temp.Normalize() - (float) Math.Sin(skewAngle2)*row.Normalize();

				var orientation = new DataSetOrientation(row, column, stack);
				TestVolume(VolumeFunction.Void, orientation.Initialize, null);

				Assert.Fail("Expected an exception of type {0}", typeof (UnsupportedGantryTiltAxisException));
			}
			catch (UnsupportedGantryTiltAxisException) {}
		}
Exemplo n.º 22
0
		private void SetPatientOrientation(Vector3D rowDirectionPatient, Vector3D columnDirectionPatient)
		{
			if (!CanRotate())
				return;

			if (rowDirectionPatient == null || columnDirectionPatient == null || !rowDirectionPatient.IsOrthogonalTo(columnDirectionPatient, (float) (5/180d*Math.PI)))
				return;

			var patientPresentation = SelectedPresentationImage as IPatientPresentationProvider;
			if (patientPresentation == null || !patientPresentation.PatientPresentation.IsValid)
				return;

			// Note the inverted column orientation vectors in both matrices - this is due to implicit Y axis inversion in the 3D transform
			columnDirectionPatient = -columnDirectionPatient;

			var currentRowOrientation = patientPresentation.PatientPresentation.OrientationX;
			var currentColumnOrientation = -patientPresentation.PatientPresentation.OrientationY;
			var currentOrientation = Matrix3D.FromRows(currentRowOrientation.Normalize(), currentColumnOrientation.Normalize(), currentRowOrientation.Cross(currentColumnOrientation).Normalize());
			var requestedOrientation = Matrix3D.FromRows(rowDirectionPatient.Normalize(), columnDirectionPatient.Normalize(), rowDirectionPatient.Cross(columnDirectionPatient).Normalize());

			var transform = _operation.GetOriginator(SelectedPresentationImage);

			// (because we're dealing with rotation matrices (i.e. orthogonal!), the Inverse is just Transpose)
			var rotation = requestedOrientation*currentOrientation.Transpose();
			transform.Rotation = rotation*transform.Rotation; // this rotation is cumulative upon current rotation, since IPatientPresentationProvider is based on *current* view

			SelectedPresentationImage.Draw();
		}
Exemplo n.º 23
0
        public void Cross()
        {
            Vector3D a = new Vector3D(1.0, 0.0, 0.0);
            Vector3D b = new Vector3D(0.0, 1.0, 0.0);
            
            Vector3D cross1 = a.Cross(b);
            Assert.AreEqual(0.0, cross1.X, 1e-14);
            Assert.AreEqual(0.0, cross1.Y, 1e-14);
            Assert.AreEqual(1.0, cross1.Z, 1e-14);

            Vector3D cross2 = b.Cross(a);
            Assert.AreEqual(0.0, cross2.X, 1e-14);
            Assert.AreEqual(0.0, cross2.Y, 1e-14);
            Assert.AreEqual(-1.0, cross2.Z, 1e-14);
        }
Exemplo n.º 24
0
		public override RGBA_Floats GetColor(IntersectInfo info)
		{
			if (Material.HasTexture)
			{
				throw new NotImplementedException();
#if false
                //Vector vecU = new Vector(hit.y - Position.y, hit.z - Position.z, Position.x-hit.x);
                Vector3 Position = Transform.Position;
                Vector3 vecU = new Vector3D((P1.y + P2.y) / 2 - Position.y, (P1.z + P2.z) / 2 - Position.z, Position.x - (P1.x + P2.x) / 2).GetNormal();
                Vector3 vecV = vecU.Cross((P1 + P2) / 2 - Position).GetNormal();

                double u = Vector3.Dot(info.hitPosition, vecU);
                double v = Vector3.Dot(info.hitPosition, vecV);
                return Material.GetColor(u, v);
#endif
			}
			else
			{
				return Material.GetColor(0, 0);
			}
		}