pipeutil.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 754 行 · 第 1/2 页
C
754 行
normal.v[0] *= 0.5;
normal.v[1] *= -0.5;
normal.v[2] *= 0.5;
len = norm( normal );
normal.v[0] /= len;
normal.v[1] /= len;
normal.v[2] /= len;
next_pt = (*get_pt)( data, 0 );
normal.v[3] = 0 - (normal.v[0]*next_pt.p[0] +
normal.v[1]*next_pt.p[1] +
normal.v[2]*next_pt.p[2]);
return( normal );
}
extern vector point_diff(
/***********************/
point pt1,
point pt2
) {
vector v;
int i;
for (i = 0; i < 4; i++) {
v.v[i] = pt2.p[i] - pt1.p[i];
}
return( v );
}
/* matrix manipulation routines */
extern point mult_matrix_pt(
/**************************/
float matrix[4][4],
point in
) {
point out;
int i;
int j;
for (i = 0; i < 4; i++) {
out.p[i] = 0.;
for (j = 0; j < 4; j++) {
out.p[i] += matrix[i][j] * in.p[j];
}
}
return( out );
}
/* line intersection */
static bool line_intersection(
/****************************/
/* Sets the param where the lines (as infinite lines) intersect. Returns FALSE*/
/* if the lines are parallel */
/* See Log Notes, set 5 */
/* NOTE: this is a 2d algorithm used for the projection of lines */
wcoord line1[2],
wcoord line2[2],
float *t,
float *k
) {
wcoord v1; /* vector between the two points */
wcoord v2;
float d;
v1.xcoord = line1[1].xcoord - line1[0].xcoord;
v1.ycoord = line1[1].ycoord - line1[0].ycoord;
v2.xcoord = line2[1].xcoord - line2[0].xcoord;
v2.ycoord = line2[1].ycoord - line2[0].ycoord;
d = v1.xcoord*v2.ycoord - v1.ycoord*v2.xcoord;
if (fabs( d ) < FUZZY_ZERO) {
/* lines are parallel so don't intersect */
return( FALSE );
} else {
*t = ( v2.xcoord * (line1[0].ycoord - line2[0].ycoord) -
v2.ycoord * (line1[0].xcoord - line2[0].xcoord) ) / d;
if (fabs( v2.xcoord ) < fabs( v2.ycoord )) {
*k = (line1[0].ycoord + *t *v1.ycoord - line2[0].ycoord)/v2.ycoord;
} else {
*k = (line1[0].xcoord + *t *v1.xcoord - line2[0].xcoord)/v2.xcoord;
}
/* the lines intersect where the parameter are t and k resp. so */
/* the line segments intersects if both t and k are in [0,1] */
return( TRUE );
}
}
extern bool proj_line_intersection(
/*********************************/
/* Determine if the projection of line1 and line2 into the x-y plane intersect*/
/* Returns true if the line segments line1 and line2 intersect. */
point line1[2],
point line2[2]
) {
wcoord ln1[2];
wcoord ln2[2];
float t,k;
/* perform the projection */
ln1[0].xcoord = line1[0].p[0];
ln1[0].ycoord = line1[0].p[1];
ln1[1].xcoord = line1[1].p[0];
ln1[1].ycoord = line1[1].p[1];
ln2[0].xcoord = line2[0].p[0];
ln2[0].ycoord = line2[0].p[1];
ln2[1].xcoord = line2[1].p[0];
ln2[1].ycoord = line2[1].p[1];
if (line_intersection( ln1, ln2, &t, &k )) {
return( 0. <= t && t <= 1. && 0. <= k && k <= 1. );
} else {
/* the lines are parallel so they don't intersect */
return( FALSE );
}
}
/* RGB to/from HLS conversions */
extern void rgb_to_hls(
/*********************/
/* This is base on the procedure given in "Computer Graphics" by Foley et. */
/* al. p. 595 */
COLORREF rgb,
hls_colour *hls
) {
float r, g, b;
float max, min;
float delta;
r = _wpi_getrvalue( rgb ) / 255.;
g = _wpi_getgvalue( rgb ) / 255.;
b = _wpi_getbvalue( rgb ) / 255.;
max = _max( _max( r, g ), b );
min = _min( _min( r, g ), b );
/* set the lightness */
hls->l = (max + min) / 2.;
/* set the saturation */
if (max == min) { /* anchromatic case because r==b==g */
hls->s = 0;
hls->h = 0; /* UNDEFINDED */
} else { /* chromatic case */
if (hls->l < 0.5) {
hls->s = (max - min) / (max + min);
} else {
hls->s = (max - min) / (2 - max - min);
}
/* set the hue */
delta = max - min;
if (r == max) { // colour is between yellow and magenta
hls->h = (g - b) / delta;
} else if (g == max) { // colour is between cyan and yellow
hls->h = 2. + (b - r) / delta;
} else { // colour is between magenta and cyan
hls->h = 4. + (r - g) / delta;
}
/* convert h to degrees */
hls->h *= 60.;
/* make sure h is positive */
if (hls->h < 0.) {
hls->h += 360.;
}
}
}
static float value(
/****************/
float n1,
float n2,
float hue
) {
if (hue > 360.) {
hue -= 360.;
} else if (hue < 0.) {
hue += 360.;
}
if (hue < 60.) {
return( n1 + (n2-n1) * hue / 60. );
} else if (hue < 180.) {
return( n2 );
} else if (hue < 240.) {
return( n1 + (n2-n1) * (240.-hue) / 60. );
} else {
return( n1 );
}
}
extern void hls_to_rgb(
/*********************/
COLORREF *rgb,
hls_colour hls
) {
float r, g, b;
float m1, m2;
if (hls.l <= .5) {
m2 = hls.l * (1 + hls.s);
} else {
m2 = hls.l + hls.s - hls.l * hls.s;
}
m1 = 2. * hls.l - m2;
if (hls.s == 0.) { // anchromatic case
r = hls.l;
g = hls.l;
b = hls.l;
} else { // chromatic case
r = value( m1, m2, hls.h + 120. );
g = value( m1, m2, hls.h );
b = value( m1, m2, hls.h - 120. );
}
*rgb = _wpi_getrgb( r * 255, g * 255, b * 255 );
}
/* rectangle, ray intersection */
static bool ray_line_inter(
/*************************/
float x1, // point 1 of the line
float y1,
float x2, // point 2
float y2,
wcoord ray_start,
wcoord ray_dir,
wcoord *inter
) {
wcoord ln1[2];
wcoord ln2[2];
float t,k;
ln1[0].xcoord = x1;
ln1[0].ycoord = y1;
ln1[1].xcoord = x2;
ln1[1].ycoord = y2;
ln2[0] = ray_start;
ln2[1].xcoord = ray_start.xcoord + ray_dir.xcoord;
ln2[1].ycoord = ray_start.ycoord + ray_dir.ycoord;
if (line_intersection( ln1, ln2, &t, &k )) {
/* don't accept if k is close to 0 since that means the ray */
/* starts on the line */
if ( FUZZY_ZERO < k ) {
inter->xcoord = ray_start.xcoord + k*ray_dir.xcoord;
inter->ycoord = ray_start.ycoord + k*ray_dir.ycoord;
return( TRUE );
} else {
return( FALSE );
}
} else {
return( FALSE );
}
}
extern bool rect_ray_inter(
/*************************/
wcoord rect[2],
wcoord ray_start,
wcoord ray_dir,
wcoord *inter
) {
float len;
/* normalize ray_dir */
len = sqrt( ray_dir.xcoord*ray_dir.xcoord + ray_dir.ycoord*ray_dir.ycoord );
ray_dir.xcoord /= len;
ray_dir.ycoord /= len;
/* is the ray more vertical than horizontal? */
if( fabs( ray_dir.ycoord ) > fabs( ray_dir.xcoord ) ) {
/* check against the horizontal edges of rect */
if (ray_line_inter( rect[0].xcoord, rect[0].ycoord,
rect[1].xcoord, rect[0].ycoord,
ray_start, ray_dir, inter )) {
return( TRUE );
}
if (ray_line_inter( rect[1].xcoord, rect[1].ycoord,
rect[0].xcoord, rect[1].ycoord,
ray_start, ray_dir, inter )) {
return( TRUE );
}
} else {
/* check against the vertical edges of rect */
if (ray_line_inter( rect[1].xcoord, rect[0].ycoord,
rect[1].xcoord, rect[1].ycoord,
ray_start, ray_dir, inter )) {
return( TRUE );
}
if (ray_line_inter( rect[0].xcoord, rect[0].ycoord,
rect[0].xcoord, rect[1].ycoord,
ray_start, ray_dir, inter )) {
return( TRUE );
}
}
/* no intersection on any of the edges so set inter arbitrarily */
inter->xcoord = rect[0].xcoord;
inter->ycoord = rect[0].ycoord;
return( FALSE );
}
#ifdef INCLUDE_DEBUG_ROUTINES
/* DEBUG ROUTINES */
#include <stdio.h>
extern void dbg_print_list(
/*************************/
rend_list * list
) {
FILE * fp;
int curr_obj;
char path[ _MAX_PATH ];
dbg_get_filename( path );
fp = fopen( path, "w" );
if (fp == NULL) {
return;
}
fprintf( fp, "list address: %p\n", (void *) list );
for (curr_obj = 0; curr_obj <= list->last; curr_obj++) {
fprintf( fp, "OBJECT NUMBER %d--------------------------"
"-------------------\n", curr_obj );
dbg_print_one_obj( fp, list->list[ curr_obj ], FALSE );
}
fclose( fp );
}
extern void dbg_print_list_long(
/******************************/
rend_list * list
) {
FILE * fp;
int curr_obj;
char path[ _MAX_PATH ];
dbg_get_filename( path );
fp = fopen( path, "w" );
if (fp == NULL) {
return;
}
fprintf( fp, "list address: %p\n", (void *) list );
for (curr_obj = 0; curr_obj <= list->last; curr_obj++) {
fprintf( fp, "OBJECT NUMBER %d--------------------------"
"-------------------\n", curr_obj );
dbg_print_one_obj( fp, list->list[ curr_obj ], TRUE );
}
fclose( fp );
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?