magic/bplane/bpTest.c

362 lines
8.0 KiB
C
Raw Normal View History

// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
/* bpTest.c
*
* (regression) tests of bplane code
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "utils.h"
#include "message.h"
#include "database.h"
#include "geometry.h"
#include "bplane.h"
#include "bplaneInt.h"
#include "debug.h"
#include "cifInt.h"
/*
* elements used by test code.
*/
typedef struct rectc
{
struct rectc *rc_links[BP_NUM_LINKS];
Rect rc_rect;
} RectC;
/*
* ----------------------------------------------------------------------------
* bpRand --
* generate a random int in given range.
*
* side effects: sets coords of input rect.
* ----------------------------------------------------------------------------
*/
int bpRand(int min, int max)
{
double f = rand()/ (double) RAND_MAX; /* random number in unit interval */
return min + (int) ((max-min+1)*f);
}
/*
* ----------------------------------------------------------------------------
* bpTestRandRect --
* generate a random unit rectangle inside bbox
*
* side effects: sets coords of input rect.
* ----------------------------------------------------------------------------
*/
static void bpTestRandRect(Rect *r, Rect *bbox)
{
r->r_xbot = bpRand(bbox->r_xbot,bbox->r_xtop-1);
r->r_ybot = bpRand(bbox->r_ybot,bbox->r_ytop-1);
r->r_xtop = r->r_xbot+1;
r->r_ytop = r->r_ybot+1;
}
/* ====== GOLD snow test.
* ====== linked list implementation (to determine 'right' answer)
*/
/*
* ----------------------------------------------------------------------------
* bpTestIntersectGold --
*
* check whether rc intersects list
* ----------------------------------------------------------------------------
*/
static bool bpTestIntersectGold(RectC *rc, RectC *list)
{
while(list)
{
if(GEO_TOUCH(&rc->rc_rect,&list->rc_rect)) return TRUE;
list=list->rc_links[0];
}
return FALSE;
}
/*
* ----------------------------------------------------------------------------
* bpTestSnowGold --
* populate square of dimension 'size' with non-overlapping random unit
* rectangles. Keep adding rectangles until failures exceed successes.
* (stop when maxFailures reached.)
*
* coded with simple linked list.
*
* ---------------------------------------------------------------------------- */
void bpTestSnowGold(int size, bool trace)
{
int failures = 0;
int successes = 0;
int i = 0;
int crc = 0;
RectC *result = NULL;
RectC *rc = NULL;
Rect area;
fprintf(stderr,"BEGIN Snow GOLD, size=%d\n", size);
/* set up area */
area.r_xbot = 0;
area.r_ybot = 0;
area.r_xtop = size;
area.r_ytop = size;
while(failures<=successes)
{
i++;
if(!rc) rc = MALLOC_TAG(RectC *,rc, sizeof(RectC), "RectC");
bpTestRandRect(&rc->rc_rect, &area);
if(!bpTestIntersectGold(rc,result))
{
if(trace) DumpRect("success ",&rc->rc_rect);
crc ^= i+ 3*rc->rc_rect.r_xbot+ 5*rc->rc_rect.r_ybot;
rc->rc_links[0] = result;
result = rc;
rc = NULL;
successes++;
}
else
{
if(trace) DumpRect("failure ",&rc->rc_rect);
failures++;
}
}
/* clean up */
while(result)
{
/* pop */
rc=result;
result=rc->rc_links[0];
/* free */
FREE(rc);
}
fprintf(stderr,"END Snow GOLD, size=%d failures=%d successes=%d crc=%d\n",
size,
failures,
successes,
crc);
}
/* ====== bplane snow test.
*/
/*
* ----------------------------------------------------------------------------
* bpTestIntersect --
*
* check whether rc intersects list
* ----------------------------------------------------------------------------
*/
static bool bpTestIntersect(RectC *rc, BPlane *bp)
{
BPEnum bpe;
int result;
BPEnumInit(&bpe,bp, &rc->rc_rect, BPE_TOUCH,"bpTestIntersect");
result = (BPEnumNext(&bpe)!=NULL);
BPEnumTerm(&bpe);
return result;
}
/*
* ----------------------------------------------------------------------------
* bpTestSnow --
* populate area with non-overlapping random unit rectangles.
*
* using bplane.
*
* ----------------------------------------------------------------------------
*/
BPlane *bpTestSnow(int size, bool trace)
{
int failures = 0;
int successes = 0;
int i = 0;
int crc = 0;
RectC *result = NULL;
RectC *rc = NULL;
BPlane *bp = BPNew();
Rect area;
fprintf(stderr,"BEGIN Snow, size=%d\n", size);
/* set up area */
area.r_xbot = 0;
area.r_ybot = 0;
area.r_xtop = size;
area.r_ytop = size;
while(failures<=successes)
{
i++;
if(!rc) rc = MALLOC_TAG(RectC *,rc, sizeof(RectC), "RectC");
bpTestRandRect(&rc->rc_rect, &area);
if(!bpTestIntersect(rc,bp))
{
if(trace) DumpRect("success ",&rc->rc_rect);
crc ^= i+ 3*rc->rc_rect.r_xbot+ 5*rc->rc_rect.r_ybot;
BPAdd(bp,rc);
rc = NULL;
successes++;
}
else
{
if(trace) DumpRect("failure ",&rc->rc_rect);
failures++;
}
}
fprintf(stderr,"END Snow, size=%d failures=%d success=%d crc=%d\n",
size,
failures,
successes,
crc);
return bp;
}
/* ====== Tile Plane based snow test.
*/
/*
* ----------------------------------------------------------------------------
* bpTestIntersectTile --
*
* check whether r intersects existing tiles
*
* ----------------------------------------------------------------------------
*/
int bpTestIntersectTileFunc(Tile *tile, ClientData cd)
{
return 1;
}
static bool bpTestIntersectTile(Rect *r, Plane *plane)
{
Rect area;
/* catch touching tiles */
area = *r;
area.r_xbot -= 1;
area.r_ybot -= 1;
area.r_xtop += 1;
area.r_ytop += 1;
return DBPlaneEnumAreaPaint((Tile *) NULL,
plane,
&area,
&DBAllButSpaceBits,
bpTestIntersectTileFunc,
NULL);
}
/*
* ----------------------------------------------------------------------------
* bpTestSnowTile --
* populate area with non-overlapping random unit rectangles.
*
* using tile plane
*
* ----------------------------------------------------------------------------
*/
Plane *bpTestSnowTile(int size, bool trace)
{
int failures = 0;
int successes = 0;
int i = 0;
int crc = 0;
RectC *result = NULL;
RectC *rc = NULL;
Plane *plane = DBPlaneNew((ClientData) TT_SPACE);
Rect area;
fprintf(stderr,"BEGIN Snow Tile, size=%d\n", size);
/* set up area */
area.r_xbot = 0;
area.r_ybot = 0;
area.r_xtop = size;
area.r_ytop = size;
while(failures<=successes)
{
Rect r;
i++;
bpTestRandRect(&r, &area);
if(!bpTestIntersectTile(&r,plane))
{
if(trace) DumpRect("success ",&r);
crc ^= i+ 3*r.r_xbot + 5*r.r_ybot;
DBPaintPlane(plane, &r, CIFPaintTable, (PaintUndoInfo *) NULL);
rc = NULL;
successes++;
}
else
{
if(trace) DumpRect("failure ",&r);
failures++;
}
}
fprintf(stderr,"END Snow Tile, size=%d failures=%d success=%d crc=%d\n",
size,
failures,
successes,
crc);
return plane;
}