Hi,
ich habe hier einen zweidimensionalen Vektor und rotiere diesen mit einer 3x3-Matrix um 180°.
Die
Die Koordinaten der Vektoren sind vom Typ
Die
Ich arbeite jetzt hier mal der Einfachheit halber nur mit 2D. Im UnitTest mache ich dann folgendes:
Ich habe also einen Einheitsvektor entlang der Y-Achse und möchte diesen um 180° drehen/rotieren.
So, jetzt das Problem:
Spoiler anzeigen
Test Name: CanRotateTwoDimensionalVector
Test FullName: SharpMath.Tests.VectorTest.CanRotateTwoDimensionalVector
Test Source: C:\Users\Trade\OneDrive\Dokumente\Visual Studio 2015\Projects\SharpMath\SharpMath.Tests\VectorTest.cs : line 98
Test Outcome: Failed
Test Duration: 0:00:00,2366936
Result StackTrace: bei SharpMath.Tests.VectorTest.CanRotateTwoDimensionalVector() in C:\Users\Trade\OneDrive\Dokumente\Visual Studio 2015\Projects\SharpMath\SharpMath.Tests\VectorTest.cs:Zeile 101.
Result Message: Fehler bei "Assert.AreEqual". Erwartet:<X: 0, Y: -1>. Tatsächlich:<X: -1,22460635382238E-16, Y: -1>.
Man sieht, dass der X-Wert minimal über 0 ist. Der Y-Wert stimmt. Woran liegt das? Ist der
Spoiler anzeigen
Just as decimal fractions are unable to precisely represent some fractional values (such as 1/3 or Math.PI), binary fractions are unable to represent some fractional values. For example, 1/10, which is represented precisely by .1 as a decimal fraction, is represented by .001100110011 as a binary fraction, with the pattern "0011" repeating to infinity. In this case, the floating-point value provides an imprecise representation of the number that it represents.
Ist das wirklich das Problem? Macht zeichnerisch wohl kaum viel sichtbaren Unterschied, aber rechnerisch natürlich schon.
Grüße
ich habe hier einen zweidimensionalen Vektor und rotiere diesen mit einer 3x3-Matrix um 180°.
C#-Quellcode
- // ...
- public static Matrix3x3 Identity
- {
- get
- {
- var resultMatrix = new Matrix(3, 3);
- for (uint i = 0; i < resultMatrix.ColumnCount; ++i)
- resultMatrix[i, i] = 1;
- return FromMatrix(resultMatrix);
- }
- }
- public static Matrix3x3 Rotation(double angle)
- {
- double sin = Math.Sin(angle);
- double cos = Math.Cos(angle);
- var matrix = Identity;
- matrix[0, 0] = cos;
- matrix[1, 0] = sin;
- matrix[0, 1] = -sin;
- matrix[1, 1] = cos;
- return matrix;
- }
- // ...
- public static Vector2 operator *(Matrix3x3 matrix, Vector2 vector)
- {
- var resultMatrix = Multiply(matrix, new Vector3(vector.X, vector.Y, 1).AsVerticalMatrix());
- return new Vector2(resultMatrix[0, 0], resultMatrix[1, 0]);
- }
Die
Matrix3x3
-Klasse erbt von Matrix
, wo grundsätzliche Sachen wie der Indexer, Zeilen- und Spaltenanzahl sowie Determinante etc. implementiert sind. Der Index arbeitet mit y, x
, also Row, Column
.Die Koordinaten der Vektoren sind vom Typ
double
, genauso wie die Felder in der Matrix.Die
Multiply
-Funktion sieht so aus:C#-Quellcode
- public static Matrix Multiply(Matrix firstMatrix, Matrix secondMatrix)
- {
- if (firstMatrix.ColumnCount != secondMatrix.RowCount)
- throw new ArgumentException("Cannot multiply the specified matrices because the column count of the first one does not match the row count of the second one.");
- var matrixProduct = new Matrix(firstMatrix.RowCount, secondMatrix.ColumnCount);
- for (uint y = 0; y < matrixProduct.RowCount; ++y)
- {
- for (uint x = 0; x < matrixProduct.ColumnCount; ++x)
- {
- // Iteration condition could be secondMatrix.RowCount, too, as they are equal (see above)
- for (uint i = 0; i < firstMatrix.ColumnCount; ++i)
- matrixProduct[y, x] += firstMatrix[y, i] * secondMatrix[i, x];
- }
- }
- return matrixProduct;
- }
Ich arbeite jetzt hier mal der Einfachheit halber nur mit 2D. Im UnitTest mache ich dann folgendes:
Ich habe also einen Einheitsvektor entlang der Y-Achse und möchte diesen um 180° drehen/rotieren.
Converter.DegreesToRadians(180)
rechnet nur den Wert des Parameters mal Math.PI/180
und gibt ihn zurück.So, jetzt das Problem:
Test Name: CanRotateTwoDimensionalVector
Test FullName: SharpMath.Tests.VectorTest.CanRotateTwoDimensionalVector
Test Source: C:\Users\Trade\OneDrive\Dokumente\Visual Studio 2015\Projects\SharpMath\SharpMath.Tests\VectorTest.cs : line 98
Test Outcome: Failed
Test Duration: 0:00:00,2366936
Result StackTrace: bei SharpMath.Tests.VectorTest.CanRotateTwoDimensionalVector() in C:\Users\Trade\OneDrive\Dokumente\Visual Studio 2015\Projects\SharpMath\SharpMath.Tests\VectorTest.cs:Zeile 101.
Result Message: Fehler bei "Assert.AreEqual". Erwartet:<X: 0, Y: -1>. Tatsächlich:<X: -1,22460635382238E-16, Y: -1>.
Man sieht, dass der X-Wert minimal über 0 ist. Der Y-Wert stimmt. Woran liegt das? Ist der
Double
zu ungenau? Ich habe dazu auch auf MSDN was gelesen und dass man stattdessen Decimal
nutzen soll:Just as decimal fractions are unable to precisely represent some fractional values (such as 1/3 or Math.PI), binary fractions are unable to represent some fractional values. For example, 1/10, which is represented precisely by .1 as a decimal fraction, is represented by .001100110011 as a binary fraction, with the pattern "0011" repeating to infinity. In this case, the floating-point value provides an imprecise representation of the number that it represents.
Ist das wirklich das Problem? Macht zeichnerisch wohl kaum viel sichtbaren Unterschied, aber rechnerisch natürlich schon.
Grüße
#define for for(int z=0;z<2;++z)for // Have fun!
Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose!
Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da
Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose!
Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da