home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
MODEL
/
SEARCH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-25
|
5KB
|
195 lines
/*
* ポリゴンデータ管理ライブラリ
*
* Copyright T.Kobayashi 1993.9.5
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "lib.h"
#include "alloc.h"
#include "buffer.h"
#include "poly.h"
#include "view.h"
/* 最近頂点を検索 */
Vertex *PolyVertex( pos, view )
Vertex *pos ;
int view ;
{
int i, vers ;
int x, y, z ;
Polygon *poly ;
Vertex *ret ;
unsigned int min, len ;
int min2, len2;
int scr[2];
int px, py;
x = pos->x ;
y = pos->y ;
z = pos->z ;
ToScreenPers(scr, pos);
px = scr[0];
py = scr[1];
min = 32767 * 32767 ;
min2 = 32767;
poly = PolyTop();
ret = NULL ;
while( poly != NULL )
{
if ( ( poly->mode & MODE_INVISIBLE ) == 0 )
{
vers = poly->vers ;
switch (view) {
case VIEW_XY:
for( i = 0 ; i < vers ; i++ )
{
len = ( poly->ver[i].x - x ) * ( poly->ver[i].x - x ) +
( poly->ver[i].y - y ) * ( poly->ver[i].y - y );
len2 = ( poly->ver[i].z - z ); if (len2 < 0) len2 = - len2;
if ( len < min || len == min && len2 < min2)
{
min = len ;
min2 = len2;
ret = &( poly->ver[i] );
}
}
break;
case VIEW_YZ:
for( i = 0 ; i < vers ; i++ )
{
len = ( poly->ver[i].y - y ) * ( poly->ver[i].y - y ) +
( poly->ver[i].z - z ) * ( poly->ver[i].z - z ) ;
len2 = ( poly->ver[i].x - x ); if (len2 < 0) len2 = - len2;
if ( len < min || len == min && len2 < min2)
{
min = len ;
min2 = len2;
ret = &( poly->ver[i] );
}
}
break;
case VIEW_ZX:
for( i = 0 ; i < vers ; i++ )
{
len = ( poly->ver[i].x - x ) * ( poly->ver[i].x - x ) +
( poly->ver[i].z - z ) * ( poly->ver[i].z - z ) ;
len2 = ( poly->ver[i].y - y ); if (len2 < 0) len2 = - len2;
if ( len < min || len == min && len2 < min2)
{
min = len ;
min2 = len2;
ret = &( poly->ver[i] );
}
}
break;
case VIEW_PERS:
if (!DrawFrontOnlyFlag || ScreenFront(poly->vec)) {
for (i = 0; i < vers; i++) {
ToScreenPers(scr, &poly->ver[i]);
len = (scr[0]-px) * (scr[0]-px) + (scr[1]-py)*(scr[1]-py);
len2 = ( poly->ver[i].x - x ) * ( poly->ver[i].x - x ) +
( poly->ver[i].y - y ) * ( poly->ver[i].y - y ) +
( poly->ver[i].z - z ) * ( poly->ver[i].z - z ) ;
if ( len < min || len == min && len2 < min2) {
min = len;
min2 = len2;
ret = &(poly->ver[i]);
}
}
}
default:
for( i = 0 ; i < vers ; i++ )
{
len = ( poly->ver[i].x - x ) * ( poly->ver[i].x - x ) +
( poly->ver[i].y - y ) * ( poly->ver[i].y - y ) +
( poly->ver[i].z - z ) * ( poly->ver[i].z - z ) ;
if ( len < min )
{
min = len ;
ret = &( poly->ver[i] );
}
}
}
}
poly = PolyNext( poly );
}
return ret ;
}
/* 平面投射 */
void PolyPlane( ver, plane, vers )
Vertex *ver ; /* 入出力 */
int plane ; /* 投射平面 */
const Vertex *vers ; /* 3 頂点 */
{
int i ;
double a, b, c, d ;
const Vertex *p1, *p2 ;
/* 係数の計算(規格化する) */
p1 = vers ;
p2 = vers + 1 ;
a = b = c = 0.0 ;
for( i = 0 ; i < 2 ; ++i )
{
a += (float)( ( p1->y - p2->y ) * ( p1->z + p2->z ) );
b += (float)( ( p1->z - p2->z ) * ( p1->x + p2->x ) );
c += (float)( ( p1->x - p2->x ) * ( p1->y + p2->y ) );
p1 ++ ;
p2 ++ ;
}
p2 = vers ;
a += (float)( ( p1->y - p2->y ) * ( p1->z + p2->z ) );
b += (float)( ( p1->z - p2->z ) * ( p1->x + p2->x ) );
c += (float)( ( p1->x - p2->x ) * ( p1->y + p2->y ) );
d = - a * (float)vers->x - b * (float)vers->y - c * (float)vers->z ;
switch( plane )
{
case VIEW_XY:
if ( c != 0.0 )
ver->z = (int)( - ( a * (float)ver->x + b * (float)ver->y + d ) / c );
else
MessageWarning( "平面投射できません" );
break ;
case VIEW_YZ:
if ( a != 0.0 )
ver->x = (int)( - ( b * (float)ver->y + c * (float)ver->z + d ) / a );
else
MessageWarning( "平面投射できません" );
break ;
case VIEW_ZX:
if ( b != 0.0 )
ver->y = (int)( - ( a * (float)ver->x + c * (float)ver->z + d ) / b );
else
MessageWarning( "平面投射できません" );
break ;
case VIEW_PERS:
{
double p[3], v0[3], v1[3];
double l, t;
p[0] = PersMatInv[3][0];
p[1] = PersMatInv[3][1];
p[2] = PersMatInv[3][2];
v1[0] = (double)ver->x - p[0];
v1[1] = (double)ver->y - p[1];
v1[2] = (double)ver->z - p[2];
l = a * v1[0] + b * v1[1] + c * v1[2];
t = -(a * p[0] + b * p[1] + c * p[2] + d) / l;
ver->x = (int)( p[0] + v1[0] * t + 0.5);
ver->y = (int)( p[1] + v1[1] * t + 0.5);
ver->z = (int)( p[2] + v1[2] * t + 0.5);
}
break;
default:
;
}
}