You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
798 lines
20 KiB
798 lines
20 KiB
1 year ago
|
// Structures for storing qsics, components, ...
|
||
|
|
||
|
#ifndef _qi_qsic_struct_h_
|
||
|
#define _qi_qsic_struct_h_
|
||
|
|
||
|
/** QI */
|
||
|
#include <libqi/kernel/QIHompoly.h>
|
||
|
#include <libqi/kernel/QIParamStruct.h>
|
||
|
#include <libqi/kernel/QIComponentTypes.h>
|
||
|
|
||
|
using namespace std;
|
||
|
using namespace rpl;
|
||
|
|
||
|
// Enter namespace QI
|
||
|
namespace QI {
|
||
|
|
||
|
// Three structures here: quad_inter, component and cut_param
|
||
|
|
||
|
template <class T> class quad_inter;
|
||
|
template <class T> class component;
|
||
|
template <class T> class cut_param;
|
||
|
|
||
|
// quad_inter
|
||
|
// The structure used to store an intersection between two quadrics: nothing
|
||
|
// more than a counter and a pointer on a structure of type component
|
||
|
|
||
|
// Possible real pencil type
|
||
|
// (1,1): empty set
|
||
|
// (1,2): smooth quartic, two finite components
|
||
|
// (1,3): smooth quartic, one finite component
|
||
|
// (1,4): smooth quartic, two infinite components
|
||
|
// (2,1): point
|
||
|
// (2,2): nodal quartic with isolated node
|
||
|
// (2,3): nodal quartic, affinely finite
|
||
|
// (2,4): nodal quartic, affinely infinite
|
||
|
// (3,1): empty set
|
||
|
// (3,2): two points
|
||
|
// (3,3): two non-secant conics
|
||
|
// (3,4): two secant conics, affinely finite
|
||
|
// (3,5): one conic
|
||
|
// (3,6): two secant conics, affinely infinite
|
||
|
// (4,1): cuspidal quartic
|
||
|
// (5,1): double point
|
||
|
// (5,2): two tangent conics
|
||
|
// (6,1): empty set
|
||
|
// (6,2): double conic
|
||
|
// (7,1): cubic and tangent line
|
||
|
// (8,1): conic
|
||
|
// (8,2): conic and two lines crossing
|
||
|
// (9,1): double line
|
||
|
// (9,2): two simple lines and a double line
|
||
|
// (10,1): point
|
||
|
// (10,2): two secant double lines
|
||
|
// (11,1): empty set
|
||
|
// (11,2): quadric of inertia (3,1)
|
||
|
// (11,3): quadric of inertia (2,2)
|
||
|
// (12,1): cubic and secant line
|
||
|
// (12,2): cubic and non-secant line
|
||
|
// (13,1): point
|
||
|
// (13,2): conic and point
|
||
|
// (13,3): conic and two lines not crossing
|
||
|
// (14,1): empty set
|
||
|
// (14,2): skew quadrilateral
|
||
|
// (14,3): two points
|
||
|
// (14,4): two lines
|
||
|
// (15,1): conic and double line
|
||
|
// (16,1): point
|
||
|
// (16,2): two concurrent lines
|
||
|
// (16,3): four concurrent lines
|
||
|
// (17,1): double line
|
||
|
// (17,2): two concurrent lines and a double line
|
||
|
// (18,1): line and triple line
|
||
|
// (19,1): point
|
||
|
// (19,2): two concurrent double lines
|
||
|
// (20,1): quadruple line
|
||
|
// (21,1): quadric of inertia (3,0)
|
||
|
// (21,2): quadric of inertia (2,1)
|
||
|
// (22,1): line and plane
|
||
|
// (23,1): quadruple line
|
||
|
// (23,2): quadruple line
|
||
|
// (24,1): plane
|
||
|
// (25,1): quadric of inertia (2,0)
|
||
|
// (25,2): quadric of inertia (1,1)
|
||
|
// (26,1): double plane
|
||
|
// (27,1): universe
|
||
|
|
||
|
template <class T>
|
||
|
class quad_inter
|
||
|
{
|
||
|
public:
|
||
|
unsigned int nb_cc;
|
||
|
|
||
|
component <T> *cc;
|
||
|
|
||
|
surface_param <T> s1, s2; // For smooth quartic case
|
||
|
|
||
|
unsigned int ctype, rtype; // Type of intersection: ctype (complex), rtype (real)
|
||
|
/** $$ JC Added: for backcompatibility*/
|
||
|
/** String versions of each type */
|
||
|
string sc;
|
||
|
string sr;
|
||
|
|
||
|
// Constructors
|
||
|
quad_inter()
|
||
|
{
|
||
|
this->create();
|
||
|
}
|
||
|
|
||
|
// Create a quad_inter with nb components
|
||
|
quad_inter(const unsigned int nb)
|
||
|
{
|
||
|
this->nb_cc = nb;
|
||
|
|
||
|
this->cc = new component <T>[nb];
|
||
|
}
|
||
|
|
||
|
// Copy constructor
|
||
|
quad_inter(const quad_inter <T> &a)
|
||
|
{
|
||
|
this->create();
|
||
|
|
||
|
this->assign(a);
|
||
|
}
|
||
|
|
||
|
// Destructor
|
||
|
~quad_inter()
|
||
|
{
|
||
|
this->destroy();
|
||
|
}
|
||
|
|
||
|
// Copy assignment
|
||
|
inline quad_inter <T> & operator = (const quad_inter <T> &a)
|
||
|
{
|
||
|
if (this != &a) // Beware of self-assignment
|
||
|
{
|
||
|
this->destroy();
|
||
|
|
||
|
this->create();
|
||
|
|
||
|
this->assign(a);
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
// Set type of intersection
|
||
|
inline void set_type(const unsigned int ct, const unsigned int rt)
|
||
|
{
|
||
|
this->ctype = ct;
|
||
|
this->rtype = rt;
|
||
|
}
|
||
|
|
||
|
// Create component cc[id] and conjugate cc[id+1]
|
||
|
inline void create_two_components(const unsigned int id,
|
||
|
const unsigned int tp, const curve_param <T> &c1,
|
||
|
const curve_param <T> &c2, const T &D)
|
||
|
{
|
||
|
this->cc[id].create_component(tp,c1,c2,D);
|
||
|
this->cc[id+1].create_component(tp,c1,-c2,D);
|
||
|
}
|
||
|
|
||
|
// Create component cc[id] and conjugate cc[id+1]
|
||
|
inline void create_two_components(const unsigned int id,
|
||
|
const unsigned int tp, const curve_param <T> &c1,
|
||
|
const curve_param <T> &c2, const curve_param <T> &c3,
|
||
|
const curve_param <T> &c4,
|
||
|
const T &D1, const T &D2, const T &D3)
|
||
|
{
|
||
|
this->cc[id].create_component(tp,c1,c2,c3,c4,D1,D2,D3);
|
||
|
this->cc[id+1].create_component(tp,c1,c2,-c3,-c4,D1,D2,D3);
|
||
|
}
|
||
|
|
||
|
// Create four components by changing signs
|
||
|
inline void create_four_components(const unsigned int tp, const curve_param <T> &c1,
|
||
|
const curve_param <T> &c2, const curve_param <T> &c3,
|
||
|
const T &D1, const T &D2)
|
||
|
{
|
||
|
this->cc[0].create_component(tp,c1,c2,c3,D1,D2);
|
||
|
this->cc[1].create_component(tp,c1,c2,-c3,D1,D2);
|
||
|
this->cc[2].create_component(tp,c1,-c2,c3,D1,D2);
|
||
|
this->cc[3].create_component(tp,c1,-c2,-c3,D1,D2);
|
||
|
}
|
||
|
|
||
|
// Create four components by changing signs
|
||
|
inline void create_four_components(const unsigned int tp, const curve_param <T> &c1,
|
||
|
const curve_param <T> &c2, const curve_param <T> &c3,
|
||
|
const curve_param <T> &c4, const T &D1,
|
||
|
const T &D2)
|
||
|
{
|
||
|
this->cc[0].create_component(tp,c1,c2,c3,c4,D1,D2,0);
|
||
|
this->cc[1].create_component(tp,c1,c2,-c3,-c4,D1,D2,0);
|
||
|
this->cc[2].create_component(tp,c1,-c2,c3,-c4,D1,D2,0);
|
||
|
this->cc[3].create_component(tp,c1,-c2,-c3,c4,D1,D2,0);
|
||
|
}
|
||
|
|
||
|
// Set the optiflag to the value of the parameter for all components of the intersection
|
||
|
inline void set_optiflag(const bool &flag)
|
||
|
{
|
||
|
for (unsigned int i = 0; i < nb_cc; i++)
|
||
|
this->cc[i].optiflag = flag;
|
||
|
}
|
||
|
|
||
|
// Assignment
|
||
|
inline void assign(const quad_inter <T> &a)
|
||
|
{
|
||
|
this->nb_cc = a.nb_cc;
|
||
|
|
||
|
this->ctype = a.ctype;
|
||
|
this->rtype = a.rtype;
|
||
|
|
||
|
this->s1 = a.s1;
|
||
|
this->s2 = a.s2;
|
||
|
|
||
|
if (this->nb_cc > 0)
|
||
|
{
|
||
|
this->cc = new component <T>[this->nb_cc];
|
||
|
|
||
|
for (unsigned int i = 0; i < this->nb_cc; i++)
|
||
|
this->cc[i] = a.cc[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
inline void create()
|
||
|
{
|
||
|
this->nb_cc = 0;
|
||
|
this->cc = NULL;
|
||
|
this->s1.assign(surface_param <T>(0));
|
||
|
this->s2.assign(surface_param <T>(0));
|
||
|
this->ctype = INTER_TYPE_UNDEFINED;
|
||
|
this->rtype = INTER_TYPE_UNDEFINED;
|
||
|
/** $$ JC Added */
|
||
|
this->sc = "Undefined";
|
||
|
this->sr = "Undefined";
|
||
|
}
|
||
|
|
||
|
inline void destroy()
|
||
|
{
|
||
|
if (this->cc != NULL)
|
||
|
delete[] this->cc;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Now to component class
|
||
|
|
||
|
// The structure used to store each component of the intersection curve
|
||
|
// In the worst case, the format of the component is:
|
||
|
//
|
||
|
// c[0] + sqrt(d[0])*c[1] + (c[3] + sqrt(d[0])*c[4])*sqrt(d[1] + sqrt(d[0])*d[2]),
|
||
|
//
|
||
|
// where the cp's are curve_params, d[0] is a bigint, and d[1], d[2] are hom_polys
|
||
|
//
|
||
|
// - type: type of real component (1: smooth quartic, 2: nodal quartic,
|
||
|
// 3: cuspidal quartic, 4: cubic, 5: conic, 6: line, 7: lines
|
||
|
// with constraint (four concurrent lines), 8: point, 9: smooth
|
||
|
// quadric, 10: cone, 11: pair of planes, 12: plane, 13: universe
|
||
|
// - nb_cp: number of cp's in the representation of the parameterization
|
||
|
// - cp's: the cp[] in the representation above
|
||
|
// - d's: the d[] in the representation above
|
||
|
// - m's: matrices when the output is a surface
|
||
|
// - h: used for bihomogeneous equation when smooth quartic
|
||
|
|
||
|
// For the fucking four concurrent lines with a constraint polynomial, I have
|
||
|
// decided not to create a surface_param but to enter the two endpoints: the first
|
||
|
// is a point and the second is a curve_param of degree 2
|
||
|
|
||
|
template <class T>
|
||
|
class component
|
||
|
{
|
||
|
public:
|
||
|
unsigned int type;
|
||
|
bool optiflag; // true if optimal, false if quasi-optimal
|
||
|
unsigned int mult; // multiplicity of intersection, default is 1
|
||
|
|
||
|
unsigned int nb_cp;
|
||
|
unsigned int nb_cut;
|
||
|
curve_param <T> *c;
|
||
|
hom_polynomial <T> *d;
|
||
|
math_matrix <T> m;
|
||
|
cut_param <T> *p;
|
||
|
|
||
|
// Constructor
|
||
|
component()
|
||
|
{
|
||
|
this->create();
|
||
|
}
|
||
|
|
||
|
// Copy constructor
|
||
|
component(const component <T> &a)
|
||
|
{
|
||
|
this->create();
|
||
|
|
||
|
this->assign(a);
|
||
|
}
|
||
|
|
||
|
// Destructor
|
||
|
~component()
|
||
|
{
|
||
|
this->destroy();
|
||
|
}
|
||
|
|
||
|
// Copy assignment
|
||
|
component <T> & operator = (const component <T> &a)
|
||
|
{
|
||
|
if (this != &a) // Beware of self-assignment
|
||
|
{
|
||
|
// Clean old stuff
|
||
|
this->destroy();
|
||
|
|
||
|
this->create();
|
||
|
|
||
|
this->assign(a);
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
// Assignment
|
||
|
inline void assign(const component <T> &a)
|
||
|
{
|
||
|
this->nb_cp = a.nb_cp;
|
||
|
this->nb_cut = a.nb_cut;
|
||
|
this->type = a.type;
|
||
|
this->optiflag = a.optiflag;
|
||
|
this->mult = a.mult;
|
||
|
|
||
|
if ((this->type >= INTER_TYPE_SMOOTH_QUARTIC_BRANCH_1) && (this->type <= INTER_TYPE_POINT))
|
||
|
// curve component
|
||
|
{
|
||
|
if (a.c != NULL)
|
||
|
{
|
||
|
this->c = new curve_param <T>[this->nb_cp];
|
||
|
|
||
|
for (unsigned int i = 0; i < this->nb_cp; i++)
|
||
|
this->c[i] = a.c[i];
|
||
|
|
||
|
if (this->nb_cp > 1)
|
||
|
{
|
||
|
this->d = new hom_polynomial <T>[this->nb_cp-1];
|
||
|
|
||
|
for (unsigned int i = 0; i < this->nb_cp-1; i++)
|
||
|
this->d[i] = a.d[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (this->nb_cut > 0)
|
||
|
{
|
||
|
this->p = new cut_param <T>[this->nb_cut];
|
||
|
|
||
|
for (unsigned int i = 0; i < this->nb_cut; i++)
|
||
|
this->p[i] = a.p[i];
|
||
|
}
|
||
|
}
|
||
|
else if ((this->type >= INTER_TYPE_SMOOTH_QUADRIC) && (this->type <= INTER_TYPE_PLANE)) // surface component
|
||
|
this->m = a.m;
|
||
|
}
|
||
|
|
||
|
// Add a cut parameter [uval0, vval0]
|
||
|
inline void create_cut_parameter(const int id0, const T &uval0, const T &vval0)
|
||
|
{
|
||
|
this->nb_cut = 1;
|
||
|
|
||
|
this->p = new cut_param <T>[1];
|
||
|
|
||
|
this->p[0].create_cut_parameter(id0,uval0,vval0);
|
||
|
}
|
||
|
|
||
|
// Add a cut parameter [val0[0], val0[1]]
|
||
|
inline void create_cut_parameter(const int id0, const math_vector <T> &val0)
|
||
|
{
|
||
|
this->create_cut_parameter(id0,val0[0],val0[1]);
|
||
|
}
|
||
|
|
||
|
// Add a cut parameter [val[0]+sqrt(D1)*val[1], val[2]]
|
||
|
inline void create_cut_parameter(const int id0,
|
||
|
const math_vector <T> &val, const T &D1)
|
||
|
{
|
||
|
this->nb_cut = 1;
|
||
|
|
||
|
this->p = new cut_param <T>[1];
|
||
|
|
||
|
if (val[1].is_zero())
|
||
|
this->p[0].create_cut_parameter(id0,val[0],val[2]);
|
||
|
else
|
||
|
this->p[0].create_cut_parameter(id0,val[0],val[1],val[2],D1);
|
||
|
}
|
||
|
|
||
|
// Add cut parameters [uval0, vval0] and [uval1, vval1]
|
||
|
inline void create_cut_parameters(const int id0, const T &uval0, const T &vval0,
|
||
|
const int id1, const T &uval1, const T &vval1)
|
||
|
{
|
||
|
this->nb_cut = 2;
|
||
|
|
||
|
this->p = new cut_param <T>[2];
|
||
|
|
||
|
this->p[0].create_cut_parameter(id0,uval0,vval0);
|
||
|
this->p[1].create_cut_parameter(id1,uval1,vval1);
|
||
|
}
|
||
|
|
||
|
// Add cut parameters [val0[0], val0[1]] and [val1[0], val1[1]]
|
||
|
inline void create_cut_parameters(const int id0, const math_vector <T> &val0,
|
||
|
const int id1, const math_vector <T> &val1)
|
||
|
{
|
||
|
this->create_cut_parameters(id0,val0[0],val0[1],id1,val1[0],val1[1]);
|
||
|
}
|
||
|
|
||
|
// Add cut parameters [val[0], val[1]] and [val[2], val[3]]
|
||
|
inline void create_cut_parameters(const int id0, const int id1,
|
||
|
const math_vector <T> &val)
|
||
|
{
|
||
|
this->create_cut_parameters(id0,val[0],val[1],id1,val[2],val[3]);
|
||
|
}
|
||
|
|
||
|
// Add cut parameters [uval0_0+sqrt(D1)*uval1_0, vval_0] and
|
||
|
// [uval0_1+sqrt(D1)*uval1_1, vval_1]
|
||
|
inline void create_cut_parameters(const int id0,
|
||
|
const T &uval0_0, const T &uval1_0, const T &vval_0,
|
||
|
const int id1,
|
||
|
const T &uval0_1, const T &uval1_1, const T &vval_1,
|
||
|
const T &D1)
|
||
|
{
|
||
|
this->nb_cut = 2;
|
||
|
|
||
|
this->p = new cut_param <T>[2];
|
||
|
|
||
|
if (uval1_0.is_zero())
|
||
|
this->p[0].create_cut_parameter(id0,uval0_0,vval_0);
|
||
|
else
|
||
|
this->p[0].create_cut_parameter(id0,uval0_0,uval1_0,vval_0,D1);
|
||
|
|
||
|
if (uval1_1.is_zero())
|
||
|
this->p[1].create_cut_parameter(id1,uval0_1,vval_1);
|
||
|
else
|
||
|
this->p[1].create_cut_parameter(id1,uval0_1,uval1_1,vval_1,D1);
|
||
|
}
|
||
|
|
||
|
// Add cut parameters [val[0]+sqrt(D1)*val[1], val[2]] and
|
||
|
// [val[3]+sqrt(D1)*val[4], val[5]]
|
||
|
inline void create_cut_parameters(const int id0, const int id1,
|
||
|
const math_vector <T> &val, const T &D1)
|
||
|
{
|
||
|
this->create_cut_parameters(id0,val[0],val[1],val[2],id1,val[3],val[4],val[5],D1);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
inline void create_cut_parameters(const int id0,
|
||
|
const T &uval0_0, const T &uval1_0, const T &uval2_0,
|
||
|
const T &uval3_0, const T &vval_0,
|
||
|
const int id1,
|
||
|
const T &uval0_1, const T &uval1_1, const T &uval2_1,
|
||
|
const T &uval3_1, const T &vval_1,
|
||
|
const T &D1, const T &D2)
|
||
|
{
|
||
|
this->nb_cut = 2;
|
||
|
|
||
|
this->p = new cut_param <T>[2];
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// Particular cases to handle
|
||
|
|
||
|
this->p[0].create_cut_parameter(id0,uval0_0,uval1_0,uval2_0,uval3_0,vval_0,D1,D2);
|
||
|
this->p[1].create_cut_parameter(id1,uval0_1,uval1_1,uval2_1,uval3_1,vval_1,D1,D2);
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
// Universe...
|
||
|
inline void create_universe()
|
||
|
{
|
||
|
this->type = INTER_TYPE_UNIVERSE;
|
||
|
this->nb_cp = 1;
|
||
|
}
|
||
|
|
||
|
// Component made of a surface
|
||
|
inline void create_component(const unsigned int tp, const math_matrix <T> &m1)
|
||
|
{
|
||
|
this->type = tp;
|
||
|
this->nb_cp = 1;
|
||
|
|
||
|
this->m = m1;
|
||
|
}
|
||
|
|
||
|
// Component of the form c1
|
||
|
inline void create_component(const unsigned int tp, const curve_param <T> &c1)
|
||
|
{
|
||
|
this->type = tp;
|
||
|
this->nb_cp = 1;
|
||
|
|
||
|
this->c = new curve_param <T>[1];
|
||
|
|
||
|
this->c[0] = c1;
|
||
|
}
|
||
|
|
||
|
// Component of the form c1 + sqrt(D)*c2
|
||
|
inline void create_component(const unsigned int tp, const curve_param <T> &c1,
|
||
|
const curve_param <T> &c2, const T &D)
|
||
|
{
|
||
|
this->type = tp;
|
||
|
this->nb_cp = 2;
|
||
|
|
||
|
this->c = new curve_param <T>[2];
|
||
|
|
||
|
this->c[0] = c1;
|
||
|
this->c[1] = c2;
|
||
|
|
||
|
this->d = new hom_polynomial <T>[1];
|
||
|
|
||
|
this->d[0] = D;
|
||
|
}
|
||
|
|
||
|
// Component of the form c1 + sqrt(D)*c2, D is polynomial
|
||
|
// or lines with constraints: u*c1+v*c2(s,t) subject to D(s,t) = 0
|
||
|
inline void create_component(const unsigned int tp, const curve_param <T> &c1,
|
||
|
const curve_param <T> &c2, const hom_polynomial <T> &D)
|
||
|
{
|
||
|
this->type = tp;
|
||
|
this->nb_cp = 2;
|
||
|
|
||
|
this->c = new curve_param <T>[2];
|
||
|
|
||
|
this->c[0] = c1;
|
||
|
this->c[1] = c2;
|
||
|
|
||
|
this->d = new hom_polynomial <T>[1];
|
||
|
|
||
|
this->d[0] = D;
|
||
|
}
|
||
|
|
||
|
// Component of the form c1 + sqrt(D1)*c2 + sqrt(D2)*c3
|
||
|
inline void create_component(const unsigned int tp, const curve_param <T> &c1,
|
||
|
const curve_param <T> &c2, const curve_param <T> &c3,
|
||
|
const T &D1, const T &D2)
|
||
|
{
|
||
|
this->type = tp;
|
||
|
this->nb_cp = 3;
|
||
|
|
||
|
this->c = new curve_param <T>[3];
|
||
|
|
||
|
this->c[0] = c1;
|
||
|
this->c[1] = c2;
|
||
|
this->c[2] = c3;
|
||
|
|
||
|
this->d = new hom_polynomial <T>[2];
|
||
|
|
||
|
this->d[0] = D1;
|
||
|
this->d[1] = D2;
|
||
|
}
|
||
|
|
||
|
// Component of the form c1 + sqrt(D1)*c2 + (c3 + sqrt(D1)*c4)*sqrt(D2 +
|
||
|
// D3*sqrt(D1)), D2 and D3 are polynomials
|
||
|
inline void create_component(const unsigned int tp, const curve_param <T> &c1,
|
||
|
const curve_param <T> &c2, const curve_param <T> &c3,
|
||
|
const curve_param <T> &c4, const T &D1,
|
||
|
const hom_polynomial <T> &D2, const hom_polynomial <T> &D3)
|
||
|
{
|
||
|
this->type = tp;
|
||
|
this->nb_cp = 4;
|
||
|
|
||
|
this->c = new curve_param <T>[4];
|
||
|
|
||
|
this->c[0] = c1;
|
||
|
this->c[1] = c2;
|
||
|
this->c[2] = c3;
|
||
|
this->c[3] = c4;
|
||
|
|
||
|
this->d = new hom_polynomial <T>[3];
|
||
|
|
||
|
this->d[0] = D1;
|
||
|
this->d[1] = D2;
|
||
|
this->d[2] = D3;
|
||
|
}
|
||
|
|
||
|
// Component of the form c1 + sqrt(D1)*c2 + (c3 + sqrt(D1)*c4)*sqrt(D2 + D3*sqrt(D1))
|
||
|
inline void create_component(const unsigned int tp, const curve_param <T> &c1,
|
||
|
const curve_param <T> &c2, const curve_param <T> &c3,
|
||
|
const curve_param <T> &c4,
|
||
|
const T &D1, const T &D2, const T &D3)
|
||
|
{
|
||
|
this->create_component(tp,c1,c2,c3,c4,D1,hom_polynomial <T>(D2),
|
||
|
hom_polynomial <T>(D3));
|
||
|
}
|
||
|
|
||
|
/** $$ JC: checks whether the component is in R^3 */
|
||
|
bool isInRealAffineSpace (void) {
|
||
|
|
||
|
unsigned short k;
|
||
|
|
||
|
for (k = 0; k < nb_cp; k++) {
|
||
|
/** $$ JC : c[k][3] is not a pointer so cannot be NULL... */
|
||
|
/*if ( c == NULL || c[k][3] == NULL) continue;*/
|
||
|
if (c == NULL) continue;
|
||
|
if (! c[k][3].is_zero() ) return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
inline void destroy()
|
||
|
{
|
||
|
if (this->c != NULL)
|
||
|
delete[] this->c;
|
||
|
|
||
|
if (this->d != NULL)
|
||
|
delete[] this->d;
|
||
|
|
||
|
if (this->p != NULL)
|
||
|
delete[] this->p;
|
||
|
}
|
||
|
|
||
|
inline void create()
|
||
|
{
|
||
|
this->optiflag = false;
|
||
|
this->type = 0;
|
||
|
this->mult = 1;
|
||
|
|
||
|
this->nb_cp = 0;
|
||
|
this->nb_cut = 0;
|
||
|
this->c = NULL;
|
||
|
this->d = NULL;
|
||
|
this->m = math_matrix<T>(0,0);
|
||
|
this->p = NULL;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
// Cut params can be (u0, v0), (u0+sqrt(D1)*u1, v0), (u0+sqrt(D1)*u1+sqrt(D2)*u2, v0) ...
|
||
|
// l is the number of ui's
|
||
|
// id is the index of a component on which the cut param falls
|
||
|
|
||
|
template <class T>
|
||
|
class cut_param
|
||
|
{
|
||
|
public:
|
||
|
unsigned int l;
|
||
|
int id; // -1 means I don't know
|
||
|
|
||
|
T *u;
|
||
|
T v;
|
||
|
T *D;
|
||
|
|
||
|
// Constructor
|
||
|
cut_param()
|
||
|
{
|
||
|
this->create();
|
||
|
}
|
||
|
|
||
|
// Copy constructor
|
||
|
cut_param(const cut_param <T> &a)
|
||
|
{
|
||
|
this->create();
|
||
|
|
||
|
this->assign(a);
|
||
|
}
|
||
|
|
||
|
// Destructor
|
||
|
~cut_param()
|
||
|
{
|
||
|
this->destroy();
|
||
|
}
|
||
|
|
||
|
// Copy assignment
|
||
|
cut_param <T> & operator = (const cut_param <T> &a)
|
||
|
{
|
||
|
if (this != &a) // Beware of self-assignment
|
||
|
{
|
||
|
// Clean old stuff
|
||
|
this->destroy();
|
||
|
|
||
|
this->create();
|
||
|
|
||
|
this->assign(a);
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
inline void assign(const cut_param <T> &a)
|
||
|
{
|
||
|
this->l = a.l;
|
||
|
this->id = a.id;
|
||
|
this->v = a.v;
|
||
|
|
||
|
if (this->l > 0)
|
||
|
{
|
||
|
this->u = new T[this->l];
|
||
|
|
||
|
for (unsigned int i = 0; i < this->l; i++)
|
||
|
this->u[i] = a.u[i];
|
||
|
}
|
||
|
|
||
|
if (this->l > 1)
|
||
|
{
|
||
|
unsigned int nbD;
|
||
|
|
||
|
if (this->l == 2)
|
||
|
nbD = 1;
|
||
|
else // l == 4
|
||
|
nbD = 2;
|
||
|
|
||
|
this->D = new T[nbD];
|
||
|
|
||
|
for (unsigned int i = 0; i < nbD; i++)
|
||
|
this->D[i].assign(a.D[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// A cut parameter (u0, v0), id0 is the index of the other component that is cut
|
||
|
inline void create_cut_parameter(const int id0, const T &u0, const T &v0)
|
||
|
{
|
||
|
this->l = 1;
|
||
|
|
||
|
this->id = id0;
|
||
|
|
||
|
this->u = new T[1];
|
||
|
this->u[0] = u0;
|
||
|
|
||
|
this->v = v0;
|
||
|
}
|
||
|
|
||
|
// A cut parameter (u0+sqrt(D1)*u1, v0)
|
||
|
inline void create_cut_parameter(const int id0,
|
||
|
const T &u0, const T &u1, const T &v0, const T &D1)
|
||
|
{
|
||
|
this->l = 2;
|
||
|
|
||
|
this->id = id0;
|
||
|
|
||
|
this->u = new T[2];
|
||
|
|
||
|
this->D = new T[1];
|
||
|
|
||
|
this->u[0] = u0;
|
||
|
this->u[1] = u1;
|
||
|
|
||
|
this->D[0] = D1;
|
||
|
|
||
|
this->v = v0;
|
||
|
}
|
||
|
|
||
|
// A cut parameter (u0+sqrt(D1)*u1+sqrt(D2)*u2+sqrt(D1*D2)*u3, v0)
|
||
|
inline void create_cut_parameter(const int id0,
|
||
|
const T &u0, const T &u1, const T &u2, const T &u3,
|
||
|
const T &v0, const T &D1, const T &D2)
|
||
|
{
|
||
|
this->l = 4;
|
||
|
|
||
|
this->id = id0;
|
||
|
|
||
|
this->u = new T[4];
|
||
|
|
||
|
this->D = new T[2];
|
||
|
|
||
|
this->u[0] = u0;
|
||
|
this->u[1] = u1;
|
||
|
this->u[2] = u2;
|
||
|
this->u[3] = u3;
|
||
|
|
||
|
this->D[0] = D1;
|
||
|
this->D[1] = D2;
|
||
|
|
||
|
this->v = v0;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
inline void create()
|
||
|
{
|
||
|
this->l = 0;
|
||
|
this->id = 0;
|
||
|
|
||
|
this->u = 0;
|
||
|
this->v = 0;
|
||
|
this->D = 0;
|
||
|
}
|
||
|
|
||
|
inline void destroy()
|
||
|
{
|
||
|
if (this->u != NULL)
|
||
|
delete[] this->u;
|
||
|
|
||
|
if (this->D != NULL)
|
||
|
delete[] this->D;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // end of namespace QI
|
||
|
|
||
|
#endif
|