示例#1
0
		public static Matrix3D CalcRotationMatrix(double x, double y, double z, Point3D center, Vector3D up, Vector3D look, Transform3D transform, RotationType type)
		{
			//Transform3DGroup trm = new Transform3DGroup();
			//trm.Children.Add(transform);
			Vector3D realup = transform.Transform(up);
			if (type != RotationType.LockAxisY)
			{
				up = realup;
			}
			if (type != RotationType.LockAxisZ)
			{
				look = transform.Transform(look);
			}
			center = transform.Transform(center);
			Vector3D axisX = Vector3D.CrossProduct(up, look);
			Matrix3D matrix = new Matrix3D();
			//Quaternion q = new Quaternion();
			//q.
			double ang = AngleBetween(realup, YAxis) + x;
			if (ang >= 90)
			{
				x = 90 - ang;
			}
			matrix.RotateAt(new Quaternion(axisX, x), center);
			matrix.RotateAt(new Quaternion(up, y), center);
			matrix.RotateAt(new Quaternion(look, z), center);
			return matrix;
		}
示例#2
0
		public static Matrix3D CalculateRotationMatrix(double x, double y, double z, Point3D center, Vector3D up, Vector3D look, Transform3D transform)
		{
			//Transform3DGroup trm = new Transform3DGroup();
			//trm.Children.Add(transform);
			up = transform.Transform(up);
			look = transform.Transform(look);
			center = transform.Transform(center);
			Vector3D axisZ = Vector3D.CrossProduct(up, look);
			Matrix3D matrix = new Matrix3D();
			matrix.RotateAt(new Quaternion(axisZ, x), center);
			matrix.RotateAt(new Quaternion(up, y), center);
			matrix.RotateAt(new Quaternion(look, z), center);
			return matrix;
		}
示例#3
0
		public static MatrixTransform3D Rotate3D(Transform3D transform, Vector3D look, Vector3D dir, Point3D center)
		{
			Matrix3D m = new Matrix3D();
			Vector3D realook = transform.Transform(look);
			Vector3D axis = Vector3D.CrossProduct(realook, dir);
			double angle = Math.Acos(Vector3D.DotProduct(realook, dir));
			Quaternion q = new Quaternion(axis, angle);
			m.RotateAt(q, center);
			MatrixTransform3D rlt = transform as MatrixTransform3D;
			return new MatrixTransform3D(Matrix3D.Multiply(rlt.Matrix, m));
		}
示例#4
0
        public void TestOriginFinder(int sampleSize)
        {
            double error = 0;
            double totalDur = 0;
            Random randomMaker = new Random(DateTime.Now.Millisecond);
            double maxErr = 0;

            for (int j = 0; j < sampleSize; j++)
            {
                Point3D[] standardPoints = new Point3D[]
                {
                    new Point3D(0, 0.5, 1.5), //top
                    new Point3D(0.5, 0.5, 1.5), //right
                    new Point3D(0, 0.5, 2), //front
                    new Point3D(-0.5, 0.25, 1.5) //back
                };

                Point3D[] capturePoints = new Point3D[standardPoints.Length];

                Matrix3D matrix = new Matrix3D();

                //matrix.Translate(new Vector3D(0, 10, 0));

                double size = 1;
                matrix.RotateAt(new Quaternion(new Vector3D((randomMaker.Next(1) - 1) * randomMaker.NextDouble() * size,
                                                                                                        (randomMaker.Next(1) - 1) * randomMaker.NextDouble() * size,
                                                                                                        randomMaker.NextDouble() * size),
                                                                                                        (randomMaker.Next(1) - 1) * randomMaker.NextDouble() * 360),
                                                                             new Point3D(0, 0, 0));

                matrix.Translate(new Vector3D((randomMaker.Next(1) - 1) * randomMaker.NextDouble() * size,
                                                                            (randomMaker.Next(1) - 1) * randomMaker.NextDouble() * size,
                                                                            (randomMaker.Next(1) - 1) * randomMaker.NextDouble() * size));

                for (int i = 0; i < standardPoints.Length; i++)
                {
                    capturePoints[i] = matrix.Transform(standardPoints[i]);
                }

                testOrigin = matrix.Transform(new Point3D());
                DateTime start = DateTime.Now.ToUniversalTime();
                Point3D newOrigin = this.BruteForceEstimateOrigin(standardPoints, capturePoints, 5);
                TimeSpan end = DateTime.Now.ToUniversalTime() - start;
                int duration = (int)end.TotalSeconds;
                totalDur += duration;
                Vector3D og = new Vector3D(testOrigin.X, testOrigin.Y, testOrigin.Z);
                Vector3D offset = new Vector3D(testOrigin.X - newOrigin.X, testOrigin.Y - newOrigin.Y, testOrigin.Z - newOrigin.Z);
                error += offset.Length;
                if (maxErr < offset.Length)
                {
                    maxErr = offset.Length;
                    Console.WriteLine("Max Error: {1}", j, Math.Round(maxErr, 6));
                }
            }
            double avgErr = error / sampleSize;
            double avgDur = totalDur / sampleSize;
            Console.WriteLine("Average Error: {0}\t Max Error: {1}", avgErr, maxErr);
        }
