Recent Testing: Mul and Inv work for 3x3 matrix, more testing coming

check www.happypedestrian.com/lwjgl/matrixop.html for current status
This commit is contained in:
Tristan Campbell 2002-09-07 19:52:01 +00:00
parent 9e58e87ce9
commit 0078885178
5 changed files with 110 additions and 40 deletions

View File

@ -288,14 +288,21 @@ void DstMatrix::writeRecord()
void subMatrix (const float * src, int side, float * dst , int col_omit, int row_omit)
{
int index = 0;
int src_index = 0;
for (int c = 0; c < side; c++)
{
if (c == col_omit) continue;
if (c == col_omit)
{ src_index += side;
continue;
}
for (int r = 0; r < side; r++)
{
if (r == row_omit) continue;
dst[index++] = src[r + c * side];
if (r == row_omit)
{ src_index++;
continue;
}
dst[index++] = src[src_index++];
}
}
}
@ -311,20 +318,21 @@ float determinant (const float * matrix , int side)
det = matrix[0] * matrix[3] - matrix[2] * matrix[1];
else
{
int temp_side = side - 1;
float temp_matrix [temp_side * temp_side];
float sign = 1;
int temp_side = side - 1; // the dimensions of the sub matrix
float temp_matrix [temp_side * temp_side]; // hold a sub matrix of this matrix
bool sign_pos = 1; // the sign is positive
for (int i = 0; i < side; i++)
for (int row = 0; row < side; row++)
{
// get a sub matrix by eliminating the ith row and the 0th column
subMatrix(matrix, side, temp_matrix, 0, i);
// get a sub matrix by eliminating the 0th col and the specified row
subMatrix(matrix, side, temp_matrix, 0, row);
// add to the determinant sign * [a]i0 * [M]i0
det += sign * matrix[i] * determinant (temp_matrix, temp_side);
det += ((sign_pos) ? matrix[row] :
-matrix[row]) * determinant (temp_matrix, temp_side);
// alternate the sign
sign = (sign == 1) ? -1 : 1;
sign_pos ^= 1;
}
}

View File

