362 lines
8.0 KiB
C
362 lines
8.0 KiB
C
// ************************************************************************
|
|
//
|
|
// 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;
|
|
}
|
|
|