示例#1
0
        public static Quaternion rotatePointByAngleAboutAxisVector(Quaternion point, double angle, Quaternion axis)
        {
            Quaternion result = new Quaternion(0, 0, 0, 0);

            // axis (r)
            // axis must be a unit vector
            axis.setX(axis.getX() / axis.magnitude());
            axis.setY(axis.getY() / axis.magnitude());
            axis.setZ(axis.getZ() / axis.magnitude());

            // angle (a)
            // dot product (dp) = cos(a)
            double dp = Math.Cos(angle);

            if (debugMode)
                Console.WriteLine("dot product: " + dp);

            // s = sqrt(2*(1+dp))
            double s = Math.Sqrt(2 * (1 + dp));

            if (debugMode)
                Console.WriteLine("s: " + s);

            // q
            Quaternion q = new Quaternion(0, 0, 0, 0);
            q.setW(s/2);
            q.setX(axis.getX() / s);
            q.setY(axis.getY() / s);
            q.setZ(axis.getZ() / s);

            if (debugMode)
                Console.WriteLine("q: " + q);

            // point (p)
            // p'= qpq^-1
            result = q.multiply(point);
            result = result.multiply(q.inverse());

            // final round for output (if set)
            if (rotationRoundingForOutput)
            {
                result.setW(Math.Round(result.getW(), 2));
                result.setX(Math.Round(result.getX(), 2));
                result.setY(Math.Round(result.getY(), 2));
                result.setZ(Math.Round(result.getZ(), 2));
            }

            return result;
        }
示例#2
0
 public Quaternion add(Quaternion other)
 {
     // (a + e)+i(b + f)+j(c + g)+k(d + h)
     Quaternion result = new Quaternion(0, 0, 0, 0);
     result.setW(this.getW() + other.getW());
     result.setX(this.getX() + other.getX());
     result.setY(this.getY() + other.getY());
     result.setZ(this.getZ() + other.getZ());
     return result;
 }
示例#3
0
 public Quaternion subtract(Quaternion other)
 {
     // (a - e)+i(b - f)+j(c - g)+k(d - h)
     Quaternion result = new Quaternion(0, 0, 0, 0);
     result.setW(this.getW() - other.getW());
     result.setX(this.getX() - other.getX());
     result.setY(this.getY() - other.getY());
     result.setZ(this.getZ() - other.getZ());
     return result;
 }
示例#4
0
        public Quaternion inverse()
        {
            double s = this.getW();
            Dictionary<string, double> v = new Dictionary<string, double>();
            Quaternion result = new Quaternion(0,0,0,0);

            v.Add("x", this.getX());
            v.Add("y", this.getY());
            v.Add("z", this.getZ());

            double totalToDivideBy = Math.Pow(s, 2)
                + Math.Pow(v["x"], 2)
                + Math.Pow(v["y"], 2)
                + Math.Pow(v["z"], 2);

            result.setW(s / totalToDivideBy);
            result.setX(-v["x"] / totalToDivideBy);
            result.setY(-v["y"] / totalToDivideBy);
            result.setZ(-v["z"] / totalToDivideBy);

            return result;
        }
