/*
This file is part of the FElt finite element analysis package.
Copyright (C) 1993-2000 Jason I. Gobat and Darren C. Atkinson
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/************************************************************************
* File: draw3d.c *
************************************************************************/
# include <math.h>
# include <X11/Intrinsic.h>
# include "Solution.h"
# include "draw3d.h"
static double x_min3d, y_min3d, z_min3d;
static double xscale3d, yscale3d, zscale3d;
static double transform [4][4];
static void CreateUnitMatrix (mat)
double mat[4][4];
{
unsigned i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (i == j)
mat[i][j] = 1.0;
else
mat[i][j] = 0.0;
}
}
}
static void CreateScaleMatrix (sx, sy, sz, mat)
double sx, sy, sz;
double mat[4][4];
{
CreateUnitMatrix(mat);
mat[0][0] = sx;
mat[1][1] = sy;
mat[2][2] = sz;
}
static void MatrixRotationX (theta, mat)
double theta;
double mat[4][4];
{
theta *= M_PI / 180.0;
CreateUnitMatrix(mat);
mat[1][1] = cos(theta);
mat[1][2] = -sin(theta);
mat[2][1] = sin(theta);
mat[2][2] = cos(theta);
}
static void MatrixRotationY (theta, mat)
double theta;
double mat[4][4];
{
theta *= M_PI / 180.0;
CreateUnitMatrix(mat);
mat[0][0] = cos(theta);
mat[0][2] = -sin(theta);
mat[2][0] = sin(theta);
mat[2][2] = cos(theta);
}
static void MatrixRotationZ (theta, mat)
double theta;
double mat[4][4];
{
theta *= M_PI / 180.0;
CreateUnitMatrix(mat);
mat[0][0] = cos(theta);
mat[0][1] = -sin(theta);
mat[1][0] = sin(theta);
mat[1][1] = cos(theta);
}
static void VisMultiplyMatrices (result, mat_a, mat_b)
double result [4][4],
mat_a [4][4],
mat_b [4][4];
{
unsigned i,j,k;
double temp[4][4];
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
temp[i][j] = 0;
for (k = 0; k < 4; k++)
temp[i][j] += mat_a[i][k] * mat_b[k][j];
}
}
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
result[i][j] = temp[i][j];
}
void Convert3Dto2D (x, y, z, xdiff, ydiff, xt, yt)
double x, y, z;
float xdiff, ydiff;
float *xt, *yt;
{
int i,j;
double v[4], res[4],
w = transform[3][3];
v[0] = (x - x_min3d)*xscale3d - 1.0;
v[1] = (y - y_min3d)*yscale3d - 1.0;
v[2] = (z - z_min3d)*zscale3d - 1.0;
v[3] = 1.0;
for (i = 0; i < 2; i++) {
res[i] = transform[3][i];
for (j = 0; j < 3; j++)
res[i] += v[j] * transform[j][i];
}
for (i = 0; i < 3; i++)
w += v[i] * transform[i][3];
if (w == 0)
w = 0.00001;
*xt = ((res[0] * 10.0 / w));
*yt = ((res[1] * 10.0*ydiff/xdiff / w));
}
void Setup3D (min_x, max_x, min_y, max_y, min_z, max_z)
double min_x, max_x;
double min_y, max_y;
double min_z, max_z;
{
double ztemp, temp;
double mat [4][4];
/*
* perform the rotations
*/
MatrixRotationY (solution -> yrot, transform);
MatrixRotationX (solution -> xrot, mat);
VisMultiplyMatrices (transform, transform, mat);
MatrixRotationZ (solution -> zrot, mat);
VisMultiplyMatrices (transform, transform, mat);
CreateScaleMatrix (0.5, 0.5, 0.5, mat);
VisMultiplyMatrices (transform, transform, mat);
/*
* fudge min / max so the z direction will scale
*/
ztemp = (max_z - min_z) / (2.0 * solution -> zscale);
temp = (max_z + min_z) / 2.0;
min_z = temp - ztemp;
max_z = temp + ztemp;
/*
* set the global variables
*/
x_min3d = min_x;
y_min3d = min_y;
z_min3d = min_z;
xscale3d = 2.0/(max_x - min_x);
yscale3d = 2.0/(max_y - min_y);
if (max_z - min_z > 0)
zscale3d = 2.0/(max_z - min_z);
else
zscale3d = 0.0;
}
syntax highlighted by Code2HTML, v. 0.9.1