@ -77,25 +77,41 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpDire
int temp_side = source.width-1;
float temp_matrix [temp_side*temp_side];
for (int i = 0; i < source.elements; i++)
for (int i = 0; i < source.elements; i++)
{
sourceRecord = source.nextRecord();
destRecord = dest.nextRecord();
float det = determinant(sourceRecord, sourceWidth);
// calculate the determinant
float det = determinant(sourceRecord, source.width);
#ifdef _DEBUG
printf("Determinant: %f\n", det);
#endif
float sign;
for (int c = 0; c < source.width; c++)
for (int col = 0; col < source.width; col++)
{
sign = (c & 1) ? 1.0f : -1.0f;
/*
Maintain sign:
+ - + - ...
- + - + ..
+ - + - ..
- + - + ..
: : : : \
*/
sign = (col & 1) ? -1.0f : 1.0f;
for (int r = 0; r < source.width; r++)
for (int row = 0; row < source.height; row++)
{
// get the sub matrix
subMatrix(sourceRecord, source.width, temp_matrix, c, r);
subMatrix(sourceRecord, source.width, temp_matrix, col, row);
// transpose the result
destRecord[r + c * source.width]
destRecord[col + row * source.height]
= (sign / det) * determinant(temp_matrix, temp_side);
// swap signs

View File

@ -38,12 +38,16 @@
* @author cix_foo <cix_foo@users.sourceforge.net>
* @version $Revision$
*/
#ifdef _DEBUG
#include <stdio.h>
#endif
#include <windows.h>
#include "org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe.h"
#include "MatrixOpCommon.h"
/*
* Class: org_lwjgl_Math_MatrixOpInvert_MatrixOpSafe
* Method: execute
@ -82,20 +86,36 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpInvert_00024MatrixOpSafe
sourceRecord = source.nextRecord();
destRecord = dest.nextRecord();
float det = determinant(sourceRecord, sourceWidth);
// calculate the determinant
float det = determinant(sourceRecord, source.width);
#ifdef _DEBUG
printf("Determinant: %f\n", det);
#endif
float sign;
for (int c = 0; c < source.width; c++)
for (int col = 0; col < source.width; col++)
{
sign = (c & 1) ? 1.0f : -1.0f;
/*
Maintain sign:
+ - + - ...
- + - + ..
+ - + - ..
- + - + ..
: : : : \
*/
sign = (col & 1) ? -1.0f : 1.0f;
for (int r = 0; r < source.width; r++)
for (int row = 0; row < source.height; row++)
{
// get the sub matrix
subMatrix(sourceRecord, source.width, temp_matrix, c, r);
subMatrix(sourceRecord, source.width, temp_matrix, col, row);
// transpose the result
destRecord[r + c * source.width]
destRecord[col + row * source.height]
= (sign / det) * determinant(temp_matrix, temp_side);
// swap signs

View File

@ -91,33 +91,45 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpMultiply_00024MatrixOpDi
// check out discussions envolving ordering
left.rewind();
for (int i = 0; i < leftElements; i++)
left.rewind();
for (int i = 0; i < left.elements; i++)
{
leftRecord = left.nextRecord();
right.rewind();
for (int j = 0; j < rightElements; j++)
for (int j = 0; j < right.elements; j++)
{
rightRecord = right.nextRecord();
destRecord = dest.nextRecord();
memset(destRecord, 0, dest.width * dest.height * sizeof(jfloat));
// zero the elements of the destination matrix
for (int d = 0; d < dest.width * dest.height; d++)
destRecord[d] = 0;
// loop through each column of the right matrix
int rightCell = 0;
for (int rightCol = 0; rightCol < right.width; rightCol++)
{
for (int leftIndex = 0; leftIndex < left.width*left.height; leftIndex++)
// [RxC] * [RxC]
// dest has same height as left
// dest has same width as right
int leftCell = 0;
for (int leftCol = 0; leftCol < left.width; leftCol++)
{
destRecord[i % dest.height] += leftRecord[i] * rightRecord[i / leftSourceHeight];
for (int leftRow = 0; leftRow < left.height; leftRow++)
{
destRecord[leftRow] += rightRecord[rightCell] * leftRecord[leftCell++];
}
rightCell ++ ;
}
rightRecord = &rightRecord[right.height];
//rightRecord = &rightRecord[right.height];
destRecord = &destRecord[dest.height];
}
dest.writeRecord();
}
}
}
}

View File

@ -39,6 +39,7 @@
* @version $Revision$
*/
#include <windows.h>
#include "org_lwjgl_Math_MatrixOpMultiply_MatrixOpSafe.h"
#include "MatrixOpCommon.h"
@ -91,26 +92,39 @@ JNIEXPORT void JNICALL Java_org_lwjgl_Math_00024MatrixOpMultiply_00024MatrixOpSa
left.rewind();
for (int i = 0; i < leftElements; i++)
for (int i = 0; i < left.elements; i++)
{
leftRecord = left.nextRecord();
right.rewind();
for (int j = 0; j < rightElements; j++)
for (int j = 0; j < right.elements; j++)
{
rightRecord = right.nextRecord();
destRecord = dest.nextRecord();
memset(destRecord, 0, dest.width * dest.height * sizeof(jfloat));
// zero the elements of the destination matrix
for (int d = 0; d < dest.width * dest.height; d++)
destRecord[d] = 0;
// loop through each column of the right matrix
int rightCell = 0;
for (int rightCol = 0; rightCol < right.width; rightCol++)
{
for (int leftIndex = 0; leftIndex < left.width*left.height; leftIndex++)
// [RxC] * [RxC]
// dest has same height as left
// dest has same width as right
int leftCell = 0;
for (int leftCol = 0; leftCol < left.width; leftCol++)
{
destRecord[i % dest.height] += leftRecord[i] * rightRecord[i / leftSourceHeight];
for (int leftRow = 0; leftRow < left.height; leftRow++)
{
destRecord[leftRow] += rightRecord[rightCell] * leftRecord[leftCell++];
}
rightCell ++ ;
}
rightRecord = &rightRecord[right.height];
//rightRecord = &rightRecord[right.height];
destRecord = &destRecord[dest.height];
}