示例#5
0
        public Quaternion multiply(Quaternion other)
        {
            Quaternion result = new Quaternion(0,0,0,0);

            // FOIL
            Pair myW = new Pair(this.getW(), 0);
            Pair myX = new Pair(this.getX(), 1);
            Pair myY = new Pair(this.getY(), 2);
            Pair myZ = new Pair(this.getZ(), 3);

            Pair otherW = new Pair(other.getW(), 0);
            Pair otherX = new Pair(other.getX(), 1);
            Pair otherY = new Pair(other.getY(), 2);
            Pair otherZ = new Pair(other.getZ(), 3);

            Dictionary<string, double> expression = new Dictionary<string, double>();

            // type, value
            expression.Add("w", 0);
            expression.Add("i", 0);
            expression.Add("j", 0);
            expression.Add("k", 0);
            expression.Add("ij", 0);
            expression.Add("jk", 0);
            expression.Add("ki", 0);
            expression.Add("ji", 0);
            expression.Add("kj", 0);
            expression.Add("ik", 0);
            expression.Add("i^2", 0);
            expression.Add("j^2", 0);
            expression.Add("k^2", 0);

            // first group
            expression["w"] += myW.getX() * otherW.getX();
            expression["i"] += myW.getX() * otherX.getX();
            expression["j"] += myW.getX() * otherY.getX();
            expression["k"] += myW.getX() * otherZ.getX();

            // second group
            expression["i"] += myX.getX() * otherW.getX();
            expression["i^2"] += myX.getX() * otherX.getX();
            expression["ij"] += myX.getX() * otherY.getX();
            expression["ik"] += myX.getX() * otherZ.getX();

            // third group
            expression["j"] += myY.getX() * otherW.getX();
            expression["ji"] += myY.getX() * otherX.getX();
            expression["j^2"] += myY.getX() * otherY.getX();
            expression["jk"] += myY.getX() * otherZ.getX();

            // fourth group
            expression["k"] += myZ.getX() * otherW.getX();
            expression["ki"] += myZ.getX() * otherX.getX();
            expression["kj"] += myZ.getX() * otherY.getX();
            expression["k^2"] += myZ.getX() * otherZ.getX();

            // convert ij and ji
            expression["k"] += expression["ij"];
            expression["k"] += -expression["ji"];

            // convert jk and kj
            expression["i"] += expression["jk"];
            expression["i"] += -expression["kj"];

            // convert ki and ik
            expression["j"] += expression["ki"];
            expression["j"] += -expression["ik"];

            // then convert any squared i|j|k to -1 and store result in "w" index
            double iSquaredResult = expression["i^2"] * -1;
            double jSquaredResult = expression["j^2"] * -1;
            double kSquaredResult = expression["k^2"] * -1;
            expression["w"] += iSquaredResult;
            expression["w"] += jSquaredResult;
            expression["w"] += kSquaredResult;

            result.setW(expression["w"]);
            result.setX(expression["i"]);
            result.setY(expression["j"]);
            result.setZ(expression["k"]);

            if (debugMode)
            {
                Console.WriteLine("\n\nexpression results:");
                foreach (var key in expression.Keys)
                {
                    Console.WriteLine("{0} - {1}", key, expression[key]);
                }
            }

            return result;
        }
示例#6
0
        public Quaternion inverse()
        {
            double s = this.getW();
            Dictionary<string, double> v = new Dictionary<string, double>();
            Quaternion result = new Quaternion(0, 0, 0, 0);

            v.Add("x", this.getX());
            v.Add("y", this.getY());
            v.Add("z", this.getZ());

            double totalToDivideBy = Math.Pow(s, 2)
                + Math.Pow(v["x"], 2)
                + Math.Pow(v["y"], 2)
                + Math.Pow(v["z"], 2);

            result.setW(s / totalToDivideBy);
            result.setX(-v["x"] / totalToDivideBy);
            result.setY(-v["y"] / totalToDivideBy);
            result.setZ(-v["z"] / totalToDivideBy);

            // final round for output (if set)
            if (roundingForOutput)
            {
                result.setW(Math.Round(result.getW(), 4));
                result.setX(Math.Round(result.getX(), 4));
                result.setY(Math.Round(result.getY(), 4));
                result.setZ(Math.Round(result.getZ(), 4));
            }

            return result;
        }
示例#7
0
        public Quaternion divide(Quaternion other)
        {
            // multiply q by inverse of other
            Quaternion result = new Quaternion(0, 0, 0, 0);
            Quaternion inverseOther = other.inverse();

            result = this.multiply(inverseOther);

            return result;
        }
示例#8
0
        public Quaternion divide(Quaternion other)
        {
            // multiply q by inverse of other
            Quaternion result = new Quaternion(0, 0, 0, 0);
            Quaternion inverseOther = other.inverse();

            result = this.multiply(inverseOther);

            // final round for output (if set)
            if (roundingForOutput)
            {
                result.setW(Math.Round(result.getW(), 4));
                result.setX(Math.Round(result.getX(), 4));
                result.setY(Math.Round(result.getY(), 4));
                result.setZ(Math.Round(result.getZ(), 4));
            }

            return result;
        }