示例#5
0
        /// <summary>
        /// Rotates the point cloud by a given angle
        /// </summary>
        /// <param name="axis">The axis of rotation</param>
        /// <param name="angle">The angle to which te point cloud is to be rotated</param>
        public void rotate(double[] axis, double angle)
        {
            if (!(axis.Length != 3)) {
                //centre of rotation
                Point3D centre = new Point3D(axis[0], axis[1], axis[2]);

                //pull out the entire tree
                PARSE.ICP.PointRGB[] pts = this.getAllPoints();

                //create a new kd tree
                KdTree.KDTree newPoints = new KdTree.KDTree(3);

                //iterate over every point and translate + jam in new tree
                foreach (PARSE.ICP.PointRGB point in pts)
                {
                    //create rot matrix
                    Matrix3D mtx = new Matrix3D();
                    Quaternion q = new Quaternion(new Vector3D(0, 1, 0), angle);
                    mtx.RotateAt(q, centre);

                    //complete rotation
                    Point3D newPoint = mtx.Transform(point.point);

                    //check if the x, y and z max and min coords need updating
                    //check min values
                    if (newPoint.X < minx) { minx = newPoint.X; }
                    if (newPoint.Y < miny) { miny = newPoint.Y; }
                    if (newPoint.Z < minz) { minz = newPoint.Z; }

                    //check max values
                    if (newPoint.X > maxx) { maxx = newPoint.X; }
                    if (newPoint.Y > maxy) { maxy = newPoint.Y; }
                    if (newPoint.Z > maxz) { maxz = newPoint.Z; }

                    //jam into the tree hole
                    double[] key = new double[3] { newPoint.X, newPoint.Y, newPoint.Z };
                    newPoints.insert(key, new PARSE.ICP.PointRGB(newPoint, point.r, point.g, point.b));
                }

                //replace the old kd tree with the new one
                this.points = newPoints;
            }
            else{
                //throw an exception and annoy Bernie in the process ;)
            }
        }
