home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware 1 2 the Maxx
/
sw_1.zip
/
sw_1
/
PROGRAM
/
CBGRX100.ZIP
/
CONTRIB
/
LIBGRX
/
SRC
/
FILLPOLY.C
< prev
next >
Wrap
Text File
|
1992-04-10
|
5KB
|
152 lines
/**
** FILLPOLY.C
**
** Copyright (C) 1992, Csaba Biegl
** 820 Stirrup Dr, Nashville, TN, 37221
** csaba@vuse.vanderbilt.edu
**
** This file is distributed under the terms listed in the document
** "copying.cb", available from the author at the address above.
** A copy of "copying.cb" should accompany this file; if not, a copy
** should be available from where this file was obtained. This file
** may not be distributed without a verbatim copy of "copying.cb".
** You should also have received a copy of the GNU General Public
** License along with this program (it is in the file "copying");
** if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
** Cambridge, MA 02139, USA.
**
** 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.
**/
#include "grx.h"
#include "libgrx.h"
#include "clipping.h"
#include "scale.h"
void _GrScanConvexPoly(int n,int pt[][2],_GrScanLineProc lnproc,void *lnarg)
{
int lx1,ly1,lx2,ly2,ldx,ldy;
int rx1,ry1,rx2,ry2,rdx,rdy;
int lslope,lerror,lcalc;
int rslope,rerror,rcalc;
int bottom,left,right;
int x1,x2,yy,next,dir;
MOUSE_FLAG;
lx1 = ly1 = 32000;
lx2 = ly2 = (-32000);
for(yy = 0; yy < n; yy++) {
if(lx1 > pt[yy][0]) lx1 = pt[yy][0];
if(lx2 < pt[yy][0]) lx2 = pt[yy][0];
if(ly1 > pt[yy][1]) ly1 = pt[yy][1],left = yy;
if(ly2 < pt[yy][1]) ly2 = pt[yy][1];
}
if(ly1 == ly2) {
CLIPHLINE(CURC,lx1,lx2,ly1);
MOUSE_BLOCK(CURC,lx1,ly1,lx2,ly1);
(*lnproc)(lx1,lx2,ly1,lnarg);
MOUSE_UNBLOCK();
return;
}
CLIPSORTEDBOX(CURC,lx1,ly1,lx2,ly2);
MOUSE_BLOCK(CURC,lx1,ly1,lx2,ly2);
bottom = ly2;
lx1 = rx1 = pt[left][0];
ly1 = ry1 = pt[left][1];
if((right = left + 1) == n) right = 0;
if(--left < 0) left = n - 1;
dir = 0;
if(pt[left][0] > pt[right][0]) {
dir = 1;
EXCHG(left,right);
}
for( ; ; ) {
lx2 = pt[left][0];
if(((ly2 = pt[left][1]) >= _GrLoY) && (ly2 != ly1)) break;
lx1 = lx2; ly1 = ly2;
if(dir) { if(++left == n) left = 0; }
else { if(--left < 0) left = n - 1; }
}
for( ; ; ) {
rx2 = pt[right][0];
if(((ry2 = pt[right][1]) >= _GrLoY) && (ry2 != ry1)) break;
rx1 = rx2; ry1 = ry2;
if(dir) { if(--right < 0) right = n - 1; }
else { if(++right == n) right = 0; }
}
if(ly1 < _GrLoY) {
SCALE(lcalc,(lx1 - lx2),(ly2 - _GrLoY),(ly2 - ly1));
lx1 = lx2 + lcalc;
ly1 = _GrLoY;
}
if(ry1 < _GrLoY) {
SCALE(rcalc,(rx1 - rx2),(ry2 - _GrLoY),(ry2 - ry1));
rx1 = rx2 + rcalc;
ry1 = _GrLoY;
}
yy = ly1; lcalc = rcalc = TRUE;
for( ; ; ) {
if(lcalc && ((ldy = ly2 - ly1) > 0)) {
lslope = (ldx = lx2 - lx1) / ldy;
if((ldx %= ldy) < 0) { lslope--; ldx += ldy; }
lerror = (ldy >> 1);
}
if(rcalc && ((rdy = ry2 - ry1) > 0)) {
rslope = (rdx = rx2 - rx1) / rdy;
if((rdx %= rdy) < 0) { rslope--; rdx += rdy; }
rerror = (rdy >> 1);
}
if((next = MIN(ly2,ry2)) > bottom) next = bottom;
while(yy < next) {
if((lx1 <= _GrHiX) && (rx1 >= _GrLoX)) {
if((x1 = lx1) < _GrLoX) x1 = _GrLoX;
if((x2 = rx1) > _GrHiX) x2 = _GrHiX;
(*lnproc)(x1,x2,yy,lnarg);
}
lx1 += lslope;
if((lerror -= ldx) < 0) { lx1++; lerror += ldy; }
rx1 += rslope;
if((rerror -= rdx) < 0) { rx1++; rerror += rdy; }
yy++;
}
if(next == bottom) break;
lcalc = rcalc = FALSE;
while(next == ly2) {
lx1 = lx2; ly1 = ly2;
if(dir) { if(++left == n) left = 0; }
else { if(--left < 0) left = n - 1; }
lx2 = pt[left][0];
ly2 = pt[left][1];
lcalc = TRUE;
}
while(next == ry2) {
rx1 = rx2; ry1 = ry2;
if(dir) { if(--right < 0) right = n - 1; }
else { if(++right == n) right = 0; }
rx2 = pt[right][0];
ry2 = pt[right][1];
rcalc = TRUE;
}
}
if((lx1 <= _GrHiX) && (rx1 >= _GrLoX)) {
if((x1 = lx1) < _GrLoX) x1 = _GrLoX;
if((x2 = rx1) > _GrHiX) x2 = _GrHiX;
(*lnproc)(x1,x2,yy,lnarg);
}
MOUSE_UNBLOCK();
}
static void default_lineproc(int x1,int x2,int y,void *arg)
{
_GrSetPixRow(PIXEL_ADDR(x1,y),(int)arg,(x2 - x1 + 1));
}
void GrFilledPolygon(int numpts,int points[][2],int c)
{
_GrScanConvexPoly(numpts,points,default_lineproc,(void *)c);
}