示例#9
0
文件: Main.cs 项目: summea/qcalc
        public static void Main(string[] args)
        {
            Quaternion quatA = new Quaternion(1,2,1,2);
            Quaternion quatB = new Quaternion(1,-1,0,2);
            Quaternion result = new Quaternion(0,0,0,0);

            // test inverse
            Console.WriteLine("inverse");
            Console.WriteLine(quatA + "^-1");
            result = quatA.inverse();
            Console.WriteLine(result + "\n");

            quatA = new Quaternion(3, 2, 1, 0);

            // test addition
            Console.WriteLine("add");
            Console.WriteLine(quatA + " + " + quatB);
            result = quatA.add(quatB);
            Console.WriteLine(result + "\n");

            // test subtraction
            Console.WriteLine("subtract");
            Console.WriteLine(quatA + " - " + quatB);
            result = quatA.subtract(quatB);
            Console.WriteLine(result + "\n");

            quatB = new Quaternion(0,1,-2,0);

            // test multiplication
            Console.WriteLine("multiply");
            Console.WriteLine(quatA + " * " + quatB);
            result = quatA.multiply(quatB);
            Console.WriteLine(result + "\n");

            // test division
            // #ADDME
            Console.WriteLine("divide");
            Console.WriteLine(quatA + " / " + quatB);
            result = quatA.divide(quatB);
            Console.WriteLine("inverse of quatB: " + quatB.inverse());
            Console.WriteLine(result + "\n");

            quatA = new Quaternion(1,2,1,2);

            // test magnitude
            Console.WriteLine("magnitude");
            Console.WriteLine(quatA);
            Console.WriteLine(quatA.magnitude() + "\n");

            // test rotation
            Quaternion axis = new Quaternion(0, 0, 0, 1);
            Quaternion point = new Quaternion(0, 5, 0, 0);

            Console.WriteLine("quaternion rotation");
            result = Quaternion.rotatePointByAngleAboutAxisVector(point, Math.PI/2, axis);
            Console.WriteLine(result + "\n");

            // verify rotation manually
            Console.WriteLine("quaternion rotation manual check");
            quatA = new Quaternion(Math.Sqrt(2) / 2, 0, 0, Math.Sqrt(2) / 2);
            Quaternion quatP = new Quaternion(0, 5, 0, 0);

            Console.WriteLine("-- inverse");
            Console.WriteLine(quatA + "^-1");
            result = quatA.inverse();
            Console.WriteLine(result + "\n");

            Console.WriteLine("-- multiply");
            Console.WriteLine(quatA + " * " + quatP);
            result = quatA.multiply(quatP);
            result = result.multiply(quatA.inverse());
            Console.WriteLine(result + "\n");
        }
示例#10
0
        public void runTests()
        {
            Quaternion quatA = new Quaternion(1,2,1,2);
            Quaternion quatB = new Quaternion(1,-1,0,2);
            Quaternion result = new Quaternion(0,0,0,0);

            // test inverse
            TLog.Text += "test inverse\n";
            TLog.Text += quatA + "^-1\n";
            result = quatA.inverse();
            TLog.Text += "= " + result + "\n\n";

            quatA = new Quaternion(3, 2, 1, 0);

            // test addition
            TLog.Text += "test add\n";
            TLog.Text += quatA + " + " + quatB + "\n";
            result = quatA.add(quatB);
            TLog.Text += "= " + result + "\n\n";

            // test subtraction
            TLog.Text += "test subtract\n";
            TLog.Text += quatA + " - " + quatB + "\n";
            result = quatA.subtract(quatB);
            TLog.Text += "= " + result + "\n\n";

            quatB = new Quaternion(0,1,-2,0);

            // test multiplication
            TLog.Text += "test multiply\n";
            TLog.Text += quatA + " * " + quatB + "\n";
            result = quatA.multiply(quatB);
            TLog.Text += "= " + result + "\n\n";

            // test division
            TLog.Text += "test divide\n";
            TLog.Text += quatA + " / " + quatB + "\n";
            result = quatA.divide(quatB);
            TLog.Text += "inverse of quatB: " + quatB.inverse() + "\n";
            TLog.Text += "= " + result + "\n\n";

            quatA = new Quaternion(1,2,1,2);

            // test magnitude
            TLog.Text += "test magnitude\n";
            TLog.Text += quatA + "\n";
            TLog.Text += "= " + quatA.magnitude() + "\n\n";

            // test rotation
            Quaternion point = new Quaternion(0, 5, 0, 0);
            Double angle = Math.PI / 2;
            Quaternion axis = new Quaternion(0, 0, 0, 1);

            TLog.Text += "test quaternion rotation\n";
            TLog.Text += "point: " + point + "\n";
            TLog.Text += "angle: " + angle + "\n";
            TLog.Text += "axis: " + axis + "\n";
            result = Quaternion.rotatePointByAngleAboutAxisVector(point, angle, axis);
            TLog.Text += "= " + result + "\n\n";

            // verify rotation manually
            TLog.Text += "test quaternion rotation (manual functions check)\n";
            quatA = new Quaternion(Math.Sqrt(2) / 2, 0, 0, Math.Sqrt(2) / 2);
            Quaternion quatP = new Quaternion(0, 5, 0, 0);

            TLog.Text += "-- inverse\n";
            TLog.Text += quatA + "^-1\n";
            result = quatA.inverse();
            TLog.Text += result + "\n\n";

            TLog.Text += "-- multiply\n";
            TLog.Text += quatA + " * " + quatP + "\n\n";
            result = quatA.multiply(quatP);
            result = result.multiply(quatA.inverse());
            TLog.Text += "= " + result + "\n\n";
        }
