// draw a cubic spline from current pos to 'to' using control1,2 // Cubic Bézier curves ( a compound curve ) // B(t)=A(1-t)^3 + 3Bt(1-t)^2 + 3Ct^2(1-t) + Dt^3 , t in [0,1]. int Ttt::my_cubic_as_lines(const FT_Vector* control1, const FT_Vector* control2, const FT_Vector *to, void* user) { double len; extents ext; boost::tie(len,ext) = cubic_length(control1,control2,to); glyph_extents.add_extents(ext); double dsteps=my_writer->get_cubic_line_subdiv(); int steps = (int) std::max( (double)2, len/dsteps); // at least two steps for(int t=1; t<=steps; t++) { double tf = (double)t/(double)steps; double x = CUBE(1-tf)*last_point.x + SQ(1-tf)*3*tf*control1->x + SQ(tf)*(1-tf)*3*control2->x + CUBE(tf)*to->x; double y = CUBE(1-tf)*last_point.y + SQ(1-tf)*3*tf*control1->y + SQ(tf)*(1-tf)*3*control2->y + CUBE(tf)*to->y; P p(x,y); line(p); } last_point = *to; return 0; }
// calculate the arc-length and extents of a cubic // FIXME: is the hard-coded csteps=10 sufficient? optimal? std::pair<double, extents> Ttt::cubic_length(const FT_Vector* control1, const FT_Vector* control2, const FT_Vector* to) { FT_Vector point=last_point; double len=0; extents ext; // define the number of linear segments we use to approximate beziers // in the gcode and the number of polyline control points for dxf code. int csteps=10; // fixme: get this value from the Writer for(int t=1; t<=csteps; t++) { double tf = (double)t/(double)csteps; // t in [0, 1] double x = CUBE(1-tf)*last_point.x + SQ(1-tf)*3*tf*control1->x + SQ(tf)*(1-tf)*3*control2->x + CUBE(tf)*to->x; double y = CUBE(1-tf)*last_point.y + SQ(1-tf)*3*tf*control1->y + SQ(tf)*(1-tf)*3*control2->y + CUBE(tf)*to->y; len += hypot(x-point.x, y-point.y); // calculate total length of cubic point.x = x; point.y = y; ext.add_point(point); // GLOBAL!! this only adds to the glyph_extents? } return std::make_pair(len,ext); }
compFaceIntegrals(FACE *f) { double *n, w; double k1, k2, k3, k4; compProjectionIntegrals(f); w = f->w; n = f->norm; k1 = 1 / n[C]; k2 = k1 * k1; k3 = k2 * k1; k4 = k3 * k1; Fa = k1 * Pa; Fb = k1 * Pb; Fc = -k2 * (n[A]*Pa + n[B]*Pb + w*P1); Faa = k1 * Paa; Fbb = k1 * Pbb; Fcc = k3 * (SQR(n[A])*Paa + 2*n[A]*n[B]*Pab + SQR(n[B])*Pbb + w*(2*(n[A]*Pa + n[B]*Pb) + w*P1)); Faaa = k1 * Paaa; Fbbb = k1 * Pbbb; Fccc = -k4 * (CUBE(n[A])*Paaa + 3*SQR(n[A])*n[B]*Paab + 3*n[A]*SQR(n[B])*Pabb + CUBE(n[B])*Pbbb + 3*w*(SQR(n[A])*Paa + 2*n[A]*n[B]*Pab + SQR(n[B])*Pbb) + w*w*(3*(n[A]*Pa + n[B]*Pb) + w*P1)); Faab = k1 * Paab; Fbbc = -k2 * (n[A]*Pabb + n[B]*Pbbb + w*Pbb); Fcca = k3 * (SQR(n[A])*Paaa + 2*n[A]*n[B]*Paab + SQR(n[B])*Pabb + w*(2*(n[A]*Paa + n[B]*Pab) + w*Pa)); }
void Hydrogen_ff(double lambda, double *chi) { /* --- Hydrogen free-free opacity See: Mihalas (1978) p. 101 -- -------------- */ register int k; long Nspace = atmos.Nspace; double hc_kla, C0, sigma, g_ff, stim, nu3, *np; C0 = SQ(Q_ELECTRON)/(4.0*PI*EPSILON_0) / sqrt(M_ELECTRON); sigma = 4.0/3.0 * sqrt(2.0*PI/(3.0 * KBOLTZMANN)) * CUBE(C0) / (HPLANCK * CLIGHT); nu3 = CUBE((lambda * NM_TO_M) / CLIGHT); hc_kla = (HPLANCK * CLIGHT) / (KBOLTZMANN * NM_TO_M * lambda); np = atmos.H->n[atmos.H->Nlevel-1]; for (k = 0; k < Nspace; k++) { stim = 1.0 - exp(-hc_kla/atmos.T[k]); g_ff = Gaunt_ff(lambda, 1, atmos.T[k]); chi[k] = sigma / sqrt(atmos.T[k]) * nu3 * atmos.ne[k] * np[k] * stim * g_ff; } }
inline double resolv_hole_d(t_rt *s) { return ((4 * ((CUBE(s->ray.new_eye.x) * s->ray.vct->x) + (CUBE(s->ray.new_eye.y) * s->ray.vct->y) + (CUBE(s->ray.new_eye.z) * s->ray.vct->z))) - (10 * ((s->ray.vct->x * s->ray.new_eye.x) + (s->ray.vct->y * s->ray.new_eye.y) + (s->ray.vct->z * s->ray.new_eye.z)))); }
bool_t Hydrogen_bf(double lambda, double *chi, double *eta) { /* --- Hydrogen bound-free opacity See: Mihalas (1978) p. 99 -- -------------- */ register int k, kr; bool_t opaque; int i; double lambdaEdge, sigma, sigma0, g_bf, twohnu3_c2, twohc, gijk, hc_k, hc_kla, *npstar, expla, n_eff, *np; AtomicContinuum *continuum; opaque = FALSE; for (k = 0; k < atmos.Nspace; k++) { chi[k] = 0.0; eta[k] = 0.0; } if (atmos.H->active) return opaque; twohc = (2.0 * HPLANCK * CLIGHT) / CUBE(NM_TO_M); hc_k = (HPLANCK * CLIGHT) / (KBOLTZMANN * NM_TO_M); sigma0 = 32.0/(3.0*sqrt(3.0)) * SQ(Q_ELECTRON)/(4.0*PI*EPSILON_0) / (M_ELECTRON * CLIGHT) * HPLANCK/(2.0*E_RYDBERG); npstar = atmos.H->nstar[atmos.H->Nlevel - 1]; for (kr = 0; kr < atmos.H->Ncont; kr++) { continuum = atmos.H->continuum + kr; lambdaEdge = continuum->lambda0; i = continuum->i; if (lambda <= lambdaEdge && lambda >= continuum->lambda[0]) { opaque = TRUE; /* --- Find the principal quantum number of level i -- -------- */ n_eff = sqrt(E_RYDBERG / (atmos.H->E[continuum->j] - atmos.H->E[continuum->i])); g_bf = Gaunt_bf(lambda, n_eff, atmos.H->stage[i] + 1); sigma = sigma0 * n_eff * g_bf * CUBE(lambda/lambdaEdge); hc_kla = hc_k / lambda; twohnu3_c2 = twohc / CUBE(lambda); np = atmos.H->n[atmos.H->Nlevel-1]; for (k = 0; k < atmos.Nspace; k++) { expla = exp(-hc_kla/atmos.T[k]); gijk = atmos.H->nstar[i][k]/npstar[k] * expla; chi[k] += sigma * (1.0 - expla) * atmos.H->n[i][k]; eta[k] += twohnu3_c2 * gijk * sigma * np[k]; } } } return opaque; }
void VarData::HeaderInteraction(FILE *FileToWrite){ double Norm2 = CUBE(pReOverCutOff()) / SQR(pNPCh()); double Norm3 = CUBE(SQR(pReOverCutOff()) / pNPCh()); MInt->Rescale(1./Norm2,2); MInt->Rescale(1./Norm3,3); fprintf(FileToWrite,"# v=%.2f %.2f %.2f %.2f %.2f %.2f ",MInt->Coeff(0,0),MInt->Coeff(0,1),MInt->Coeff(0,2),MInt->Coeff(1,1),MInt->Coeff(1,2),MInt->Coeff(2,2)); fprintf(FileToWrite,"w=%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n",MInt->Coeff(0,0,0),MInt->Coeff(0,0,1),MInt->Coeff(0,0,2),MInt->Coeff(0,1,1),MInt->Coeff(0,1,2),MInt->Coeff(0,2,2),MInt->Coeff(1,1,1),MInt->Coeff(1,1,2),MInt->Coeff(1,2,2),MInt->Coeff(2,2,2)); fprintf(FileToWrite,"# a2=%.1f a3=%.1f Re=%.1f N=%d ks=%.3f kb=%.3f l0=0\n",Gen->WFuncStraight2,Gen->WFuncStraight3,Gen->ReOverCutOff,Gen->NPCh,Gen->kappaSpring,Gen->kappaBend); MInt->Rescale(Norm2,2); MInt->Rescale(Norm3,3); }
// samples the radial distribution function void SampleRDF(int Ichoise) { int i,j; double r2; static double Ggt,Gg[Maxx],Delta; VECTOR dr; FILE *FilePtr; switch(Ichoise) { case INITIALIZE: for(i=0;i<Maxx;i++) Gg[i]=0.0; Ggt=0.0; Delta=Box/(2.0*Maxx); break; case SAMPLE: Ggt+=1.0; // loop over all pairs for(i=0;i<NumberOfParticles-1;i++) { for(j=i+1;j<NumberOfParticles;j++) { dr.x=Positions[i].x-Positions[j].x; dr.y=Positions[i].y-Positions[j].y; dr.z=Positions[i].z-Positions[j].z; // apply boundary conditions dr.x-=Box*rint(dr.x/Box); dr.y-=Box*rint(dr.y/Box); dr.z-=Box*rint(dr.z/Box); r2=sqrt(SQR(dr.x)+SQR(dr.y)+SQR(dr.z)); // calculate in which bin this interaction is in if(r2<0.5*Box) Gg[(int)(r2/Delta)]+=2.0; } } break; case WRITE_RESULTS: // Write Results To Disk FilePtr=fopen("rdf.dat","w"); for(i=0;i<Maxx-1;i++) { r2=(4.0*M_PI/3.0)*(NumberOfParticles/CUBE(Box))*CUBE(Delta)*(CUBE(i+1)-CUBE(i)); fprintf(FilePtr,"%f %f\n",(i+0.5)*Delta,Gg[i]/(Ggt*NumberOfParticles*r2)); } fclose(FilePtr); break; } }
void generate(PARAMS *p,SSDATA *d) { double GPE,KE,f; int i,j; for (i=0;i<p->N;i++) { gen_body(p,&d[i],i); for (j=0;j<i;j++) if (OVERLAP(d[i].pos,d[i].radius,d[j].pos,d[j].radius)) { (void) printf("Particle %i overlaps particle %i\n" "-- regenerating particle %i\n",i,j,i); --i; break; } } GPE = KE = 0.0; for (i=0;i<p->N;i++) { GPE += d[i].mass*pot(p,d,i); KE += 0.5*d[i].mass*MAG_SQ(d[i].vel); } (void) printf("Starting KE = %g = %g times GPE\n",KE,KE/GPE); assert(KE > 0.0); f = -0.5*p->KEf*GPE/KE; assert(f >= 0.0); for (i=0;i<p->N;i++) reset_vel(p,f,&d[i]); GPE = KE = 0.0; for (i=0;i<p->N;i++) { GPE += d[i].mass*pot(p,d,i); KE += 0.5*d[i].mass*MAG_SQ(d[i].vel); } (void) printf("Adjusted KE = %g = %g times GPE (= %g times virial)\n",KE,KE/GPE,-2*KE/GPE); { double t_dyn,t_step; t_dyn = 2*sqrt(CUBE(p->Rd)/(p->N*p->m)); (void) printf("Dynamical time ~ %g\n",t_dyn); t_step = 2*sqrt(CUBE(p->R)/p->m)/33; (void) printf("Recommended time step < %g\n",t_step); (void) printf("Estimated number of steps needed per t_dyn = %i\n",(int) (t_dyn/t_step + 0.5)); } }
double nonlin_heat_source_2(double x, double y, double z, double time, double temperature) { double source_value; double pi = M_PI, uex, f; double w = 1.5, m = 2.0, n = 3.0; uex = exp(-w*time) * sin(m*pi*x) * sin(n*pi*y); f = (w -(m*m + n*n)*pi*pi)*uex + uex - CUBE(uex); source_value = -temperature + CUBE( temperature ) + f; return source_value; } // end of 'nonlin_heat_source_2'
/* * Draw a graph of the polynomial with the coefficients a,b,c and d, * using ascii characters. * @param a,b,c,d - The polynomial's coefficients. */ void drawGraph(double a, double b, double c, double d) { int x,y; //variables for iterating over the the x and y axes //starting from the top left corner moving one line at a time working //our way to the bottom right corner of our range. for(y = Y_MAX; y >= Y_MIN; y--) { for(x = X_MIN; x <= X_MAX; x++) { // if(fabs(a+b*x+c*SQUARE(x)+d*CUBE(x) - y) < TOLERANCE) { printf(FUNCTION_LINE); } else if(x==0 && y==0) { printf(ORIGIN); } else if(x==0) { printf(Y_AXIS); } else if(y==0) { printf(X_AXIS); } else { printf(EMPTY_SPACE); } } printf("\n"); } }
/* NB: rates include the degeneracy of the initial level!!! */ static double rate_int_f(double e, void *params) { const rate_int_params_t *p = params; double xs, Omega; double x = e/p->de, x1, conv; switch (p->type) { case CFACDB_CS_CE: case CFACDB_CS_CI: x1 = x; /* convert collisional strength to cross-section */ conv = M_PI/(2*e); break; case CFACDB_CS_PI: x1 = x + 1; /* d_gf/d_E* to RR cross-section */ conv = M_PI*CUBE(ALPHA)*p->de*SQR(x1)/x; break; default: return 0.0; break; } Omega = cfacdb_intext(&p->intext, x1); xs = Omega*conv; return xs*get_e_MB_vf(p->T, e); }
void interpolation(double y[],double xs[],double ys[],int n,double x[], int nx,double *ys2, double *temp) { int i,j,jfin,cur,prev; double p,sig,a,b,c,d,e,f,g,a0,a1,a2,a3,xc; /* Compute second derivatives at the knots */ ys2[0]=temp[0]=0.0; for (i=1;i<n-1;i++) { sig=(xs[i]-xs[i-1])/(xs[i+1]-xs[i-1]); p=sig*ys2[i-1]+2.0; ys2[i]=(sig-1.0)/p; temp[i]=(ys[i+1]-ys[i])/(xs[i+1]-xs[i])-(ys[i]-ys[i-1])/(xs[i]-xs[i-1]); temp[i]=(6.0*temp[i]/(xs[i+1]-xs[i-1])-sig*temp[i-1])/p; } ys2[n-1]=0.0; for (j=n-2;j>=0;j--) ys2[j]=ys2[j]*ys2[j+1]+temp[j]; /* Compute the spline coefficients */ cur=0; j=0; jfin=n-1; while (xs[j+2]<x[0]) j++; while (xs[jfin]>x[nx-1]) jfin--; for (;j<=jfin;j++) { /* Compute the coefficients of the polynomial between two knots */ a=xs[j]; b=xs[j+1]; c=b-a; d=ys[j]; e=ys[j+1]; f=ys2[j]; g=ys2[j+1]; a0=(b*d-a*e+CUBE(b)*f/6-CUBE(a)*g/6)/c+c*(a*g-b*f)/6; a1=(e-d-SQUARE(b)*f/2+SQUARE(a)*g/2)/c+c*(f-g)/6; a2=(b*f-a*g)/(2*c); a3=(g-f)/(6*c); prev=cur; while ((cur<nx) && ((j==jfin) || (x[cur]<xs[j+1]))) cur++; /* Compute the value of the spline at the sampling times x[i] */ for (i=prev;i<cur;i++) { xc=x[i]; y[i]=a0+a1*xc+a2*SQUARE(xc)+a3*CUBE(xc); } } }
double MultivariateFNormalSufficient::evaluate_derivative_factor() const { //warning: untested! //d(-log(p))/dfactor = -N/f^3 trans(eps)P(eps) -1/f^3 tr(WP) + NM/f LOG( "MVN: evaluate_derivative_factor() = " << std::endl); double R; if (N_==1) { R = - get_mean_square_residuals()/CUBE(factor_) + double(M_)/factor_; } else { R = - (double(N_)*get_mean_square_residuals() + trace_WP())/CUBE(factor_) + double(M_*N_)/factor_; } return R; }
int main(void) { float x; printf("Enter a number: "); scanf("%f", &x); printf("the cube of %f what you enter is:%f", x, CUBE(x)); return 0; }
double nonlin_heat_source_4(double x, double y, double z, double time, double temperature) { double source_value = 2.0 * CUBE( temperature ); return source_value; } // end of 'nonlin_heat_source_4'
int read_header(FILE *f, Slice *s) /* Read the header from file f. Place information and calculated numbers into the Slice variable, unless *s is NULL, in which case just skip the header */ /* Return 0 if successful, non-zero otherwise */ { int sizeheader[2]; float header[100]; f77read(f, header, 400); f77read(f, sizeheader, 8); if (s==NULL) return 0; /* We've been instructed just to skip the header without recording the information */ /* Now read the interesting information out of these arrays */ s->numpart = sizeheader[0]; s->numblocks = sizeheader[1]; s->numperblock = sizeheader[0]/sizeheader[1]; if (s->numpart != s->numblocks*(s->numperblock)) myerror("Number of blocks not an even divisor of number of particles."); s->z = header[0]; s->boxsize = header[1]*1000.0; /* We use kpc, not Mpc */ s->physsize = s->boxsize/(1.0+s->z); /* We use kpc, not Mpc */ s->velscale = 100.0*header[1]*sqrt(3.0/8.0/PI)/(1.0+s->z); /* To go from data to pec vel */ s->omega = header[4]; if (header[6]!=0.0) myerror("HDM component listed in header."); s->lambda = header[7]; s->h0 = header[8]; s->sigma8 = header[9]; /* At z=0 */ /* Now find some computed quantities. */ s->a = 1.0/(1.0+s->z); s->curv = 1.0-s->omega-s->lambda; s->gamma = s->omega*(s->h0); s->specn = 1.0; s->hubb = 0.1*sqrt(s->omega/CUBE(s->a)+s->curv/SQR(s->a)+s->lambda)*(s->a); /* The following assume Omega = 1 */ s->masspart = RHOCRIT/s->numpart*CUBE(s->boxsize); s->growth = s->a; s->t = HTIME*(s->h0)*pow(s->a, 1.5); return 0; }
void nonlin_force_density_4(double x, double y, double z, double time, DoubleVec &displacement, DoubleVec &result) { result[0] = 12.0 * exp( -0.25*displacement[0] ) - 9.0 * exp( -0.5*displacement[0] ); result[1] = -4.0 * SQR( displacement[1] ) + 8.0 * CUBE( displacement[1] ); result[2] = 0.0; } // end of 'nonlin_force_density_4'
void nonlin_force_density_1(double x, double y, double z, double time, DoubleVec &displacement, DoubleVec &result) { double pi = M_PI, uex0, uex1, f0, f1; double m0 = 2.0, n0 = 3.0, m1 = 1.0, n1 = 2.0; uex0 = sin(m0*pi*x) * sin(n0*pi*y); uex1 = sin(m1*pi*x) * sin(n1*pi*y); f0 = (m0*m0 + n0*n0)*pi*pi * uex0 - uex0 + CUBE( uex0 ); f1 = (m1*m1 + n1*n1)*pi*pi * uex1 - uex1 + CUBE( uex1 ); result[0] = displacement[0] - CUBE( displacement[0] ) + f0; result[1] = displacement[1] - CUBE( displacement[1] ) + f1; result[2] = 0.0; } // end of 'nonlin_force_density_1'
int main(void) { int y = 2; printf("%.3f, %d\n", CUBE(1.2), CUBE(y + 3)); printf("%d, %d\n", NMOD_4(7.9), NMOD_4(17)); printf("%.3f\n", XY(14.0,.3f)); test_nelms_macro(); test_toupper(); test_disp(); return 0; }
REAL SmoothingDerivative(REAL theta) { REAL on,off; on=170.0*DEG2RAD; off=180.0*DEG2RAD; if(theta<on) return 0.0; return 6.0*(off-theta)*(on-theta)/CUBE(off-on); }
void Forces::AllocTens(){ if(VAR_IF_TYPE(SysAlloc,ALL_TENS)) return; for(int d=0;d<3;d++){ Tens.RefPos[d] = pNanoPos(0,d);//.5*pEdge(d); } Tens.Pre = (double **)calloc(Tens.NComp,sizeof(double)); Tens.Dens = (double **)calloc(2,sizeof(double)); // 2d if(VAR_IF_TYPE(Tens.CalcMode,CALC_2d)){ Tens_Ref = &Forces::TensRefPol; SetEdge(.5*MIN(pEdge(CLat1),pEdge(CLat2)),3); Tens.Edge[0] = pEdge(3); Tens.Edge[1] = pEdge(CNorm); Tens.Edge[2] = 1.; Tens.Wrap[0] = 0; Tens.Wrap[1] = 1; for(int d=0;d<3;d++){ Tens.EdgeInv[d] = 1./Tens.Edge[d]; } for(int c=0;c<Tens.NComp;c++){ Tens.Pre[c] = (double *)calloc(SQR(Tens.NSlab),sizeof(double)); } for(int c=0;c<2;c++){ Tens.Dens[c] = (double *)calloc(SQR(Tens.NSlab),sizeof(double)); } } // 3d if(VAR_IF_TYPE(Tens.CalcMode,CALC_3d)){ Tens_Ref = &Forces::TensRefCart; for(int d=0;d<3;d++){ Tens.Edge[d] = pEdge(d); Tens.Wrap[d] = 1; Tens.EdgeInv[d] = pInvEdge(d); } for(int c=0;c<Tens.NComp;c++){ Tens.Pre[c] = (double *)calloc(CUBE(Tens.NSlab),sizeof(double)); } for(int c=0;c<2;c++){ Tens.Dens[c] = (double *)calloc(CUBE(Tens.NSlab),sizeof(double)); } } VAR_ADD_TYPE(SysAlloc,ALL_TENS); }
main() { int i,offset; offset = 5; for (i = START;i <= STOP;i++) { printf("The square of %3d is %4d, and its cube is %6d\n", i+offset,SQUR(i+offset),CUBE(i+offset)); printf("The wrong of %3d is %6d\n",i+offset,WRONG(i+offset)); } }
REAL Smoothing(REAL theta) { REAL on,off; on=170.0*DEG2RAD; off=180.0*DEG2RAD; if(theta<on) return 1.0; return SQR(off-theta)*(off+2.0*theta-3.0*on)/CUBE(off-on); }
int armstrong(int n) { int temp=n,t,sum=0; while(n) { t=n%10; sum+=CUBE(t); n=n/10; } if(sum==temp) return 1; return 0; }
boolean test_score(population *pop, entity *entity) { double A, B, C, D; /* Parameters. */ A = ((double *)entity->chromosome[0])[0]; B = ((double *)entity->chromosome[0])[1]; C = ((double *)entity->chromosome[0])[2]; D = ((double *)entity->chromosome[0])[3]; entity->fitness = -(fabs(0.75-A)+SQU(0.95-B)+fabs(CUBE(0.23-C))+FOURTH_POW(0.71-D)); return TRUE; }
/* Calculate the Wigner-Seitz radius of sites in a lattice, assuming that they * all share the same radius. We pass the 2D matrix like this to make the * semantics clearer than const double **lat_matrix. */ double wigner_seitz_radius (double lattice_parameter, const double lat_matrix[3][3], int nsites) { double determinant = 0.0; determinant += lat_matrix[0][0] * (lat_matrix[1][1] * lat_matrix[2][2] - lat_matrix[1][2] * lat_matrix[2][1]); determinant += lat_matrix[0][1] * (lat_matrix[1][2] * lat_matrix[2][0] - lat_matrix[1][0] * lat_matrix[2][2]); determinant += lat_matrix[0][2] * (lat_matrix[1][0] * lat_matrix[2][1] - lat_matrix[1][1] * lat_matrix[2][0]); const double volume = determinant * CUBE(lattice_parameter); return cbrt (0.75 * volume / (M_PI * (double) nsites)); }
void real_eigenvalues(double a2, double a1, double a0, double *z1, double *z2, double *z3) /* ------------------------------------------------------------------------- * * More generally, the real roots of a cubic (roots are guaranteed to be all * real if the coefficients ai are the invariants of a symmetric 3x3 matrix). * We find the roots of x^3 + a2.x^2 + a1.x + a0 = 0 and return them sorted * in descending order. See Abramowitz & Stegun 3.8. * ------------------------------------------------------------------------- */ { double q, r, t, thetaon3, cosA, sinA; q = a1 / 3.0 - SQR(a2) / 9.0; r = (a1*a2 - 3.0*a0) / 6.0 - CUBE(a2) / 27.0; t = CUBE(q) + SQR(r); if (t > 0) { #if 0 /* -- This is mostly caused by rounding errors. Ignore. */ fprintf(stderr, "warning: t = %g: ==> complex conjugate roots\n", t); #endif t = 0.0; } t = sqrt(-t); thetaon3 = atan2(t, r)/3.0; cosA = cos(thetaon3); sinA = sin(thetaon3); q = sqrt(-q); *z1 = 2.0*q*cosA - a2/3.0; *z2 = (*z3 = -q*cosA -a2/3.0); *z2 = *z2 - SQRT3*q*sinA; *z3 = *z3 + SQRT3*q*sinA; if (*z2 > *z1) SWAP(*z1, *z2); if (*z3 > *z2) SWAP(*z2, *z3); if (*z2 > *z1) SWAP(*z1, *z2); }
/* Initialize Taper params */ void Init_Taper( control_params *control, storage *workspace, MPI_Comm comm ) { real d1, d7; real swa, swa2, swa3; real swb, swb2, swb3; swa = control->nonb_low; swb = control->nonb_cut; if( fabs( swa ) > 0.01 ) fprintf( stderr, "Warning: non-zero lower Taper-radius cutoff\n" ); if( swb < 0 ) { fprintf( stderr, "Negative upper Taper-radius cutoff\n" ); MPI_Abort( comm, INVALID_INPUT ); } else if( swb < 5 ) fprintf( stderr, "Warning: very low Taper-radius cutoff: %f\n", swb ); d1 = swb - swa; d7 = pow( d1, 7.0 ); swa2 = SQR( swa ); swa3 = CUBE( swa ); swb2 = SQR( swb ); swb3 = CUBE( swb ); workspace->Tap[7] = 20.0 / d7; workspace->Tap[6] = -70.0 * (swa + swb) / d7; workspace->Tap[5] = 84.0 * (swa2 + 3.0*swa*swb + swb2) / d7; workspace->Tap[4] = -35.0 * (swa3 + 9.0*swa2*swb + 9.0*swa*swb2 + swb3 ) / d7; workspace->Tap[3] = 140.0 * (swa3*swb + 3.0*swa2*swb2 + swa*swb3 ) / d7; workspace->Tap[2] =-210.0 * (swa3*swb2 + swa2*swb3) / d7; workspace->Tap[1] = 140.0 * swa3 * swb3 / d7; workspace->Tap[0] = (-35.0*swa3*swb2*swb2 + 21.0*swa2*swb3*swb2 + 7.0*swa*swb3*swb3 + swb3*swb3*swb ) / d7; }
// dispatch to this func if writer doesn't have native cubics // instead of a single cubic, output many arcs // FIXME: make the number of arcs adjustabe (a property of Writer?) int Ttt::my_cubic_as_biarcs(const FT_Vector* control1, const FT_Vector* control2, const FT_Vector *to, void* user) { double len; extents ext; boost::tie(len,ext) = cubic_length(control1,control2,to); glyph_extents.add_extents(ext); // define the subdivision of curves into arcs: approximate curve length // in font coordinates to get one arc pair (minimum of two arc pairs // per curve) double dsteps=my_writer->get_cubic_biarc_subdiv(); int steps = (int) std::max( (double)2, len/dsteps); // at least two steps P p0(&last_point); P p1(control1); P p2(control2); P p3(to); P q0=p1-p0; P q1=p2-p1; P q2=p3-p2; P ps=p0; P ts=q0; for(int ti=1; ti<=steps; ti++) { double tf = ti*1.0/steps; double t1 = 1-tf; P p = p0*CUBE(t1) + p1*3*tf*SQ(t1) + p2*3*SQ(tf)*t1 + p3*CUBE(tf) ; P t = q0*SQ(t1) + q1*2*tf*t1 + q2*SQ(tf); biarc(ps, ts, p, t, 1.0); // output many biarcs instead. ps = p; ts = t; } last_point = *to; return 0; }