/*
* 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: s1787.c,v 1.3 2005-02-28 09:04:49 afr Exp $
*
*/
#define S1787
#include "sislP.h"
#if defined(SISLNEEDPROTOTYPES)
void
s1787(SISLSurf *ps,double alevel,double aepsge,double epar[],
double gpar1[],double gpar2[],int *jstat)
#else
void s1787(ps,alevel,aepsge,epar,gpar1,gpar2,jstat)
SISLSurf *ps;
double alevel;
double aepsge;
double epar[];
double gpar1[];
double gpar2[];
int *jstat;
#endif
/*
*********************************************************************
*
*********************************************************************
*
* PURPOSE : In surface-point intersection in dimention one.
* To search for endpoints on an intersection curve.
* The intersection curve must go through the parameter
* pair epar. If the function find a closed curve
* it will return a status message 2.
* Else if epar is an edge point the function
* will return parameter values for the other end point
* on the intersection curve in gpar1 and a status message
* 1. If epar is an internal point the function will
* return the parameter values for the two endpoints on
* the intersection curve in gpar1 and gpar2 and a status
* message 0.
*
*
* INPUT : ps - The surface in intersection.
* alevel - The constant value the surface is intersected with.
* aepsge - Geometry resolution.
* epar[2] - Parameter values for the intersection point.
*
*
*
* OUTPUT : gpar1[2] - Parameter values for the first intersection point.
* One of the ends are within computer tolerance from
* epar, then this point is put in this variable and
* the status 1 is returned.
* gpar2[2] - Parameter values for the second intersection point
* on the edges. If closed curve found with no singular
* point this point is equal to the first point.
* jstat - status messages
* < 0 : Error.
* = 0 : The marching did not succeed.
* = 11 : epar == gpar1. Open curve.
* = 12 : epar == gpar1. Open curve. gpar2 inside.
* = 13 : epar == gpar1. Open curve. gpar1 inside.
* = 14 : epar == gpar1. Open curve. Both ends inside.
* = 16 : epar == gpar1. Closed curve. gpar2 == gpar1
* = 17 : epar == gpar1. Closed curve. gpar2 singular.
* = 21 : epar != output points. Open curve.
* = 22 : epar != output points. Open curve. gpar2 inside.
* = 24 : epar != output points. Open curve.
* Output points inside.
* = 26 : epar != output points. Closed curve. gpar2 == gpar1
* = 27 : epar != output points. Closed curve.
* gpar2 singular.
*
*
* METHOD :
*
*
* REFERENCES :
*
* WRITTEN BY : Tor Dokken, SI, Oslo, Norway. July 1989
*
*********************************************************************
*/
{
int kdeg=1; /* Indicate that a plane is used */
int kk1,kk2,kn1,kn2; /* Orders and numbers of vertices */
int kstat; /* Status variable */
int kkm1,kkm2; /* Orders minus 1 */
int kincre; /* Number of doubles in first vertex direction */
int kpos=0; /* Position of error */
int ki,kj,kl,kstop;
int kcur,kgraph; /* Indicators telling to control type of output
from marching */
int kmark1,kmark2,kclose,kmatch1,kmatch2; /* Flags */
double tmax; /* Box size */
double tstart,tlength;/* Variables used in Marsdens identity */
double tfak;
double tdum1; /* Max knot value used in DEQUAL comparing. */
double tdum2; /* Max knot value used in DEQUAL comparing. */
double tsum,*sp,*sq;
double simpli[4]; /* Description of plane */
double *st1,*st2,*scoef; /* Knots and vertices of input surface */
double *s3coef=SISL_NULL; /* 3-D coeff */
double tepsco = REL_COMP_RES;
double tepsge;
double sval1[2]; /* Limits of parameter plane in first SISLdir */
double sval2[2]; /* Limits of parameter plane in second SISLdir */
double *spar1,*spar2; /* Pointers to arrays */
double *spar=SISL_NULL; /* Pointer to allocated values for parameter values*/
SISLSurf *qs=SISL_NULL; /* 3-D version of surface */
SISLCurve *qcrv; /* Curve in parameter plane */
SISLIntcurve *qintcr=SISL_NULL;/* Intersection curve object */
kk1 = ps -> ik1;
kk2 = ps -> ik2;
kn1 = ps -> in1;
kn2 = ps -> in2;
st1 = ps -> et1;
st2 = ps -> et2;
scoef = ps -> ecoef;
sval1[0] = st1[kk1-1];
sval1[1] = st1[kn1];
sval2[0] = st2[kk2-1];
sval2[1] = st2[kn2];
/* Allocate array for 3-D representation of surface */
if((s3coef = newarray(kn1*kn2*3,DOUBLE)) == SISL_NULL) goto err101;
sh1992su(ps,0,aepsge,&kstat);
if (kstat < 0) goto error;
tmax = ps->pbox->e2max[0][0] - ps->pbox->e2min[0][0];
/* Make description of plane */
simpli[0] = (double)0.0;
simpli[1] = (double)0.0;
simpli[2] = (double)1.0;
simpli[3] = -alevel;
/* Make 3-D description of the surface */
/* Make representation of coefficients from Marsdens identity for the
* function f(t) = t, with the knot vector in first parameter direction
* scaled to [0,tmax]. This will be used as the x-coordinate in the 3-D
* representation */
tstart = st1[kk1-1];
tlength = st1[kn1] - tstart;
tfak = tmax/tlength;
kkm1 = kk1 - 1;
kincre = 3*kn1;
for (ki=0,kl=0,sp=s3coef ; ki ppar1;
if (qcrv == SISL_NULL) goto war00;
spar1 = qcrv -> ecoef;
spar2 = spar1 + 2*(qcrv->in)-2;
/* Check if any of the points lie on the boundary */
kmark1 = 0;
tdum1 = (double)2.0*max(fabs(sval1[0]),fabs(sval1[1]));
tdum2 = (double)2.0*max(fabs(sval2[0]),fabs(sval2[1]));
if (DEQUAL(spar1[0]+tdum1,sval1[0]+tdum1) || DEQUAL(spar1[0]+tdum1,sval1[1]+tdum1) ||
DEQUAL(spar1[1]+tdum2,sval2[0]+tdum2) || DEQUAL(spar1[1]+tdum2,sval2[1]+tdum2) )
kmark1 = 1;
kmark2 = 0;
if (DEQUAL(spar2[0]+tdum1,sval1[0]+tdum1) || DEQUAL(spar2[0]+tdum1,sval1[1]+tdum1) ||
DEQUAL(spar2[1]+tdum2,sval2[0]+tdum2) || DEQUAL(spar2[1]+tdum2,sval2[1]+tdum2) )
kmark2 = 1;
/* Check if closed */
kclose = 0;
if (spar1[0] == spar2[0] && spar1[1] == spar2[1]) kclose = 1;
/* Check if first points matches start point */
kmatch1 = 0;
if (DEQUAL(epar[0]+tdum1,spar1[0]+tdum1) && DEQUAL(epar[1]+tdum2,spar1[1]+tdum2) )
kmatch1 = 1;
/* Check if second points matches start point */
kmatch2 = 0;
if (DEQUAL(epar[0]+tdum1,spar2[0]+tdum1) && DEQUAL(epar[1]+tdum2,spar2[1]+tdum2) )
kmatch2 = 1;
/* Check if any point matches start point */
if (kmatch1 == 1 || kmatch2 == 1)
{
/* Start point matches one of the end points, status values in
the range 11-19*/
if (kmark1 == 1 && kmark2 == 1 && kclose == 0)
{
/* Open curve, status 11 */
*jstat = 11;
if(kmatch1==1)
goto copy;
else
goto invcopy;
}
else if (kmark1 ==1 || (kmark2 == 1 && kclose == 0))
{
/* Open curve one point inside status 12 or 13 */
if (kmark1 == 1 && kmatch1 == 1)
{
*jstat = 12;
goto copy;
}
else if (kmark2 == 1 && kmatch2 == 1)
{
*jstat = 12;
goto invcopy;
}
if (kmark1 == 1 && kmatch2 == 1)
{
*jstat = 13;
goto invcopy;
}
if (kmark2 == 1 && kmatch1 == 1)
{
*jstat = 13;
goto copy;
}
}
else if (kclose == 0)
{
/* Both ends inside */
*jstat = 14;
if(kmatch1==1)
goto copy;
else
goto invcopy;
}
else if(kmatch1 == 1)
{
/* Closed curve, no singularity */
*jstat = 16;
memcopy(gpar1,spar1,2,DOUBLE);
memcopy(gpar2,spar1,2,DOUBLE);
goto out;
}
else
{
/* Closed curve, with singularity */
*jstat=17;
memcopy(gpar1,epar ,2,DOUBLE);
memcopy(gpar2,spar1,2,DOUBLE);
goto out;
}
}
else
{
/* epar does not match produced end points, status messages in
21-29 the range */
if (kmark1 ==1 && kmark2 ==1 && kclose == 0)
{
/* Open curve, status 11 */
*jstat = 21;
memcopy(gpar1,spar1,2,DOUBLE);
memcopy(gpar2,spar2,2,DOUBLE);
goto out;
}
else if (kmark1 ==1 && kclose == 0)
{
/* Open curve one point inside status 12 */
*jstat=22;
goto copy;
}
else if (kmark2 ==1 && kclose == 0)
{
/* Open curve one point inside status 12 */
*jstat=22;
goto invcopy;
}
else if (kclose == 0)
{
/* Both ends inside */
*jstat=24;
goto copy;
}
else if(kmatch1 == 1)
{
/* Closed curve, no singularity */
*jstat=26;
memcopy(gpar1,spar1,2,DOUBLE);
memcopy(gpar2,spar1,2,DOUBLE);
}
else
{
/* Closed curve, with singularity */
*jstat = 27;
memcopy(gpar1,epar ,2,DOUBLE);
memcopy(gpar2,spar1,2,DOUBLE);
goto out;
}
}
/* Marching produced no curve */
war00: *jstat = 0;
memcopy(gpar1,epar,2,DOUBLE);
memcopy(gpar2,epar,2,DOUBLE);
goto out;
copy:
memcopy(gpar1,spar1,2,DOUBLE);
memcopy(gpar2,spar2,2,DOUBLE);
goto out;
invcopy:
memcopy(gpar1,spar2,2,DOUBLE);
memcopy(gpar2,spar1,2,DOUBLE);
goto out;
/* Error in space allocation */
err101:
*jstat = -101;
s6err("s1787",*jstat,kpos);
goto out;
/* Error in lower level function */
error:
*jstat = kstat;
s6err("s1787",*jstat,kpos);
goto out;
out:
if (s3coef != SISL_NULL) freearray(s3coef);
if (qs != SISL_NULL) freeSurf (qs);
if (qintcr != SISL_NULL) freeIntcurve(qintcr);
}