示例#6
0
文件: Core.cs 项目: hcilab-um/STim
        private Vector3D CalculateHeadOrientation(WagSkeleton skeleton)
        {
            Vector3D headOrientation = new Vector3D(0, 0, -1);

              FaceTrackFrame face = skeleton.FaceFrame;
              var FacePoints = face.Get3DShape();

              Vector3DF eyeLeft = FacePoints[Constants.LEFT_EYE];
              Vector3DF eyeRight = FacePoints[Constants.RIGHT_EYE];
              Vector3DF faceTop = FacePoints[Constants.FACE_TOP];
              Vector3DF faceBottom = FacePoints[Constants.FACE_BOTTOM];

              Vector3D faceVectorHorizontal = new Vector3D(eyeLeft.X - eyeRight.X, eyeLeft.Y - eyeRight.Y, eyeLeft.Z - eyeRight.Z);
              Vector3D faceVectorVertical = new Vector3D(faceTop.X - faceBottom.X, faceTop.Y - faceBottom.Y, faceTop.Z - faceBottom.Z);

              headOrientation = Vector3D.CrossProduct(faceVectorHorizontal, faceVectorVertical);
              headOrientation = Calibration.CalibrateTransform.Transform(headOrientation);
              headOrientation.Normalize();
              Matrix3D headPointsPointUpMatrix = new Matrix3D();
              headPointsPointUpMatrix.RotateAt(new System.Windows.Media.Media3D.Quaternion(new Vector3D(int.MaxValue, 0, 0), -20), skeleton.TransformedJoints[JointType.Head].Position.ToPoint3D());
              Vector3D lowered = headPointsPointUpMatrix.Transform(headOrientation);

              return lowered;
        }
示例#7
0
文件: Core.cs 项目: hcilab-um/STim
        private Vector3D CalculateHeadOrientation(WagSkeleton skeleton)
        {
            Vector3D headOrientation = new Vector3D(0, 0, -1);

            FaceTrackFrame face = skeleton.FaceFrame;
            var FacePoints = face.Get3DShape();

            Vector3DF eyeLeft = FacePoints[LEFT_EYE];
            Vector3DF eyeRight = FacePoints[RIGHT_EYE];
            Vector3DF faceTop = FacePoints[FACE_TOP];
            Vector3DF faceBottom = FacePoints[FACE_BOTTOM];

            Vector3D faceVectorHorizontal = new Vector3D(eyeLeft.X - eyeRight.X, eyeLeft.Y - eyeRight.Y, eyeLeft.Z - eyeRight.Z);
            Vector3D faceVectorVertical = new Vector3D(faceTop.X - faceBottom.X, faceTop.Y - faceBottom.Y, faceTop.Z - faceBottom.Z);

            headOrientation = Vector3D.CrossProduct(faceVectorHorizontal, faceVectorVertical);
            headOrientation = originTransform.Transform(headOrientation);
            headOrientation.Normalize();

            Matrix3D headPointsPointUpMatrix = new Matrix3D();
            headPointsPointUpMatrix.RotateAt(new Quaternion(new Vector3D(1, 0, 0), -20), skeleton.TransformedJoints[JointType.Head].Position.ToPoint3D());
            Vector3D lowered = headPointsPointUpMatrix.Transform(headOrientation);

            if (headOrientation.Z > 0)
                throw new Exception("Right hand rule violation");

            return lowered;
        }
