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 + -
显示快捷键?