36vect_intersect(vector<double>
const &a, vector<double>
const &b,
double tol=0.){
39 while ( i<a.size() && j<b.size() ){
40 if (fabs(a[i]-b[j])<tol){
41 inter.push_back(a[i]);
55 if ( k>=(
int)a.
size()){
59 if(k < 0)
return shift(a,-k);
68 for (
int i=2; i<=-k; i++){
75 for (
int i=2; i<=k; i++){
86 for (
int i=2; i<=-k; i++){
93 for (
int i=2; i<=k; i++){
104 while ((M[0].
size()>1||M[1].
size()>1) &&
105 fabs(M[0].at0())<ZERO &&
106 fabs(M[1].at0())<ZERO &&
107 fabs(M[0].at1())<ZERO &&
108 fabs(M[1].at1())<ZERO){
112 while ((M[0].
size()>1||M[1].
size()>1) &&
113 fabs(M[0].at0())<ZERO && fabs(M[1].at0())<ZERO){
117 while ((M[0].
size()>1||M[1].
size()>1) &&
118 fabs(M[0].at1())<ZERO && fabs(M[1].at1())<ZERO){
138 for (
unsigned i=0; i<M.size(); i++){
139 vector<double> seg_rts =
roots((M.segs[i])[0]);
142 for (
double & seg_rt : seg_rts){
143 seg_rt= mapToDom(seg_rt);
145 rts.insert(rts.end(),seg_rts.begin(),seg_rts.end());
147 return partition(M,rts);
160 result.cuts.push_back(v.cuts.front());
161 for (
unsigned i=0; i<v.size(); i++){
171 angle += -std::atan2(vi0[1],vi0[0]) - angle[0].at0();
176 angle.setDomain(
Interval(v.cuts[i],v.cuts[i+1]));
231 if (V[0].isZero(tol) && V[1].isZero(tol))
233 SBasis x = V[0], y = V[1];
239 a[0] =
Linear(-v0[1],-v1[1]);
241 b[0] =
Linear( v0[0], v1[0]);
244 r_eqn2 =
Linear(1.)-(a*a+b*b);
246 for (
unsigned k=1; k<=
order; k++){
247 double r0 = (k<r_eqn1.
size())? r_eqn1.
at(k).
at0() : 0;
248 double r1 = (k<r_eqn1.
size())? r_eqn1.
at(k).
at1() : 0;
249 double rr0 = (k<r_eqn2.
size())? r_eqn2.
at(k).
at0() : 0;
250 double rr1 = (k<r_eqn2.
size())? r_eqn2.
at(k).
at1() : 0;
257 a0 = r0/
dot(v0,V.
at0())*v0[0]-rr0/2*v0[1];
258 b0 = r0/
dot(v0,V.
at0())*v0[1]+rr0/2*v0[0];
259 a1 = r1/
dot(v1,V.
at1())*v1[0]-rr1/2*v1[1];
260 b1 = r1/
dot(v1,V.
at1())*v1[1]+rr1/2*v1[0];
267 r_eqn2 =
Linear(1)-(a*a+b*b);
276 double rel_tol = std::max(1.,std::max(V_in[0].tailError(0),V_in[1].tailError(0)))*tol;
309 for (
unsigned i=0; i<VV.
size(); i++){
347 return length.segs.back().at1();
353 return length.segs.back().at1();
369 k =
divide(k,dMlength,tol,3);
384 for (
unsigned i=0; i<VV.
size(); i++){
409 for (
unsigned i=0; i < s.
size();i++){
416 for (
unsigned dim=0;dim<2;dim++){
438 for (
unsigned i=0; i<M.size(); i++) {
444#include <gsl/gsl_integration.h>
447 return sqrt((*pc)(t));
463 gsl_integration_workspace *
w
464 = gsl_integration_workspace_alloc (20);
466 F.params = (
void*)&dB2;
467 double quad_result, err;
470 gsl_integration_qag (&F, 0, 1, 0, tol, 20,
471 GSL_INTEG_GAUSS21,
w, &quad_result, &err);
487 double abs_error = 0;
501 double abs_error = 0;
502 for (
unsigned i=0; i < s.size();i++){
522 Point centroid_tmp(0,0);
524 for(
unsigned i = 0; i < p.size(); i++) {
528 atmp += A.
at1() - A.
at0();
529 centroid_tmp += C.
at1()- C.
at0();
533 Point final = p[p.size()-1].at1(), initial = p[0].at0();
534 const double ai =
cross(
final, initial);
536 centroid_tmp += (
final + initial)*ai;
540 centroid = centroid_tmp / (3 * atmp);
562 int insist_on_speeds_signs){
564 double a0=aa0,a1=aa1,c0=cc0,c1=cc1;
567 if (a1<0){a1=-a1; c1=-c1;}
568 if (a0<0){a0=-a0; c0=-c0;}
569 double a = (a0<a1 ? a0 : a1);
570 double c = (c0<c1 ? c0 : c1);
574 double lambda_max = (1+std::sqrt(
delta))/2/a;
579 if (insist_on_speeds_signs == 1){
591 int insist_on_speeds_signs){
594 p[0] =
Linear( a1*c0*c0+c1, a1*a0*(a0+ 2*c0) +a1*c0*c0 +c1 -1 );
595 p[1] =
Linear( -a1*a0*(a0+2*c0), -a1*a0*(3*a0+2*c0) );
596 p[2] =
Linear( a1*a0*a0 );
600 return std::vector<double>();
602 std::vector<double>rts =
roots(p);
603 for (
double & rt : rts){
604 rt = domain->min() + rt * domain->extent();
629std::vector<D2<SBasis> >
632 double d2M0xdM0,
double d2M1xdM1,
633 int insist_on_speed_signs,
635 std::vector<D2<SBasis> >
result;
640 std::vector<double> lambda0,lambda1;
641 double dM1xdM0=
cross(dM1,dM0);
642 if (fabs(dM1xdM0)<epsilon){
643 if (fabs(d2M0xdM0)<epsilon || fabs(d2M1xdM1)<epsilon){
646 double lbda02 = 6.*
cross(M1-M0,dM0)/d2M0xdM0;
647 double lbda12 =-6.*
cross(M1-M0,dM1)/d2M1xdM1;
648 if (lbda02<0 || lbda12<0){
651 lambda0.push_back(std::sqrt(lbda02) );
652 lambda1.push_back(std::sqrt(lbda12) );
657 a0 = -d2M0xdM0/2/dM1xdM0;
658 c0 = 3*
cross(M1-M0,dM0)/dM1xdM0;
659 a1 = -d2M1xdM1/2/dM1xdM0;
660 c1 = -3*
cross(M1-M0,dM1)/dM1xdM0;
662 if (fabs(a0)<epsilon){
663 lambda1.push_back( c0 );
664 lambda0.push_back( a1*c0*c0 + c1 );
665 }
else if (fabs(a1)<epsilon){
666 lambda0.push_back( c1 );
667 lambda1.push_back( a0*c1*c1 + c0 );
670 vector<double> solns=
solve_lambda0(a0,a1,c0,c1,insist_on_speed_signs);
671 for (
double lbda0 : solns){
672 double lbda1=c0+a0*lbda0*lbda0;
674 if (lbda0>=0. && lbda1>=0.){
675 lambda0.push_back( lbda0);
676 lambda1.push_back( lbda1);
679 else if (lbda0<=0. && lbda1<=0. && insist_on_speed_signs<=0){
680 lambda0.push_back( lbda0);
681 lambda1.push_back( lbda1);
684 else if (insist_on_speed_signs<0){
685 lambda0.push_back( lbda0);
686 lambda1.push_back( lbda1);
692 for (
unsigned i=0; i<lambda0.size(); i++){
693 Point V0 = lambda0[i]*dM0;
694 Point V1 = lambda1[i]*dM1;
696 for(
unsigned dim=0;dim<2;dim++){
698 c[0] =
Linear(M0[dim],M1[dim]);
699 c[1] =
Linear( M0[dim]-M1[dim]+V0[dim],
700 -M0[dim]+M1[dim]-V1[dim]);
705 double dM0_l = dM0.length();
706 double dM1_l = dM1.length();
707 g_warning(
"Target radii: %f, %f", dM0_l*dM0_l*dM0_l/d2M0xdM0,dM1_l*dM1_l*dM1_l/d2M1xdM1);
708 g_warning(
"Obtained radii: %f, %f",1/k.
valueAt(0),1/k.
valueAt(1));
715std::vector<D2<SBasis> >
719 int insist_on_speed_signs,
721 double d2M0xdM0 =
cross(d2M0,dM0);
722 double d2M1xdM1 =
cross(d2M1,dM1);
726std::vector<D2<SBasis> >
729 double k0,
double k1,
730 int insist_on_speed_signs,
Adaptor that creates 2D functions from 1D ones.
std::vector< double > find_tangents_by_vector(Point V, D2< SBasis > const &A)
returns all the parameter values of A whose tangent is parallel to vector V.
std::vector< double > find_normals(Point P, D2< SBasis > const &A)
returns all the parameter values of A whose normal passes through P.
std::vector< double > find_normals_by_vector(Point V, D2< SBasis > const &A)
returns all the parameter values of A whose normal is parallel to vector V.
std::vector< double > find_tangents(Point P, D2< SBasis > const &A)
returns all the parameter values of A whose tangent passes through P.
Range of real numbers that is never empty.
Function that interpolates linearly between two values.
Range of real numbers that can be empty.
Function defined as discrete pieces.
output_type valueAt(double t) const
void push(const T &s, double to)
Convenience/implementation hiding function to add segment/cut pairs.
std::vector< double > cuts
void concat(const Piecewise< T > &other)
void setDomain(Interval dom)
Two-dimensional point that doubles as a vector.
Coord length() const
Compute the distance from origin.
Polynomial in symmetric power basis.
const_iterator end() const
void insert(iterator before, const_iterator src_begin, const_iterator src_end)
const_iterator begin() const
double tailError(unsigned tail) const
bound the error from term truncation
Various utility functions.
SBasisN< n > cos(LinearN< n > bo, int k)
Coord length(LineSegment const &seg)
SBasisN< n > divide(SBasisN< n > const &a, SBasisN< n > const &b, int k)
SBasisN< n > compose_inverse(SBasisN< n > const &f, SBasisN< n > const &g, unsigned order=2, double tol=1e-3)
Piecewise< SBasis > curvature(D2< SBasis > const &M, double tol=.01)
Bezier multiply(Bezier const &f, Bezier const &g)
double atan2(Point const &p)
int centroid(std::vector< Geom::Point > const &p, Geom::Point ¢roid, double &area)
polyCentroid: Calculates the centroid (xCentroid, yCentroid) and area of a polygon,...
std::vector< D2< SBasis > > cubics_with_prescribed_curvature(Point const &M0, Point const &M1, Point const &dM0, Point const &dM1, double k0, double k1, int insist_on_speed_signs=1, double error=1e-5)
SBasisN< n > sqrt(SBasisN< n > const &a, int k)
SBasisOf< T > shift(SBasisOf< T > const &a, int sh)
static double area(Geom::Point a, Geom::Point b, Geom::Point c)
D2< T > compose(D2< T > const &a, T const &b)
D2< Piecewise< SBasis > > tan2(SBasis const &angle, double tol=.01, unsigned order=3)
std::vector< double > roots(SBasis const &s)
Bezier integral(Bezier const &a)
Bezier derivative(Bezier const &a)
Piecewise< SBasis > cross(Piecewise< D2< SBasis > > const &a, Piecewise< D2< SBasis > > const &b)
Piecewise< D2< SBasis > > arc_length_parametrization(D2< SBasis > const &M, unsigned order=3, double tol=.01)
std::vector< D2< SBasis > > cubics_fitting_curvature(Point const &M0, Point const &M1, Point const &dM0, Point const &dM1, double d2M0xdM0, double d2M1xdM1, int insist_on_speed_signs=1, double epsilon=1e-5)
T dot(D2< T > const &a, D2< T > const &b)
Point unit_vector(Point const &a)
Piecewise< D2< SBasis > > cutAtRoots(Piecewise< D2< SBasis > > const &M, double tol=1e-4)
void length_integrating(D2< SBasis > const &B, double &result, double &abs_error, double tol)
Piecewise< SBasis > arcLengthSb(D2< SBasis > const &M, double tol=.01)
SBasisN< n > sin(LinearN< n > bo, int k)
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
D2< T > rot90(D2< T > const &a)
Piecewise< D2< SBasis > > unitVector(D2< SBasis > const &vect, double tol=.01, unsigned order=3)
static SBasis divide_by_t1k(SBasis const &a, int k)
static std::vector< double > solve_lambda0(double a0, double a1, double c0, double c1, int insist_on_speeds_signs)
static OptInterval find_bounds_for_lambda0(double aa0, double aa1, double cc0, double cc1, int insist_on_speeds_signs)
Find cubics with prescribed curvatures at both ends.
static SBasis divide_by_t0k(SBasis const &a, int k)
static double sb_length_integrating(double t, void *param)
static SBasis divide_by_sk(SBasis const &a, int k)
static D2< SBasis > RescaleForNonVanishingEnds(D2< SBasis > const &MM, double ZERO=1.e-4)
static vector< double > vect_intersect(vector< double > const &a, vector< double > const &b, double tol=0.)
Return a list of doubles that appear in both a and b to within error tol a, b, vector of double tol t...
two-dimensional geometric operators.
some std functions to work with (pw)s-basis
Polynomial in symmetric power basis (S-basis)