p3dcoords.c

来自「speech signal process tools」· C语言 代码 · 共 1,240 行 · 第 1/2 页

C
1,240
字号
/* * This material contains unpublished, proprietary software of  * Entropic Research Laboratory, Inc. Any reproduction, distribution,  * or publication of this work must be authorized in writing by Entropic  * Research Laboratory, Inc., and must bear the notice:  * *    "Copyright (c) 1986-1990  Entropic Speech, Inc.  *    "Copyright (c) 1990-1993  Entropic Research Laboratory, Inc.  *                   All rights reserved" * * The copyright notice above does not evidence any actual or intended  * publication of this source code.      * * Written by:  Rodney W. Johnson, Entropic Speech, Inc. * Checked by: * Revised by: * * Brief description:  Handle coordinate transformations. * */static char *sccs_id = "@(#)p3dcoords.c	1.13	6/24/93	ESI/ERL"; #include <stdio.h>#include <math.h>#include <esps/esps.h>#include <esps/unix.h>#include <esps/constants.h>#include "plot3d.h"extern int  debug_level;extern int  force_monochrome_plot;extern void drawline();extern void drawlines();extern void drawpoint();extern void drawing_style();void	    update_mats();void	    make_rmat(), update_rmat();void	    make_imats();int	    base_trans();int	    can_width = 250,	    can_height = 250;int	    length = 150,	    width = 250,	    height = 400;int	    box_dims[3] = {150, 250, 400};double	    hskew = 0.0,	    vskew = 0.0,	    finv = 0.0005;		/* 1/finv = coord normal to screen					   of center of projection.					   (0 => parallel proj.) */int	    ori = -1;			/* orientation (handedness) of axes.					   -1 = left, 1 = right. */double	    rot = 0.0,	    sin_psi = 0.0,	cos_psi = 1.0,	    bear = 0.0,	    sin_theta = 0.0,	cos_theta = 1.0,	    elev = 0.0,	    sin_phi = 0.0,	cos_phi = 1.0;double	    xlow = 0.0,	    xhigh = 100.0,	xscale = 1.0,	    ylow = 0.0,	    yhigh = 100.0,	yscale = 1.0,	    zlow = 0.0,	    zhigh = 100.0,	zscale = 1.0;		/* transformation matrices */double	    tmat[3][4];		/* plot coordinates to canvas coordinates */double	    smat[3][4];		/* data coordinates to canvas coordinates */double	    rmat[3][3];		/* rotation matrix, used in updating rota-				/* tion angles with mouse movements */double	    amat[3][3];		/* axis-label coords to canvas coords */double	    base_imat[3][3];	/* canvas to data coords in base plane */double	    pmatx[3][4],	/* project on vertical planes in data */	    pmaty[3][4];	/*     space, for checking visibility */double	    pconstx, pconsty;	/* used with pmats; coordinates locating the				   vertical planes */				/* normal vectors to box faces */int	    face_nor[6][3] =   {{-1,  0,  0}, { 1,  0,  0},				{ 0, -1,  0}, { 0,  1,  0},				{ 0,  0, -1}, { 0,  0,  1}};				/* edge lists of box faces */int	    face_edge[6][4] =  {{ 4,  8,  5,  9},				{ 6, 11,  7, 10},				{ 0, 10,  1,  8},				{ 2,  9,  3, 11},				{ 0,  4,  2,  6},				{ 1,  7,  3,  5}};				/* face lists of box edges */int	    edge_face[12][2] = {{2, 4}, {2, 5}, {3, 4}, {3, 5},				{0, 4}, {0, 5}, {1, 4}, {1, 5},				{0, 2}, {0, 3}, {1, 2}, {1, 3}};				/* vertex lists of box edges */				/* directed low end to high end */int	    edge_vert[12][2] = {{0, 4}, {1, 5}, {2, 6}, {3, 7},				{0, 2}, {1, 3}, {4, 6}, {5, 7},				{0, 1}, {2, 3}, {4, 5}, {6, 7}};				/* edge parallel to x-axis (0), y-axis (1),				   or z-axis (2)? */int	    edge_dir[12] =     {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2};				/* vertex lists of box faces				   (counter-clockwise order as seen				   from outside) */int	    face_vert[6][4] =  {{0, 1, 3, 2},				{4, 6, 7, 5},				{0, 4, 5, 1},				{2, 3, 7, 6},				{0, 2, 6, 4},				{1, 5, 7, 3}};				/* normalized coordinates of box vertices				   (mult by {length, width, height}				   to get coords in plot space) */int	    vert_coor[8][3] =  {{ 0,  0,  0},				{ 0,  0,  1},				{ 0,  1,  0},				{ 0,  1,  1},				{ 1,  0,  0},				{ 1,  0,  1},				{ 1,  1,  0},				{ 1,  1,  1}};/* numbering of box's * *                faces                               edges * *        (0) *          \      (5) *         _________|____                      _____(5)______ *        |\  \     |    \                    |\             \ *        | \       |   | \                   | \           | \ *        |  \  \          \                  | (1)           (3) *        |   \         |   \                (8)  \        (9)  \ *        |    \ ____________\                |    \ _____(7)____\ *        |     |       |     |               |     |       |     | *   (2)-----   |           - |--(3)          |     |             | *        |_  _ |_  _  _|     |               |_  _ |(4)_  _|     | *         \    |        \    |                \  (10)          (11) *          \   |             |                 \   |         \   | *           \  |       \  \  |                 (0) |         (2) | *            \ |   |    \    |                   \ |           \ | *             \|_________\__\|                    \|_____(6)_____| *                  |      \ *                 (4)     (1) * * * *               vertices * * *       (1)___________(3) *        |\             \ *        | \           | \ *        |  \             \ *        |   \         |   \ *        |    (5)___________(7)              z *        |     |       |     |               | *        |     |             |               | *       (0)_  _| _  _ (2)    |               |_____y *         \    |        \    |                \ *          \   |             |                 \ *           \  |          \  |                  x *            \ |             | *             (4)___________(6) * */voidset_canv_dimens(w, h)    int	    w, h;{    can_width = w;    can_height = h;    update_mats();}voidset_box_len(n)    int     n;{    length = box_dims[0] = n;    xscale = length / (xhigh - xlow);    update_mats();}intget_box_len(){    return length;}voidset_box_wid(n)    int     n;{    width = box_dims[1] = n;    yscale = width / (yhigh - ylow);    update_mats();}intget_box_wid(){    return width;}voidset_box_hgt(n)    int     n;{    height = box_dims[2] = n;    zscale = height / (zhigh - zlow);    update_mats();}intget_box_hgt(){    return height;}voidset_hskew(x)    double  x;{    hskew = x;    update_mats();}doubleget_hskew(){    return hskew;}   voidset_vskew(x)    double  x;{    vskew = x;    update_mats();}doubleget_vskew(){    return vskew;}   voidset_finv(x)    double x;{    finv = 0.00001*x;    update_mats();}doubleget_finv(){    return 100000.0*finv;}voidset_ori(n)    int	    n;{    if (n == ORI_RIGHT)	ori = 1;    else	ori = -1;    update_mats();}intget_ori(){    return (ori == 1) ? ORI_RIGHT : ORI_LEFT;}voidset_rot(x)    double x;{    rot = x;    sin_psi = sin(rot);    cos_psi = cos(rot);    update_mats();}doubleget_rot(){    return rot;}voidset_bear(x)    double x;{    bear = x;    sin_theta = sin(bear);    cos_theta = cos(bear);    update_mats();}doubleget_bear(){    return bear;}voidset_elev(x)    double x;{    elev = x;    sin_phi = sin(elev);    cos_phi = cos(elev);    update_mats();}doubleget_elev(){    return elev;}voidupdate_mats(){    double  m[4][4];    int	    i, j;    double  ctr_x, ctr_y, ctr_z, ctr_u, ctr_v;    /* matrix for rotation in xy-, xz-, and yz-planes (homogeneous coords) */    /*     *       /          0 \     *   m = |   rmat   0 |     *       |          0 |     *       \ 0  0  0  1 /     */    make_rmat();    for (i = 0; i < 3; i++)    {	for (j = 0; j < 3; j++)	    m[i][j] = rmat[i][j];	m[i][3] = 0.0;    }    for (j = 0; j < 3; j++)	m[3][j] = 0.0;    m[3][3] = 1.0;    /* precede with orientation setting */    /*     *         / -1    0    0  0 \     *   m = m |  0  - ori  0  0 |     *         |  0    0    1  0 |     *         \  0    0    0  1 /     */    for (i = 0; i < 3; i++)    {	m[i][0] = -m[i][0];	m[i][1] = -ori*m[i][1];    }    /* ... and with translation of center of box to origin */    /*     *         / 1  0  0  - length/2 \     *   m = m | 0  1  0  - width/2  |     *         | 0  0  1  - height/2 |     *         \ 0  0  0       1     /     */    ctr_x = 0.5*length;	ctr_y = 0.5*width;  ctr_z = 0.5*height;    for (i = 0; i < 3; i++)	m[i][3] = - m[i][0]*ctr_x - m[i][1]*ctr_y - m[i][2]*ctr_z;    /* follow with projection into yz-plane */    /*     *       / - hskew  1  0  0 \     *   m = | - vskew  0  1  0 | m     *       \ - finv   0  0  1 /     */    for (j = 0; j < 4; j++)    {	m[1][j] -= hskew*m[0][j];	m[2][j] -= vskew*m[0][j];	m[3][j] -= finv*m[0][j];    }    /* map into canvas coordinates (translate origin to center of canvas) */    /*     *          / 1    0  can_width/2  \     *   tmat = | 0  - 1  can_height/2 | m     *          \ 0    0        1      /     */    ctr_u = 0.5*can_width;	ctr_v = 0.5*can_height;    for (j = 0; j < 4; j++)    {	tmat[0][j] = m[1][j] + ctr_u*m[3][j];	tmat[1][j] = - m[2][j] + ctr_v*m[3][j];	tmat[2][j] = m[3][j];    }    if (debug_level >= 2)	printmat("tmat", &tmat[0][0], 3, 4);    /* tmat defined--now do smat */    /* precede transformation with scaling from data units to plot units */    /*     *               / xscale     0       0    0 \     *   smat = tmat |    0    yscale     0    0 |     *               |    0       0    zscale  0 |     *               \    0       0       0    1 /     */    for (i = 0; i < 3; i++)    {	smat[i][0] = tmat[i][0]*xscale;	smat[i][1] = tmat[i][1]*yscale;	smat[i][2] = tmat[i][2]*zscale;	smat[i][3] = tmat[i][3];    }	    if (debug_level >= 2)	printmat("scale", &smat[0][0], 3, 4);    /* precede that with translation of coordinate low limits to origin */    /*     *               / 1  0  0  - xlow \     *   smat = smat | 0  1  0  - ylow |     *               | 0  0  1  - zlow |     *               \ 0  0  0     1   /     */    for (i = 0; i < 3; i++)	smat[i][3] -= (smat[i][0]*xlow + smat[i][1]*ylow + smat[i][2]*zlow);    if (debug_level >= 2)	printmat("trans smat", &smat[0][0], 3, 4);    make_imats();}voidmake_rmat(){    double  t;    int	    i, j;    for (i = 0; i < 3; i++)	for (j = 0; j < 3; j++)	    rmat[i][j] = 0.0;    /* rotation in xy-plane */    /*     *          /   cos theta  sin theta  0 \     *   rmat = | - sin theta  cos theta  0 |     *          \      0           0      1 /     */    rmat[0][0] = cos_theta;	rmat[0][1] = sin_theta;    rmat[1][0] = -sin_theta;	rmat[1][1] = cos_theta;    rmat[2][2] = 1.0;    /* rotation in xz-plane */    /*     *          /   cos phi  0  sin phi \     *   rmat = |     0      1     0    | rmat     *          \ - sin phi  0  cos phi /     */    for (j = 0; j < 3; j++)    {	t = cos_phi*rmat[0][j] + sin_phi*rmat[2][j];	rmat[2][j] = - sin_phi*rmat[0][j] + cos_phi*rmat[2][j];	rmat[0][j] = t;    }    /* rotation in yz-plane */    /*     *          / 1      0         0    \     *   rmat = | 0    cos psi  sin psi | rmat     *          \ 0  - sin psi  cos psi /     */    for (j = 0; j < 3; j++)    {	t = cos_psi*rmat[1][j] + sin_psi*rmat[2][j];	rmat[2][j] = - sin_psi*rmat[1][j] + cos_psi*rmat[2][j];	rmat[1][j] = t;    }    if (debug_level >= 2)    {	(void) fprintf(stderr, "make_rmat:\n  sin theta %g,\tcos theta %g\n",			sin_theta, cos_theta);	(void) fprintf(stderr, "  sin phi   %g,\tcos phi   %g\n",			sin_phi, cos_phi);	(void) fprintf(stderr, "  sin psi   %g,\tcos psi   %g\n",			sin_psi, cos_psi);	printmat("rmat", &rmat[0][0], 3, 3);    }	}voidupdate_rmat(th, ph, theta, phi, psi)    double  th, ph, *theta, *phi, *psi;{    if (th == 0.0 && ph == 0.0)    {	*theta = bear;	*phi = elev;	*psi = rot;    }    else    {	double	r, c, s, t, ps, dif;	int	j;	r = sqrt(th*th + ph*ph);	th /= r;	ph /= r;	c = cos(r);	s = sin(r);	/* transform axis of rotation to z axis */	/*	 *          / 1   0    0 \	 *   rmat = | 0   th  ph | rmat	 *          \ 0  -ph  th /	 */		for (j = 0; j < 3; j++)	{	    t = th*rmat[1][j] + ph*rmat[2][j];	    rmat[2][j] = -ph*rmat[1][j] + th*rmat[2][j];	    rmat[1][j] = t;	}	/* do the rotation */	/*	 *          /  c  s  0 \	 *   rmat = | -s  c  0 | rmat	 *          \  0  0  1 /	 */		for (j = 0; j < 3; j++)	{	    t = c*rmat[0][j] + s*rmat[1][j];	    rmat[1][j] = -s*rmat[0][j] + c*rmat[1][j];	    rmat[0][j] = t;	}	/* transform z axis back to rotation axis */	/*	 *          / 1   0   0  \	 *   rmat = | 0  th  -ph | rmat	 *          \ 0  ph   th /	 */	for (j = 0; j < 3; j++)	{	    t = th*rmat[1][j] - ph*rmat[2][j];	    rmat[2][j] = ph*rmat[1][j] + th*rmat[2][j];	    rmat[1][j] = t;	}	if (debug_level >= 2)	{	    (void) fprintf(stderr, "update_rmat:  th %g, ph %g\n", th, ph);	    printmat("rmat", &rmat[0][0], 3, 3);	}	/* solve for new Euler angles */	*phi = asin(rmat[0][2]);	s = rmat[1][2];		/* sin psi cos phi */	c = rmat[2][2];		/* cos psi cos phi */	ps = (s == 0.0 && c == 0.0) ? 0.0 : atan2(s, c);				/* approx. psi */	s = rmat[0][1];	/* cos phi sin theta */	c = rmat[0][0];	/* cos phi cos theta */	th = (s == 0.0 && c == 0.0) ? 0.0 : atan2(s, c);				/* approx. theta */	/* psi and theta may be poorly determined if cos phi is small;	 * but their sum or difference is well determined.	 *//*!*//* if cos phi not small output ps and th ... */	if (*phi > 0.0)	{	    s = - rmat[1][0] - rmat[2][1];				/* (1 + sin phi) sin (psi + theta) */	    c = rmat[1][1] - rmat[2][0];				/* (1 + sin phi) cos (psi + theta) */	    dif = atan2(s, c) - (ps + th);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?