示例#11
0
 private Quaternion parseStringToQuat(String input)
 {
     String[] inputString = input.Split(',');
     Quaternion result = new Quaternion(Convert.ToDouble(inputString[0]), Convert.ToDouble(inputString[1]), Convert.ToDouble(inputString[2]), Convert.ToDouble(inputString[3]));
     return result;
 }
示例#12
0
        private void Operation(String op)
        {
            Quaternion quatA = new Quaternion(0,0,0,0);
            Quaternion quatB = new Quaternion(0,0,0,0);
            Quaternion quatResult = new Quaternion(0,0,0,0);
            Double doubleResult = 0.0f;

            switch (op)
            {
                case "add":
                    quatA = parseStringToQuat(OPQuatABox.Text);
                    quatB = parseStringToQuat(OPQuatBBox.Text);
                    quatResult = quatA.add(quatB);
                    OPResultBox.Text = quatResult.ToString();
                    break;
                case "subtract":
                    quatA = parseStringToQuat(OPQuatABox.Text);
                    quatB = parseStringToQuat(OPQuatBBox.Text);
                    quatResult = quatA.subtract(quatB);
                    OPResultBox.Text = quatResult.ToString();
                    break;
                case "multiply":
                    quatA = parseStringToQuat(OPQuatABox.Text);
                    quatB = parseStringToQuat(OPQuatBBox.Text);
                    quatResult = quatA.multiply(quatB);
                    OPResultBox.Text = quatResult.ToString();
                    break;
                case "divide":
                    quatA = parseStringToQuat(OPQuatABox.Text);
                    quatB = parseStringToQuat(OPQuatBBox.Text);
                    quatResult = quatA.divide(quatB);
                    OPResultBox.Text = quatResult.ToString();
                    break;
                case "inverse":
                    quatA = parseStringToQuat(IMQuatBox.Text);
                    quatResult = quatA.inverse();
                    IMResultBox.Text = quatResult.ToString();
                    break;
                case "magnitude":
                    quatA = parseStringToQuat(IMQuatBox.Text);
                    doubleResult = quatA.magnitude();
                    IMResultBox.Text = doubleResult.ToString();
                    break;
                case "rotate":
                    quatA = parseStringToQuat(RQuatABox.Text);
                    quatB = parseStringToQuat(RQuatBBox.Text);
                    double angleNumerator = 1.0f;

                    if (!string.IsNullOrWhiteSpace(RAngleNumerator.Text))
                        angleNumerator = Convert.ToDouble(RAngleNumerator.Text);

                    double piInNumerator = 1.0f;

                    if (RAngleIncludePIInNumerator.IsChecked.Value)
                        piInNumerator = Math.PI;

                    double angleDenominator = Convert.ToDouble(RAngleDenominator.Text);
                    double angle = (angleNumerator * piInNumerator) / angleDenominator;

                    quatResult = Quaternion.rotatePointByAngleAboutAxisVector(quatA, angle, quatB);
                    RResultBox.Text = quatResult.ToString();
                    break;
                default:
                    break;
            }
        }