/*
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
*
* Description:
*
****************************************************************************/
# include <stdio.h>
# include <string.h>
# include <math.h>
# include "problem.h"
# include "error.h"
# define WindowWidth 400
# define WindowHeight 400
double x_min3d, y_min3d, z_min3d;
double xscale3d, yscale3d, zscale3d;
double transform [4][4];
static void MultiplyTransformMatrices (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];
}
}
}
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 Convert3Dto2D (x, y, z, xdiff, ydiff, xt, yt)
double x, y, z;
double xdiff, ydiff;
double *xt, *yt;
{
int i,j;
double v[4], res[4];
double w;
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));
}
static void Setup3D (min_x, max_x, min_y, max_y, min_z, max_z, xrot, yrot, zrot, zsc)
double min_x, max_x;
double min_y, max_y;
double min_z, max_z;
double xrot, yrot, zrot;
double zsc;
{
double ztemp, temp;
double mat [4][4];
/*
* perform the rotations
*/
MatrixRotationY (yrot, transform);
MatrixRotationX (xrot, mat);
MultiplyTransformMatrices (transform, transform, mat);
MatrixRotationZ (zrot, mat);
MultiplyTransformMatrices (transform, transform, mat);
CreateScaleMatrix (0.5, 0.5, 0.5, mat);
MultiplyTransformMatrices (transform, transform, mat);
/*
* fudge min / max so the z direction will scale
*/
ztemp = (max_z - min_z) / (2.0 * zsc);
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;
return;
}
void WriteWireframe3D (fp, table, n, mag, xrot, yrot, zrot, zsc)
FILE *fp;
Node **table;
unsigned n;
double mag;
double xrot;
double yrot;
double zrot;
double zsc;
{
int i, j;
double maxX, minX, maxY, minY, maxZ, minZ;
double Xscale, Yscale;
int height, width;
double x, y, z;
double sx, sy;
double sx1, sy1;
double sx2, sy2;
int isx1, isy1;
int isy2, isx2;
double w,h;
double xdiff, ydiff;
maxX = minX = table [1][1] -> x;
maxY = minY = table [1][1] -> y;
maxZ = minZ = table [1][1] -> z;
if (zsc == 0.0)
zsc = 1.0;
for (i = 1 ; i <= n ; i++) {
for (j = 1 ; j <= 2 ; j++) {
x = table [i][j] -> x + table [i][j] -> dx [1] * mag;
y = table [i][j] -> y + table [i][j] -> dx [2] * mag;
z = table [i][j] -> z + table [i][j] -> dx [3] * mag;
if (x > maxX) maxX = x;
else if (x < minX) minX = x;
if (y > maxY) maxY = y;
else if (y < minY) minY = y;
if (z > maxZ) maxZ = z;
else if (z < minZ) minZ = z;
}
}
Setup3D (minX, maxX, minY, maxY, minZ, maxZ, xrot, yrot, zrot, zsc);
xdiff = maxX - minX;
ydiff = maxY - minY;
for (i = 1 ; i <= n ; i++) {
for (j = 1 ; j <= 2; j++) {
x = table [i][j] -> x + table [i][j] -> dx [1] * mag;
y = table [i][j] -> y + table [i][j] -> dx [2] * mag;
z = table [i][j] -> z + table [i][j] -> dx [3] * mag;
Convert3Dto2D (x, y, z, xdiff, ydiff, &sx, &sy);
if (i == 1 && j == 1) {
maxX = minX = sx;
maxY = minY = sy;
}
else {
if (sx > maxX) maxX = sx;
else if (sx < minX) minX = sx;
if (sy > maxY) maxY = sy;
else if (sy < minY) minY = sy;
}
}
}
maxX += 0.05*(maxX - minX);
maxY += 0.05*(maxY - minY);
minY -= 0.05*(maxY - minY);
minX -= 0.05*(maxX - minX);
height = WindowHeight;
width = WindowWidth;
w = (double) WindowWidth;
h = (double) WindowHeight;
if ((maxX - minX)/w > (maxY - minY)/h) {
Xscale = (float) (w/(maxX - minX));
Yscale = Xscale;
height = (int) ((maxY - minY) * Yscale);
}
else {
Yscale = (float) (h/(maxY - minY));
Xscale = Yscale;
width = (int) ((maxX - minX) * Xscale);
}
fprintf (fp, "%d, %d\n", width, height);
for (i = 1 ; i <= n ; i++) {
x = table [i][1] -> x + table [i][1] -> dx [1] * mag;
y = table [i][1] -> y + table [i][1] -> dx [2] * mag;
z = table [i][1] -> z + table [i][1] -> dx [3] * mag;
Convert3Dto2D (x, y, z, xdiff, ydiff, &sx1, &sy1);
x = table [i][2] -> x + table [i][2] -> dx [1] * mag;
y = table [i][2] -> y + table [i][2] -> dx [2] * mag;
z = table [i][2] -> z + table [i][2] -> dx [3] * mag;
Convert3Dto2D (x, y, z, xdiff, ydiff, &sx2, &sy2);
isx1 = (int) ((sx1 - minX) * Xscale);
isy1 = (int) (height - (sy1 - minY) * Yscale);
isx2 = (int) ((sx2 - minX) * Xscale);
isy2 = (int) (height - (sy2 - minY) * Yscale);
fprintf (fp, "%d, %d, %d, %d\n", isx1, isy1, isx2, isy2);
}
return;
}
syntax highlighted by Code2HTML, v. 0.9.1