/*
* Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT,
* Applied Mathematics, Norway.
*
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
*
* This file is part of SISL.
*
* SISL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* SISL 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with SISL. If not, see
* .
*
* In accordance with Section 7(b) of the GNU Affero General Public
* License, a covered work must retain the producer line in every data
* file that is created or manipulated using SISL.
*
* Other Usage
* You can be released from the requirements of the license by purchasing
* a commercial license. Buying such a license is mandatory as soon as you
* develop commercial activities involving the SISL library without
* disclosing the source code of your own applications.
*
* This file may be used in accordance with the terms contained in a
* written agreement between you and SINTEF ICT.
*/
#include "sisl-copyright.h"
/*
*
* $Id: sh1790.c,v 1.2 2001-03-19 15:59:05 afr Exp $
*
*/
#define SH1790
#include "sislP.h"
#if defined(SISLNEEDPROTOTYPES)
void sh1790(SISLObject *po1,SISLObject *po2,int itype,
double aepsge,int *jstat)
#else
void sh1790(po1,po2,itype,aepsge,jstat)
SISLObject *po1;
SISLObject *po2;
int itype;
double aepsge;
int *jstat;
#endif
/*
*********************************************************************
*
*********************************************************************
*
* PURPOSE : Perform a box-test on the two object given by
* po1 and po2 and check if the boxes overlap.
*
*
*
* INPUT : po1 - First object.
* po2 - Second object.
* itype - Kind of box to make.
* = 0 : Do not expand box.
* = 1 : Make a totally expanded box.
* = 2 : Make a box expanded in the inner of the
* object, and reduced along the edges/endpoints.
* If itype>=10, it is interpreted as itype-10. This
* code is present to reduce the number of sides in
* the box to be made.
* aepsge - Geometry resolution.
*
*
* OUTPUT : jstat - status messages
* = 5 : Danger of shadow area in point
* intersection.
* = 4 : One box is collapsed into a point.
* = 3 : Both boxes inside geometry resolution.
* = 2 : Overlap as closed sets only.
* = 1 : Overlap as open sets.
* = 0 : No overlap.
* < 0 : error
*
*
* METHOD :
*
*
* REFERENCES :
*
*-
* CALLS :
*
* WRITTEN BY : Arne Laksaa, SI, 89-03.
* Arne Laksaa, SI, 89-07.
* REWISED BY : Vibeke Skytt, SI, 91-01. Tolerance dependant boxes.
* CORRECTED BY: UJK and ALA, SI, 91-08. Removed edge test
* REWISED BY : VSK, SI, 92-10. Transform tolerance to other object when a point
* is included. Special check on "shadow area",
* which may arise in point-object intersection
* where the point lies outside the reduced box
* of the other object, but still within a
* distance less than the tolerance from the
* object itself (in particular curve). This
* is possible near the endpoints/edges of the
* other object.
*********************************************************************
*/
{
int kstat = 0; /* Local status error. */
int kpos = 0; /* Position of error. */
int ktype = itype%10; /* Type of box to make. */
int kant; /* Number of sides in all boxes. */
int kdim1,kdim2; /* Dimension of space. */
int ki,kj=0; /* Counters. */
int kpttest=0; /* Indicates wether one object is a point and
the geometry has dimension greater than 1.
In that case the boundaries of the box is
placed further out in the min- and max-arrays. */
int kshadow = 0; /* Indicates if there is a risk of a shadow areas */
int kbez = 0; /* Indicates if any object is a bezier object. */
double tdist; /* Distance between boxes. */
double teps1; /* To be used in 1D. */
double teps2; /* Two times aepsge if expanded box. */
double tepsge = aepsge; /* Tolerance to be used locally. In 1D
tepsge=2*aepsge since the point is not
expended. */
double t1,t2,t3,t4; /* Help variables. */
double t01,t02,t03,t04; /* Help variables. */
double *tmin1,*tmax1; /* Smallest and larges value of the vertices of
first object in each box in all dimension. */
double *tmin2,*tmax2; /* Smallest and larges value of the vertices of
second object in each box in all dimension.*/
/* Set local tolerance. */
teps2 = (ktype == 0) ? aepsge : (double)2.0*aepsge;
/* Check if one object is a point. */
if (po1->iobj == SISLPOINT) kdim1 = po1->p1->idim;
else if (po1->iobj == SISLCURVE) kdim1 = po1->c1->idim;
else if (po1->iobj == SISLSURFACE) kdim1 = po1->s1->idim;
if (kdim1 == 1)
{
if (ktype != 0) teps2 = (double)3.0*aepsge;
teps1 = (ktype == 0) ? aepsge : aepsge+aepsge;
if (po1->iobj == SISLPOINT || po2->iobj == SISLPOINT)
tepsge += aepsge;
}
else
{
teps1 = DZERO;
if (po1->iobj == SISLPOINT || po2->iobj == SISLPOINT)
kpttest = 1;
}
/* Compute the box of the first object. */
sh1992(po1,itype,tepsge,&kstat);
if (kstat < 0) goto error;
/* VSK. 06.93. Adjust microbox tolerance in bezier case. */
if (ktype != 0 && kstat == 1) kbez = 1;
/* Set pointers to box boundaries. */
if (po1->iobj == SISLPOINT)
{
tmin1 = po1->p1->pbox->e2min[ktype];
tmax1 = po1->p1->pbox->e2max[ktype];
}
else if (po1->iobj == SISLCURVE)
{
tmin1 = po1->c1->pbox->e2min[ktype];
tmax1 = po1->c1->pbox->e2max[ktype];
}
else if (po1->iobj == SISLSURFACE)
{
tmin1 = po1->s1->pbox->e2min[ktype];
tmax1 = po1->s1->pbox->e2max[ktype];
}
else goto err121;
/* Make requested box. */
sh1992(po2,itype,tepsge,&kstat);
if (kstat < 0) goto error;
/* VSK. 06.93. Adjust microbox tolerance in bezier case. */
if (ktype != 0 && kstat == 1) kbez += 1;
if (kdim1 == 1 && kbez > 0) teps2 -= (double)2.0*aepsge;
else if (kbez > 0) teps2 -= aepsge;
if (kbez) teps1 = aepsge;
/* Set pointers to box boundaries. */
if (po2->iobj == SISLPOINT)
{
tmin2 = po2->p1->pbox->e2min[ktype];
tmax2 = po2->p1->pbox->e2max[ktype];
kdim2 = po2->p1->idim;
}
else if (po2->iobj == SISLCURVE)
{
tmin2 = po2->c1->pbox->e2min[ktype];
tmax2 = po2->c1->pbox->e2max[ktype];
kdim2 = po2->c1->idim;
}
else if (po2->iobj == SISLSURFACE)
{
tmin2 = po2->s1->pbox->e2min[ktype];
tmax2 = po2->s1->pbox->e2max[ktype];
kdim2 = po2->s1->idim;
}
else goto err121;
/* Check dimension. */
if (kdim1 != kdim2 ) goto err106;
else
if (kdim1 < 1 ) goto err105;
/* Compute total number of SISLbox edges. */
if (itype < 10 && kdim1 == 3) kant = 9;
else
if (itype < 10 && kdim1 == 2) kant = 4;
else kant = kdim1;
/* For each dimension in all boxes perform box-test. First check
that we point on the right place in the min- and max-arrays. */
if (kpttest)
{
tmin1 += kant;
tmin2 += kant;
tmax1 += kant;
tmax2 += kant;
}
for (ki=0; ki *tmax2)
{
t1 = *tmax1; t01 = *(tmax1 - kant*kpttest);
t2 = *tmin1; t02 = *(tmin1 - kant*kpttest);
t3 = *tmax2; t03 = *(tmax2 - kant*kpttest);
t4 = *tmin2; t04 = *(tmin2 - kant*kpttest);
}
else
{
t1 = *tmax2; t01 = *(tmax2 - kant*kpttest);
t2 = *tmin2; t02 = *(tmin2 - kant*kpttest);
t3 = *tmax1; t03 = *(tmax1 - kant*kpttest);
t4 = *tmin1; t04 = *(tmin1 - kant*kpttest);
}
tdist = t2 - t3;
/* Use non-expanded boxes when testing if minibox is possible. */
if (t01 - min(t02,t04) <= teps2)
kj++; /* Minibox is possible. */
else if (kdim1 == 1 && t01-t04 <= teps1 && t03-t02 <= teps1)
kj++; /* Minibox is possible. */
else if (t3 < t2 && (tdist > teps2 || !kpttest))
{
*jstat = 0; /* No overlap. */
goto out;
}
else if (t3 < t2)
kshadow = 1; /* Danger of shadow area. */
/* UJK and ALA, 91-08: The tolerance is now
incorporated in the box.
else if (kdim1 != 1 && t3 - t2 < tepsge && t3 - t4 > teps2 &&
t1 - t2 > teps2)
{
*jstat = 2; Only edge touching possible.
goto degenerate;
}
else if ( kdim1 == 1 && (t1 - t4 < tepsge || t3 - t2 < tepsge))
{
*jstat = 2; Only edge touching possible.
goto out;
} */
/* else possible overlap. */
}
if (kj == kant)
*jstat = 3; /* Minibox found. */
else if (kshadow)
*jstat = 5; /* Danger of shadow area. */
else
*jstat = 1; /* Overlap. */
/* Box-test performed. */
/* degenerate: */
/* Test if one of the objects has collapsed. Use non-expanded box. */
if (kdim1 != 1 && po1->iobj > SISLPOINT)
{
if (po1->iobj == SISLCURVE)
{
tmin1 = po1->c1->pbox->e2min[ktype];
tmax1 = po1->c1->pbox->e2max[ktype];
}
else if (po1->iobj == SISLSURFACE)
{
tmin1 = po1->s1->pbox->e2min[ktype];
tmax1 = po1->s1->pbox->e2max[ktype];
}
/* Make sure that we are correct place in the min- and max-arrays. */
if (kpttest)
{
tmin1 += kant;
tmax1 += kant;
}
for(ki=0;ki tepsge) break;
if (ki == kdim1+1)
{
*jstat = 4;
goto out;
}
}
if (kdim1 != 1 && po2->iobj > SISLPOINT)
{
if (po2->iobj == SISLCURVE)
{
tmin1 = po2->c1->pbox->e2min[ktype];
tmax1 = po2->c1->pbox->e2max[ktype];
}
else if (po2->iobj == SISLSURFACE)
{
tmin1 = po2->s1->pbox->e2min[ktype];
tmax1 = po2->s1->pbox->e2max[ktype];
}
/* Make sure that we are correct place in the min- and max-arrays. */
if (kpttest)
{
tmin1 += kant;
tmax1 += kant;
}
for(ki=0;ki tepsge) break;
if (ki == kdim1+1)
{
*jstat = 4;
goto out;
}
}
goto out;
/* Dimensions conflicting. */
err106: *jstat = -106;
s6err("sh1790",*jstat,kpos);
goto out;
/* Dimensions less than one. */
err105: *jstat = -105;
s6err("sh1790",*jstat,kpos);
goto out;
/* Kind of object does not exist. */
err121: *jstat = -121;
s6err("sh1790",*jstat,kpos);
goto out;
/* Error in lower level routine. */
error: *jstat = kstat;
s6err("sh1790",*jstat,kpos);
goto out;
out: return;
}