# XNA inverted matrix acting strange

First of all, I am trying to calculate the two points of a triangle that have a given z position. I have figured out what I think to be quite a good method. First of all I move the triangle to be centered on (0; 0; 0). I then rotate the triangle to be parallel with the x and z axis. I then calculate the right and left offset using the z offset and I can then calculate the slicing points. Up until here it is completely fine. The issue comes when I try to transform these slicing points to the positions where they should actually be. To do this I invert the product of all the matrices that were applied to the triangle (I am assuming this is the correct procedure because it seems to put the triangle back where it should be).

This seems to work fine on triangles that are parallel with the x axis from the beginning but not on those that are not. The strange thing is that these other triangles are in a situation where their y coordinates are incorrect. Their z coordinates are also incorrect and the amount that the z coordinate differs from the requested z slicing position correlates exactly to the amount that the y coordinate is incorrect. The thing is just that the way this difference should be used to fix the y coordinate differs depending on the angle that the triangle makes with the x axis.

At the moment I am only working with the triangles of a cube sliced into two layers. Therefor all angles are right angles and all edges are parallel with the z axis. If they were not I guess my x coordinates would then also have been incorrect.

I am not sure what could be causing this, but here are some pieces of code that might be relevant:

firstly I transform the triangle to the position where I can easily calculate the slicing points with this method:

``````    public Matrix transformToSlice(long zPosition, out float zDistance)
{
Matrix revertMatrix = Matrix.Identity;

if (zPosition > otherPoint.Z)
{
//Use highest point as top
levelBottom();
}
else
{
//Use lowest point as top
levelTop();
}

zDistance = highestPoint.Z - lowestPoint.Z;

revertMatrix *= centreOnOrigin();
revertMatrix *= flipRightSideDown();
revertMatrix *= rotateXToParallelZ();
revertMatrix *= rotateZToParallelX();

revertMatrix = Matrix.Invert(revertMatrix);

return revertMatrix;
}
``````

All the methods used above return the matrix that they applied to the triangle.

The triangle is sliced with this method:

``````    public LineSegment calculateZSLicePoints(long zPosition)
{
if (point1.Z == point2.Z && point2.Z == point3.Z)
return null;

Vector3 slicePoint1 = new Vector3();
Vector3 slicePoint2 = new Vector3();

//We start by calculating the initial distance between the highest and the lowest point of the triangle before rotating it
//this is sothat we can calculate what the z coordionate will effectively have to be on the rotated triangle
float startDistance;// = highestPoint.Z - otherPoint.Z;

Triangle temp = new Triangle(this);

Matrix revertMatrix = temp.transformToSlice(zPosition, out startDistance);

//We now calculate the z position
float newDistance = temp.highestPoint.Z - temp.otherPoint.Z;
float zMultiplier = newDistance / startDistance;
long newZ = (long)(zPosition * zMultiplier);
long zOff = newZ - lowestPoint.Z;

//We then calculate the overall x and z differences between the top and right points
float xDif = temp.rightPoint.X - temp.highestPoint.X;
float zDif = temp.highestPoint.Z - temp.rightPoint.Z;

//We use the above ration to calculate the x offset of the slicing point
float xOffRight = xDif / zDif * zOff;

//We then calculate the preliminary x coordinate of the first slcing point
long sliceX = (long)(temp.rightPoint.X - xOffRight);

//We then calculate the first slicing point
slicePoint1 = new Vector3(sliceX, temp.rightPoint.Y, /*zPosition - centrePoint.Z*/temp.rightPoint.Z + zOff);
slicePoint1 = Vector3.Transform(slicePoint1, revertMatrix);

//We then calculate the overall x and z differences between the top and left points
xDif = temp.highestPoint.X - temp.leftPoint.X;
zDif = temp.highestPoint.Z - temp.leftPoint.Z;

//We use the above ration to calculate the x offset of the slicing point
float xOffLeft = xDif / zDif * zOff;

//We then calculate the preliminary x coordinate of the second slcing point
sliceX = (long)(temp.leftPoint.X + xOffLeft);

//We then calculate the second slicing point
slicePoint2 = new Vector3(sliceX, temp.leftPoint.Y, /*zPosition - centrePoint.Z*/temp.leftPoint.Z + zOff);
slicePoint2 = Vector3.Transform(slicePoint2, revertMatrix);

//We just round the values a bit to remove some of the decimal errors that might have occured
slicePoint1.X = (long)(Math.Round((double)slicePoint1.X / 10) * 10);
slicePoint1.Y = (long)(Math.Round((double)slicePoint1.Y / 10) * 10);
slicePoint2.X = (long)(Math.Round((double)slicePoint2.X / 10) * 10);
slicePoint2.Y = (long)(Math.Round((double)slicePoint2.Y / 10) * 10);

//Finally we return the two points as a LineSegment
return new LineSegment(new IntPoint(slicePoint1.X, slicePoint1.Y), new IntPoint(slicePoint2.X, slicePoint2.Y));
}
``````

Here are some examples of the results that I am getting:

1. y should be: 2500 y is : 7500 z should be: 2500 z is : 7501

2. y should be: 10000 y is : 7500 z should be: 2500 z is : 1

3. y should be: 7500 y is : 2500 z should be: 2500 z is : 7500

4. y should be: 1000 y is : 7500 z should be: 2500 z is : 1

EDIT: Even though in the above data it seem that I can just take the z difference and add it to the y value, this is merely a coincidence because if you think about it that can never work. I have also in fact tried it and the results are actually quite horrific (lines are shorter than they should be and in other cases they go outside the bounds of the original cube...)

-
Curious. What ultimately are you trying to accomplish? I mean the "Why" behind your first sentence. –  Steve H Sep 18 '13 at 17:09
I am trying to slice a 3D model up into 2D layers. –  Gerhman Sep 18 '13 at 17:11