示例#8
0
        private void MainForm_Click(object sender, EventArgs e)
        {
            Console.Clear();

            #region Create source data.

            for (int i = 0; i < pointsCountForFill; ++i) {
                this.sourcePoints[i] = new Point3D(
                    this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)),
                    this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)),
                    this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)));
            }
            for (int i = pointsCountForFill; i < pointsCount; ++i) {
                this.sourcePoints[i] = new Point3D(
                    this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)),
                    this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)),
                    this.rand.Next(Math.Max(this.ClientSize.Width, this.ClientSize.Height)));
            }

            #endregion Create source data.

            #region Create target data.

            Matrix3D matrix3D = new Matrix3D();
            matrix3D.Translate(new Vector3D(10, 50, 20));
            matrix3D.RotateAt(new Quaternion(new Vector3D(2, 9, 1), 20), new Point3D(30, 30, 70));
            matrix3D.Translate(new Vector3D(10, 50, 20));
            matrix3D.RotateAt(new Quaternion(new Vector3D(1, 3, 5), -5), new Point3D(10, 0, 10));

            Console.WriteLine("{0,30}{1,30}{2,30}{3,30}", matrix3D.M11, matrix3D.M21, matrix3D.M31, matrix3D.OffsetX);
            Console.WriteLine("{0,30}{1,30}{2,30}{3,30}", matrix3D.M12, matrix3D.M22, matrix3D.M32, matrix3D.OffsetY);
            Console.WriteLine("{0,30}{1,30}{2,30}{3,30}", matrix3D.M13, matrix3D.M23, matrix3D.M33, matrix3D.OffsetZ);

            for (int i = 0; i < pointsCount; ++i) {
                this.targetPoints[i] = matrix3D.Transform(this.sourcePoints[i]);
            }

            Point3D[] sourcePointsToFill = new Point3D[pointsCountForFill];
            Point3D[] targetPointsToFill = new Point3D[pointsCountForFill];
            for (int i = 0; i < pointsCountForFill; ++i) {
                sourcePointsToFill[i] = this.sourcePoints[i];
                targetPointsToFill[i] = this.targetPoints[i];
            }
            AffineCoorTransformator ct = new AffineCoorTransformator();
            ct.Fill(sourcePointsToFill, targetPointsToFill);

            double[] matrix = ct.MatrixCopy;
            int index = 0;
            for (int i = 0; i < AffineCoorTransformator.dim; ++i) {
                for (int j = 0; j < AffineCoorTransformator.dimExt; ++j) {
                    Console.Write("{0,30}", matrix[index]);
                    ++index;
                }
                Console.WriteLine();
            }
            Console.WriteLine();

            #endregion Create target data.

            double[] error = new double[pointsCount];
            double totalError = 0;
            for (int i = 0; i < pointsCount; ++i) {
                this.targetPointsRes[i] = ct.Transform(this.sourcePoints[i]);

                error[i] = (this.targetPointsRes[i] - this.targetPoints[i]).Length;
                Console.WriteLine("Error {0}: {1}.", i, error[i]);
                totalError += error[i];
            }
            double totalErrorMax = pointsCount * eps * Math.Sqrt(AffineCoorTransformator.dim);
            Console.WriteLine();
            Console.WriteLine("Max: {0}. Current: {1}. Middle: {2}", totalErrorMax, totalError, totalError / pointsCount);
            Console.WriteLine();

            this.Invalidate();
        }
        //taken from http://stackoverflow.com/questions/2042214/wpf-3d-rotate-a-model-around-its-own-axes
        //adjusted for offset by Dawid Rusin
        private Matrix3D CalculateRotationMatrix(double x, double y, double z)
        {
            Matrix3D matrix = new Matrix3D();
            matrix.RotateAt(new Quaternion(new Vector3D(1, 0, 0), x), new Point3D(offsetX, offsetY, offsetZ));
            matrix.RotateAt(new Quaternion(new Vector3D(0, 1, 0) * matrix, y), new Point3D(offsetX, offsetY, offsetZ));
            matrix.RotateAt(new Quaternion(new Vector3D(0, 0, 1) * matrix, z), new Point3D(offsetX, offsetY, offsetZ));

            return matrix;
        }
示例#10
0
		public static MatrixTransform3D Rotate3D(Transform3D transform, double x, double y, double z, Point3D center, Vector3D up, Vector3D look, RotationType type)
		{
			if (type != RotationType.LockAxisY)
			{
				up = transform.Transform(up);
			}
			if (type != RotationType.LockAxisZ)
			{
				look = transform.Transform(look);
			}
			center = transform.Transform(center);
			Vector3D axisX = Vector3D.CrossProduct(up, look);
			Matrix3D matrix = new Matrix3D();
			matrix.RotateAt(new Quaternion(axisX, x), center);
			matrix.RotateAt(new Quaternion(up, y), center);
			matrix.RotateAt(new Quaternion(look, z), center);
			MatrixTransform3D mOriginTransform = transform as MatrixTransform3D;
			//mOriginTransform.Matrix.RotateAt(
			try
			{
				return new MatrixTransform3D(Matrix3D.Multiply(mOriginTransform.Matrix, matrix));
			}
			catch (Exception err)
			{
				Exceptions.LogOnly(err);
				return null;
			}
		}