DBstatus GEevalnc( /*-------------- Argument declarations --------------------------------------*/ /* */ /* In: */ DBCurve *p_cur, /* Curve (ptr) */ DBSeg *p_seg, /* Curve segment (ptr) */ EVALC *p_evalc ) /* Curve coordinates & derivatives (ptr) */ /* Out: */ /* Data to p_evalc */ /*---------------------------------------------------------------------------*/ { /* Start of function */ /*!------------------------ Internal variables ------------------------------*/ bool offseg; /* Flag for offset segment */ bool ratseg; /* Flag for rational segment */ DBfloat offset; /* Offset value */ DBVector n_p; /* Curve segment plane normal */ DBint status; /* Error code from called function */ DBint i; /* loop variable */ DBVector r; /* Position (non-offset) */ DBVector drdu; /* First derivative with respect to u */ DBVector d2rdu2; /* Second derivative with respect to u */ DBVector d3rdu3; /* Third derivative with respect to u */ DBHvector w; /* Position, homogenus coordinates */ DBHvector dwdu; /* 1:st der.with respect to u, hom. coord. */ DBHvector d2wdu2; /* 2:nd der.with respect to u, hom. coord. */ DBHvector d3wdu3; /* 3:rd der.with respect to u, hom. coord. */ DBshort degree; /* Nurbs degree */ DBint offs_p; /* offset in control points array */ DBint offs_u; /* offset in knots array */ DBHvector *P; /* Pointer to control points for curve */ DBfloat *U; /* Pointer to knots for curve */ DBfloat u; /* local parameter value */ DBfloat invHom; /* 1/w.w_gm) */ DBfloat invHomQuad; /* 1/((w.w_gm)*(w.w_gm)) */ DBfloat invHomCub; /* 1/((w.w_gm)*(w.w_gm)*(w.w_gm)) */ char errbuf[80]; /* String for error message fctn erpush */ DBfloat ders[3][MAX_NURBD]; /* basis values[der_no][index] */ DBint no_der; /* no off requested derivatives */ DBfloat kappa; /* Curvature */ DBfloat tx,ty,tz; /* Unit tangent */ DBfloat bx,by,bz; /* Binormal */ DBfloat nx,ny,nz; /* Principal normal */ DBfloat dsdu,dsdu3,dsdu6; /* 1:st derivative of s with respect to u */ DBfloat d2sdu2; /* 2:nd derivative of s with respect to u */ DBfloat xoff,yoff,zoff; /* Position in offset */ DBfloat npy,npx,npz; /* Direction of tangent in offset */ DBfloat dxoff,dyoff,dzoff; /* 1:st der. with respect to u, in offset */ DBfloat d2xoff,d2yoff,d2zoff;/* 2:nd der. with respect to u, in offset */ DBfloat ntpx,ntpy,ntpz; /* Principal normal in offset */ DBfloat dsoffs,dsoff3; /* 1:st derivative of s in offset */ DBfloat kapofs; /* Curvature in offset */ DBfloat dkappadu; /* 1:st derivative of Curvature */ DBfloat tmpx,tmpy,tmpz,tmp; DBfloat ux,uy,uz,vx,vy,vz; /*-------------------end-of-declarations-------------------------------------*/ /* *** Copy to local variables */ degree = p_seg -> nurbs_degree; offs_p = p_seg -> offset_cpts; offs_u = p_seg -> offset_knots; P = p_seg -> cpts_c; U = p_seg -> knots_c; u = p_evalc->t_local; /* *** Let offset flag be true and retrieve curve plane if the *** curve is in offset. */ if ( p_seg->ofs != 0.0 ) { offseg = TRUE; offset = p_seg->ofs; n_p.x_gm = p_cur->csy_cu.g31; n_p.y_gm = p_cur->csy_cu.g32; n_p.z_gm = p_cur->csy_cu.g33; } else { offseg = FALSE; offset = p_seg->ofs; } /* *** Is the segment rational? */ ratseg = FALSE; for (i=0 ;i <= degree ; i++ ) { if (ABS((P + offs_p + i)->w_gm - 1.0) > COMPTOL) { ratseg = TRUE; break; } } /* *** How many derivatives do we need in "DeersBasisFuns"? */ no_der = -1; if ( p_evalc ->evltyp & EVC_R ) no_der = 0; if ( p_evalc ->evltyp & EVC_DR ) no_der = 1; if (offseg == TRUE || (p_evalc ->evltyp & (EVC_D2R + EVC_PN + EVC_BN + EVC_KAP))) no_der = 2; if (offseg == TRUE && (p_evalc ->evltyp & (EVC_D2R + EVC_PN + EVC_BN + EVC_KAP))) no_der = 3; if (no_der < 0) { sprintf(errbuf," - evltyp - %%GEevalnc"); return(varkon_erpush("SU2993",errbuf)); } /* *** Calculate basis values */ status = DersBasisFuns (offs_u,u,degree,no_der,p_seg->knots_c,ders); /* *** Calculate position *** (always needed for a rational curve) */ if ((p_evalc ->evltyp & EVC_R) || (ratseg == TRUE)) { w.x_gm = w.y_gm = w.z_gm = w.w_gm = 0.0; for (i=0;i<=degree;i++) { w.x_gm = w.x_gm + (P + offs_p + i)->x_gm * ders[0][i]; w.y_gm = w.y_gm + (P + offs_p + i)->y_gm * ders[0][i]; w.z_gm = w.z_gm + (P + offs_p + i)->z_gm * ders[0][i]; w.w_gm = w.w_gm + (P + offs_p + i)->w_gm * ders[0][i]; } if (ratseg == TRUE) { invHom = 1.0 / w.w_gm; p_evalc ->r.x_gm = r.x_gm = w.x_gm * invHom; p_evalc ->r.y_gm = r.y_gm = w.y_gm * invHom; p_evalc ->r.z_gm = r.z_gm = w.z_gm * invHom; } else { w.w_gm = 1.0; p_evalc ->r.x_gm = r.x_gm = w.x_gm; p_evalc ->r.y_gm = r.y_gm = w.y_gm; p_evalc ->r.z_gm = r.z_gm = w.z_gm; } if ( no_der == 0 ) return(SUCCED); } /* end position */ /* *** Calculate first derivative */ if ((p_evalc ->evltyp & (EVC_DR+EVC_PN+EVC_BN+EVC_KAP)) || (offseg==TRUE )) { dwdu.x_gm = dwdu.y_gm = dwdu.z_gm = dwdu.w_gm = 0.0; for (i=0 ;i <= degree ;i++ ) { dwdu.x_gm = dwdu.x_gm + (P + offs_p + i)->x_gm * ders[1][i]; dwdu.y_gm = dwdu.y_gm + (P + offs_p + i)->y_gm * ders[1][i]; dwdu.z_gm = dwdu.z_gm + (P + offs_p + i)->z_gm * ders[1][i]; dwdu.w_gm = dwdu.w_gm + (P + offs_p + i)->w_gm * ders[1][i]; } if (ratseg == TRUE) { invHomQuad = invHom * invHom; drdu.x_gm = (w.w_gm * dwdu.x_gm - dwdu.w_gm * w.x_gm) * invHomQuad; drdu.y_gm = (w.w_gm * dwdu.y_gm - dwdu.w_gm * w.y_gm) * invHomQuad; drdu.z_gm = (w.w_gm * dwdu.z_gm - dwdu.w_gm * w.z_gm) * invHomQuad; } else { drdu.x_gm = dwdu.x_gm; drdu.y_gm = dwdu.y_gm; drdu.z_gm = dwdu.z_gm; } p_evalc ->drdt.x_gm = drdu.x_gm; p_evalc ->drdt.y_gm = drdu.y_gm; p_evalc ->drdt.z_gm = drdu.z_gm; if ( no_der == 1 ) return(SUCCED); } /* end 1:st derivative */ /* *** Calculate second derivative */ if ( (p_evalc->evltyp & (EVC_D2R+EVC_PN+EVC_BN+EVC_KAP)) || (offseg==TRUE )) { if (degree > 1) { d2wdu2.x_gm=0.0; d2wdu2.y_gm=0.0; d2wdu2.z_gm=0.0; d2wdu2.w_gm=0.0; for (i=0 ;i <= degree ;i++ ) { d2wdu2.x_gm = d2wdu2.x_gm + (P + offs_p + i)->x_gm * ders[2][i]; d2wdu2.y_gm = d2wdu2.y_gm + (P + offs_p + i)->y_gm * ders[2][i]; d2wdu2.z_gm = d2wdu2.z_gm + (P + offs_p + i)->z_gm * ders[2][i]; d2wdu2.w_gm = d2wdu2.w_gm + (P + offs_p + i)->w_gm * ders[2][i]; } if (ratseg == TRUE) { invHomCub = invHomQuad * invHom; d2rdu2.x_gm = (w.w_gm * (w.w_gm * d2wdu2.x_gm - w.x_gm * d2wdu2.w_gm) + 2 * dwdu.w_gm * (w.x_gm * dwdu.w_gm - w.w_gm * dwdu.x_gm)) * invHomCub; d2rdu2.y_gm = (w.w_gm * (w.w_gm * d2wdu2.y_gm - w.y_gm * d2wdu2.w_gm) + 2 * dwdu.w_gm * (w.y_gm * dwdu.w_gm - w.w_gm * dwdu.y_gm)) * invHomCub; d2rdu2.z_gm = (w.w_gm * (w.w_gm * d2wdu2.z_gm - w.z_gm * d2wdu2.w_gm) + 2 * dwdu.w_gm * (w.z_gm * dwdu.w_gm - w.w_gm * dwdu.z_gm)) * invHomCub; } else { d2rdu2.x_gm = d2wdu2.x_gm; d2rdu2.y_gm = d2wdu2.y_gm; d2rdu2.z_gm = d2wdu2.z_gm; } } else d2rdu2.x_gm = d2rdu2.y_gm = d2rdu2.z_gm = d2wdu2.w_gm = 0.0; p_evalc->d2rdt2.x_gm = d2rdu2.x_gm ; p_evalc->d2rdt2.y_gm = d2rdu2.y_gm ; p_evalc->d2rdt2.z_gm = d2rdu2.z_gm ; } /* end 2:nd derivative */ /* *** Do we need to calculate kappa ? */ if (p_evalc ->evltyp & (EVC_KAP + EVC_BN + EVC_PN) || (offseg == TRUE )) { tmpx = drdu.y_gm * d2rdu2.z_gm - drdu.z_gm * d2rdu2.y_gm; tmpy = drdu.z_gm * d2rdu2.x_gm - drdu.x_gm * d2rdu2.z_gm; tmpz = drdu.x_gm * d2rdu2.y_gm - drdu.y_gm * d2rdu2.x_gm; tmp = tmpx * tmpx + tmpy * tmpy + tmpz * tmpz; /* *** dr/du = (dxdu,dydu,dzdu). *** The tangent vector, T = dr/ds is the unit vector with same *** direction as dr/du. *** Calculate the length of dr/du = dsdu. */ dsdu = SQRT( drdu.x_gm * drdu.x_gm + drdu.y_gm * drdu.y_gm + drdu.z_gm * drdu.z_gm) ; dsdu3 = dsdu*dsdu*dsdu; if ( dsdu3 < 1e-14 ) dsdu3 = 1e-10; if ( tmp > COMPTOL ) kappa = SQRT(tmp)/dsdu3; else kappa = 0.0; p_evalc->kappa = kappa; } /* end kappa */ /* *** The binormal. This is calculated as: *** drdu X d2rdu2 / dsdu ** 3 / kappa. See Faux-Pratt p. 100. */ if ( p_evalc ->evltyp & (EVC_BN+EVC_PN) || (offseg == TRUE )) { bx = tmpx/dsdu3; by = tmpy/dsdu3; bz = tmpz/dsdu3; if ( kappa > COMPTOL ) { bx /= kappa; by /= kappa; bz /= kappa; } p_evalc->bn_x = bx; p_evalc->bn_y = by; p_evalc->bn_z = bz; p_evalc->b_norm.x_gm = bx; p_evalc->b_norm.y_gm = by; p_evalc->b_norm.z_gm = bz; } /*end binormal*/ /* *** Principal normal, N = B X T. */ if ( (p_evalc ->evltyp & EVC_PN) ||(offseg == TRUE )) { tx = drdu.x_gm/dsdu; ty = drdu.y_gm/dsdu; tz = drdu.z_gm/dsdu; nx = by*tz - ty*bz; ny = bz*tx - tz*bx; nz = bx*ty - tx*by; p_evalc->pn_x = nx; p_evalc->pn_y = ny; p_evalc->pn_z = nz; p_evalc->p_norm.x_gm = nx; p_evalc->p_norm.y_gm = ny; p_evalc->p_norm.z_gm = nz; } /*end principal normal*/ /* *** Calculate offset coordinates and derivatives if the curve *** segment is in offset. */ if (offseg == TRUE ) { /* *** Calculate the direction of the offset vector as the cross-product *** between the tangent to the curve and the normal of the curve-plane. *** T and P are normalized, thus the result of T X P is a *** normalized vector with same direction as the curve normal, *** possibly with opposite sign. *** When the curve turns right in the curve plane, T X P = N but *** when the curve turbs left T X P = -N. This is varkons definition *** of the concept of offset. Thus positive offset is always the right *** side of the curve in the curve plane. *** Length of offset vector = the offset value of the curve. */ if (p_evalc ->evltyp & EVC_R) { p_evalc->r.x_gm= xoff= r.x_gm + offset*(ty * n_p.z_gm- n_p.y_gm * tz); p_evalc->r.y_gm= yoff= r.y_gm + offset*(tz * n_p.x_gm- n_p.z_gm * tx); p_evalc->r.z_gm= zoff= r.z_gm + offset*(tx * n_p.y_gm- n_p.x_gm * ty); } if ((p_evalc ->evltyp & (EVC_DR+EVC_KAP))) { /* *** The offset tangent has same direction as the original tangent, T. *** But, since offset is counted positive on the right side of the *** curve and negative on the left side of the curve, the sign of the *** tangent must be adjusted. *** compare with the calculation of coordinates in offset. *** The direction of the offset tangent is calculated as N X P. */ npx = ny * n_p.z_gm - n_p.y_gm * nz; npy = nz * n_p.x_gm - n_p.z_gm * nx; npz = nx * n_p.y_gm - n_p.x_gm * ny; /* *** The tangent in offset = dr/du + offset*kappa * dsdu*(npx,npy,npz). *** Simply a factor kappa*offset greater. The sign of np eliminates *** the sign of offset, which make the result correct. */ p_evalc->drdt.x_gm = dxoff = drdu.x_gm + offset * kappa * dsdu * npx; p_evalc->drdt.y_gm = dyoff = drdu.y_gm + offset * kappa * dsdu * npy; p_evalc->drdt.z_gm = dzoff = drdu.z_gm + offset * kappa * dsdu * npz; } if ((p_evalc ->evltyp & (EVC_D2R+EVC_KAP))) { /* Third derivative */ if (degree>2) { d3wdu3.x_gm=0.0; d3wdu3.y_gm=0.0; d3wdu3.z_gm=0.0; d3wdu3.w_gm=0.0; for (i=0 ;i <= degree ;i++ ) { d3wdu3.x_gm = d3wdu3.x_gm + (P + offs_p + i)->x_gm * ders[3][i]; d3wdu3.y_gm = d3wdu3.y_gm + (P + offs_p + i)->y_gm * ders[3][i]; d3wdu3.z_gm = d3wdu3.z_gm + (P + offs_p + i)->z_gm * ders[3][i]; d3wdu3.w_gm = d3wdu3.w_gm + (P + offs_p + i)->w_gm * ders[3][i]; } if (ratseg==TRUE) { d3rdu3.x_gm = (d3wdu3.x_gm -3.0 * d2rdu2.x_gm * dwdu.w_gm - 3.0 * drdu.x_gm * d2wdu2.w_gm - r.x_gm * d3wdu3.w_gm) * invHom; d3rdu3.y_gm = (d3wdu3.y_gm -3.0 * d2rdu2.y_gm * dwdu.w_gm - 3.0 * drdu.y_gm * d2wdu2.w_gm - r.y_gm * d3wdu3.w_gm) * invHom; d3rdu3.z_gm = (d3wdu3.z_gm -3.0 * d2rdu2.z_gm * dwdu.w_gm - 3.0 * drdu.z_gm * d2wdu2.w_gm - r.z_gm * d3wdu3.w_gm) * invHom; } else { d3rdu3.x_gm = d3wdu3.x_gm; d3rdu3.y_gm = d3wdu3.y_gm; d3rdu3.z_gm = d3wdu3.z_gm; } } else d3rdu3.x_gm = d3rdu3.y_gm = d3rdu3.z_gm = d3wdu3.x_gm = d3wdu3.y_gm = d3wdu3.z_gm = d3wdu3.w_gm = 0.0; /* Second derivative of s with respect to u. */ d2sdu2 = d2rdu2.x_gm * tx + d2rdu2.y_gm * ty + d2rdu2.z_gm * tz; /* dr/du X d2r/du2. */ vx = drdu.y_gm * d2rdu2.z_gm - drdu.z_gm * d2rdu2.y_gm; vy = drdu.z_gm * d2rdu2.x_gm - drdu.x_gm * d2rdu2.z_gm; vz = drdu.x_gm * d2rdu2.y_gm - drdu.y_gm * d2rdu2.x_gm; /* dr/du X d3r/du3 */ ux = drdu.y_gm * d3rdu3.z_gm - drdu.z_gm * d3rdu3.y_gm; uy = drdu.z_gm * d3rdu3.x_gm - drdu.x_gm * d3rdu3.z_gm; uz = drdu.x_gm * d3rdu3.y_gm - drdu.y_gm * d3rdu3.x_gm; /* Scalar product ( dr/du ! dr/du )**3 */ dsdu6 = dsdu3 * dsdu3; /* *** dkappa/du. */ dkappadu = vx * ux + vy * uy + vz * uz; if ( dsdu6 > TOL1 && kappa > TOL1 ) { dkappadu = dkappadu/dsdu6/kappa; } else { dkappadu = n_p.x_gm * ux + n_p.y_gm * uy + n_p.z_gm * uz; dkappadu = dkappadu/dsdu3; } dkappadu = dkappadu - 3.0 * kappa * (d2rdu2.x_gm * drdu.x_gm + d2rdu2.y_gm * drdu.y_gm + d2rdu2.z_gm * drdu.z_gm) / (dsdu * dsdu); /* *** Normalen i offset korrigerad för tecknet på offset. */ ntpx = ty * n_p.z_gm - n_p.y_gm * tz; ntpy = tz * n_p.x_gm - n_p.z_gm * tx; ntpz = tx * n_p.y_gm - n_p.x_gm * ty; /* *** Calculate second derivative */ p_evalc->d2rdt2.x_gm = d2xoff = d2rdu2.x_gm + offset*(dkappadu * dsdu * npx + kappa * (d2sdu2 * npx - dsdu * dsdu * kappa * ntpx)); p_evalc->d2rdt2.y_gm = d2yoff = d2rdu2.y_gm + offset*(dkappadu * dsdu * npy + kappa * (d2sdu2 * npy - dsdu * dsdu * kappa * ntpy)); p_evalc->d2rdt2.z_gm = d2zoff = d2rdu2.z_gm + offset*(dkappadu*dsdu*npz + kappa * (d2sdu2 * npz - dsdu * dsdu*kappa*ntpz)); } /* *** Kappa in offset. */ if (p_evalc ->evltyp & EVC_KAP) { tmpx = dyoff * d2zoff - dzoff * d2yoff; tmpy = dzoff * d2xoff - dxoff * d2zoff; tmpz = dxoff * d2yoff - dyoff * d2xoff; tmp = tmpx * tmpx + tmpy * tmpy + tmpz * tmpz; if ( tmp > COMPTOL ) { kapofs = SQRT(tmp); dsoffs = SQRT(dxoff*dxoff + dyoff*dyoff + dzoff*dzoff); dsoff3 = dsoffs * dsoffs * dsoffs; kapofs /= dsoff3; } else kapofs = 0.0; p_evalc->kappa = kapofs; } /* *** Binormal and Pricipal normal, need not to be recalculated. *** (not dependet on offset value) *** *** The binormal has same direction as for offset = 0. Both *** The principal-normal, N = B X T. Is also same as for offset = 0. */ } /* end offset curve */ return(SUCCED); } /* End of function */
main() { FILE *Bspline=fopen("Bspline.dat","wt"); FILE *Bsplineslope=fopen("Bsplineslope.dat","wt"); FILE *CP=fopen("CP.dat","wt"); FILE *BPxy=fopen("BPxy.dat","wt"); FILE *test=fopen("test.dat","wt"); int k, i, j, spn, *pivot; double *BaseP_x, *BaseP_y, *End_BaseP_x, *End_BaseP_y, angle, arc, D0_x, D0_y, Dn_x, Dn_y; double *BP_sn, *BP_dests, **BP_N, **temp_BP_N, *N, plusminusone; double *x, *y, *u, **xdev, **ydev; double *ksi, *eta, *rhs; double *U, *Nonuni_U, *End_Nonuni_U; double maxu, delu, **nders; double *nx, *ny, *kslope; BaseP_x = (double*)malloc(sizeof(double) * BP); BaseP_y = (double*)malloc(sizeof(double) * BP); End_BaseP_x = (double*)malloc(sizeof(double) * (BP+ENDD)); End_BaseP_y = (double*)malloc(sizeof(double) * (BP+ENDD)); BP_sn = (double*)malloc(sizeof(double) * BP); BP_dests = (double*)malloc(sizeof(double)); N = (double*)malloc(sizeof(double) * (ORD+1)); U = (double*)malloc(sizeof(double) * (VER_ARR+ENDD)); Nonuni_U = (double*)malloc(sizeof(double) * VER_ARR); End_Nonuni_U = (double*)malloc(sizeof(double) * (VER_ARR+ENDD)); pivot = (int*)malloc(sizeof(int) * (VER+ENDD)); rhs = (double*)malloc(sizeof(double) * (VER+ENDD)); ksi = (double*)malloc(sizeof(double) * (VER+ENDD)); eta = (double*)malloc(sizeof(double) * (VER+ENDD)); x = (double*)malloc(sizeof(double) * Num); y = (double*)malloc(sizeof(double) * Num); u = (double*)malloc(sizeof(double) * Num); nx = (double*)malloc(sizeof(double) * Num); ny = (double*)malloc(sizeof(double) * Num); kslope = (double*)malloc(sizeof(double) * Num); nders = (double**)malloc(sizeof(double*) * (ORD+1)); nders[0] = (double*)malloc(sizeof(double) * (ORD+1) * (ORD+1)); for(i=1; i<(ORD+1); i++) { nders[i] = nders[i-1] + (ORD+1); } xdev = (double**)malloc(sizeof(double*) * 2); xdev[0] = (double*)malloc(sizeof(double) * 2 * Num); for(i=1; i<2; i++) { xdev[i] = xdev[i-1] + Num; } ydev = (double**)malloc(sizeof(double*) * 2); ydev[0] = (double*)malloc(sizeof(double) * 2 * Num); for(i=1; i<2; i++) { ydev[i] = ydev[i-1] + Num; } /* BP_N = (double**)malloc(sizeof(double*) * BP); BP_N[0] = (double*)malloc(sizeof(double) * BP * BP); for(i=1; i<BP; i++) { BP_N[i] = BP_N[i-1] + BP; } temp_BP_N = (double**)malloc(sizeof(double*) * BP); temp_BP_N[0] = (double*)malloc(sizeof(double) * BP * BP); for(i=1; i<BP; i++) { temp_BP_N[i] = temp_BP_N[i-1] + BP; } */ BP_N = (double**)malloc(sizeof(double*) * (BP+ENDD)); BP_N[0] = (double*)malloc(sizeof(double) * (BP+ENDD) * (BP+ENDD)); for(i=1; i<(BP+ENDD); i++) { BP_N[i] = BP_N[i-1] + (BP+ENDD); } temp_BP_N = (double**)malloc(sizeof(double*) * (BP+ENDD)); temp_BP_N[0] = (double*)malloc(sizeof(double) * (BP+ENDD) * (BP+ENDD)); for(i=1; i<(BP+ENDD); i++) { temp_BP_N[i] = temp_BP_N[i-1] + (BP+ENDD); } //...init datapoint .... bow shape BaseP_x[0] = 0.000; BaseP_x[1] = 0.200; BaseP_x[2] = 1.000; BaseP_x[3] = 1.500; BaseP_x[4] = 2.500; BaseP_x[5] = 3.100; BaseP_x[6] = 2.500; // BaseP_x[7] = 3.500; BaseP_y[0] = 0.000; BaseP_y[1] = 0.500; BaseP_y[2] = 0.700; BaseP_y[3] = 0.250; BaseP_y[4] = 0.000; BaseP_y[5] = 1.150; BaseP_y[6] = 1.330; // BaseP_y[7] = 1.700; //init End BP for(i=0;i<(BP+ENDD);i++) { End_BaseP_x[i] = End_BaseP_y[i] = 0.0; } End_BaseP_x[0] = BaseP_x[0]; End_BaseP_y[0] = BaseP_y[0]; End_BaseP_x[BP+ENDD-1] = BaseP_x[BP-1]; End_BaseP_y[BP+ENDD-1] = BaseP_y[BP-1]; for(i=ENDD;i<(BP+ENDD)-2;i++) { End_BaseP_x[i] = BaseP_x[i-ENDD/2]; End_BaseP_y[i] = BaseP_y[i-ENDD/2]; } for(i=0;i<BP;i++) { fprintf(BPxy, "%lf %lf\n", BaseP_x[i], BaseP_y[i]); } *BP_dests = 0.0; for(i=1;i<BP;i++) { cacu_BP_dests(BaseP_x[i], BaseP_x[i-1], BaseP_y[i], BaseP_y[i-1], BP_dests); } // D0 = Dn = *BP_dests * 0.0; End_BaseP_x[ENDD/2] = 0.000; End_BaseP_y[ENDD/2] = 10.000;//D0; End_BaseP_x[BP+ENDD-2] = -10.000; End_BaseP_y[BP+ENDD-2] = 0.000;//Dn; for(i=0;i<(BP+ENDD);i++) { // printf("%lf %lf\n", End_BaseP_x[i], End_BaseP_y[i]); } for(i=0;i<BP;i++) { if(i==0) { BP_sn[i] = 0.0; } else { cacu_BP_sn(BP_dests, BP_sn[i-1], BaseP_x[i], BaseP_x[i-1], BaseP_y[i], BaseP_y[i-1], &BP_sn[i]); } // printf("%lf\n", BP_sn[i]); } // create_Nonuni_Knot_Ver(BP, ORD, BP_sn, Nonuni_U); create_End_Nonuni_Knot_Ver(BP, ORD, BP_sn, End_Nonuni_U); for(i=0;i<VER_ARR;i++) { // printf("%lf\n", Nonuni_U[i]); } for(i=0;i<(VER_ARR+ENDD);i++) { // printf("%lf\n", End_Nonuni_U[i]); } /* for(i=0;i<BP;i++) { for(j=0;j<BP;j++) { BP_N[i][j] = 0.0; temp_BP_N[i][j] = 0.0; } } for(j=0;j<BP;j++) { spn = FindSpan(BP-1, ORD, BP_sn[j], Nonuni_U); BasisFuns(spn, BP_sn[j], ORD, Nonuni_U, N); for(i=0;i<=ORD;i++) { BP_N[j][spn-ORD+i] = N[i]; } } for(i=0;i<BP;i++) { for(j=0;j<BP;j++) { fprintf(test, "%lf ", BP_N[i][j]); } fprintf(test, "\n"); } */ for(i=0;i<(BP+ENDD);i++) { for(j=0;j<(BP+ENDD);j++) { BP_N[i][j] = 0.0; temp_BP_N[i][j] = 0.0; } } for(j=1;j<(BP+ENDD)-1;j++) { spn = FindSpan((BP+ENDD)-1, ORD, BP_sn[j-1], End_Nonuni_U); BasisFuns(spn, BP_sn[j-1], ORD, End_Nonuni_U, N); for(i=0;i<=ORD;i++) { BP_N[j][spn-ORD+i] = N[i]; } } for(j=1;j<(BP+ENDD)-1;j++) { if(j==(0+ENDD/2) || j==((BP+ENDD)-2)) { spn = FindSpan((BP+ENDD)-1, ORD, BP_sn[j-1], End_Nonuni_U); DersBasisFuns(spn, BP_sn[j-1], ORD, 1, End_Nonuni_U, nders); for(i=0;i<=ORD;i++) { BP_N[j][spn-ORD+i] = nders[1][i]; } } } BP_N[0][0] = BP_N[BP+ENDD-1][BP+ENDD-1]= 1.0; /* for(i=0;i<(BP+ENDD);i++) { for(j=0;j<(BP+ENDD);j++) { fprintf(test, "%lf ", BP_N[i][j]); } fprintf(test, "\n"); } */ ludcmp(BP_N, temp_BP_N, (BP+ENDD), pivot, &plusminusone); for(i=0;i<(BP+ENDD);i++) { rhs[i] = End_BaseP_x[i]; } lubksb(temp_BP_N, (BP+ENDD), pivot, rhs); for(i=0;i<(BP+ENDD);i++) { ksi[i] = rhs[i]; } for(i=0;i<(BP+ENDD);i++) { rhs[i] = End_BaseP_y[i]; } lubksb(temp_BP_N, (BP+ENDD), pivot, rhs); for(i=0;i<(BP+ENDD);i++) { eta[i] = rhs[i]; } for(i=0;i<(VER+ENDD);i++) { fprintf(CP, "%lf %lf\n", ksi[i], eta[i]); } create_Uni_Knot_Ver((VER+ENDD), ORD, U); maxu = (double)((VER+ENDD) - ORD); delu = maxu / (double)(Num-1); for(i=0;i<Num;i++) { u[i] = (double)i * delu; CurvePoint((VER+ENDD)-1, ORD, U, ksi, u[i], &x[i]); CurvePoint((VER+ENDD)-1, ORD, U, eta, u[i], &y[i]); fprintf(Bspline, "%lf %lf\n", x[i], y[i]); } for(k=0;k<2;k++) { for(i=0;i<Num;i++) { xdev[k][i] = 0.0; ydev[k][i] = 0.0; spn = FindSpan((VER+ENDD)-1, ORD, u[i], U); DersBasisFuns(spn, u[i], ORD, k+1, U, nders); for(j=0;j<=ORD;j++) { xdev[k][i] += nders[k+1][j] * ksi[spn-ORD+j]; ydev[k][i] += nders[k+1][j] * eta[spn-ORD+j]; } } } for(i=0;i<Num;i++) { fprintf(Bsplineslope, "zone t=\"Bsplineslope\"\n"); cacu_nx(xdev[0][i], ydev[0][i], &nx[i]); cacu_ny(xdev[0][i], ydev[0][i], &ny[i]); cacu_kslope(xdev[0][i], ydev[0][i], xdev[1][i], ydev[1][i], &kslope[i]); fprintf(Bsplineslope, "%lf %lf\n", x[i], y[i]); fprintf(Bsplineslope, "%lf %lf\n", x[i]+nx[i]*kslope[i]*rad, y[i]+ny[i]*kslope[i]*rad); } /* */ return 0; }
DBstatus GEevaluvnc( /*-------------- Argument declarations --------------------------------------*/ /* */ /* In: */ DBCurve *p_cur, /* Curve (ptr) */ DBSeg *p_seg, /* Curve segment (ptr) */ EVALC *p_evalc ) /* Curve coordinates & derivatives (ptr) */ /* Out: */ /* Data to p_evalc */ /*---------------------------------------------------------------------------*/ { /* Start of function */ /*!------------------------ Internal variables ------------------------------*/ bool ratseg; /* Flag for rational segment */ DBint status; /* Error code from called function */ DBint i; /* loop variable */ DBVector r; /* Position (non-offset) */ DBVector drdu; /* First derivative with respect to u */ DBVector d2rdu2; /* Second derivative with respect to u */ DBHvector w; /* Position, homogenus coordinates */ DBHvector dwdu; /* 1:st der.with respect to u, hom. coord. */ DBHvector d2wdu2; /* 2:nd der.with respect to u, hom. coord. */ DBshort degree; /* Nurbs degree */ DBint offs_p; /* offset in control points array */ DBint offs_u; /* offset in knots array */ DBHvector *P; /* Pointer to control points for curve */ DBfloat *U; /* Pointer to knots for curve */ DBfloat u; /* local parameter value */ DBfloat invHom; /* 1/w.w_gm) */ DBfloat invHomQuad; /* 1/((w.w_gm)*(w.w_gm)) */ DBfloat invHomCub; /* 1/((w.w_gm)*(w.w_gm)*(w.w_gm)) */ char errbuf[80]; /* String for error message fctn erpush */ DBfloat ders[3][MAX_NURBD]; /* basis values[der_no][index] */ DBint no_der; /* no off requested derivatives */ /*-------------------end-of-declarations-------------------------------------*/ /* *** Let flag for UV segment be true. */ if ( p_seg->typ == UV_NURB_SEG ) p_evalc->surpat = TRUE; else { sprintf(errbuf, "(not UV_NURB_SEG)%%varkon_seg_uveval"); return(varkon_erpush("SU2993",errbuf)); } /* *** Copy to local variables */ degree = p_seg -> nurbs_degree; offs_p = p_seg -> offset_cpts; offs_u = p_seg -> offset_knots; P = p_seg -> cpts_c; U = p_seg -> knots_c; u = p_evalc->t_local; /* *** Is the segment rational? */ ratseg = FALSE; for (i=0 ;i <= degree ; i++ ) { if (ABS((P + offs_p + i)->w_gm - 1.0) > COMPTOL) { ratseg = TRUE; break; } } /* *** Calculate basis values */ no_der = 2; status = DersBasisFuns (offs_u,u,degree,no_der,p_seg->knots_c,ders); /* *** Calculate position */ w.x_gm = w.y_gm = w.z_gm = w.w_gm = 0.0; for (i=0;i<=degree;i++) { w.x_gm = w.x_gm + (P + offs_p + i)->x_gm * ders[0][i]; w.y_gm = w.y_gm + (P + offs_p + i)->y_gm * ders[0][i]; w.w_gm = w.w_gm + (P + offs_p + i)->w_gm * ders[0][i]; } if (ratseg == TRUE) { invHom = 1.0 / w.w_gm; p_evalc -> u = r.x_gm = w.x_gm * invHom; p_evalc -> v = r.y_gm = w.y_gm * invHom; } else { w.w_gm = 1.0; p_evalc -> u = r.x_gm = w.x_gm; p_evalc -> v = r.y_gm = w.y_gm; } /* *** Calculate first derivative */ dwdu.x_gm = dwdu.y_gm = dwdu.z_gm = dwdu.w_gm = 0.0; for (i=0 ;i <= degree ;i++ ) { dwdu.x_gm = dwdu.x_gm + (P + offs_p + i)->x_gm * ders[1][i]; dwdu.y_gm = dwdu.y_gm + (P + offs_p + i)->y_gm * ders[1][i]; dwdu.w_gm = dwdu.w_gm + (P + offs_p + i)->w_gm * ders[1][i]; } if (ratseg == TRUE) { invHomQuad = invHom * invHom; drdu.x_gm = (w.w_gm * dwdu.x_gm - dwdu.w_gm * w.x_gm) * invHomQuad; drdu.y_gm = (w.w_gm * dwdu.y_gm - dwdu.w_gm * w.y_gm) * invHomQuad; } else { drdu.x_gm = dwdu.x_gm; drdu.y_gm = dwdu.y_gm; } p_evalc ->u_t = drdu.x_gm; p_evalc ->v_t = drdu.y_gm; /* *** Calculate second derivative */ if (degree > 1) { d2wdu2.x_gm=0.0; d2wdu2.y_gm=0.0; d2wdu2.w_gm=0.0; for (i=0 ;i <= degree ;i++ ) { d2wdu2.x_gm = d2wdu2.x_gm + (P + offs_p + i)->x_gm * ders[2][i]; d2wdu2.y_gm = d2wdu2.y_gm + (P + offs_p + i)->y_gm * ders[2][i]; d2wdu2.w_gm = d2wdu2.w_gm + (P + offs_p + i)->w_gm * ders[2][i]; } if (ratseg == TRUE) { invHomCub = invHomQuad * invHom; d2rdu2.x_gm = (w.w_gm * (w.w_gm * d2wdu2.x_gm - w.x_gm * d2wdu2.w_gm) + 2 * dwdu.w_gm * (w.x_gm * dwdu.w_gm - w.w_gm * dwdu.x_gm)) * invHomCub; d2rdu2.y_gm = (w.w_gm * (w.w_gm * d2wdu2.y_gm - w.y_gm * d2wdu2.w_gm) + 2 * dwdu.w_gm * (w.y_gm * dwdu.w_gm - w.w_gm * dwdu.y_gm)) * invHomCub; } else { d2rdu2.x_gm = d2wdu2.x_gm; d2rdu2.y_gm = d2wdu2.y_gm; } } else d2rdu2.x_gm = d2rdu2.y_gm = d2rdu2.z_gm = d2wdu2.w_gm = 0.0; p_evalc->u_t2 = d2rdu2.x_gm ; p_evalc->v_t2 = d2rdu2.y_gm ; return(SUCCED); } /* End of function */
main() { FILE *Bspline=fopen("Bspline.dat","wt"); FILE *Bsplineslope=fopen("Bsplineslope.dat","wt"); FILE *CP=fopen("CP.dat","wt"); FILE *BPxy=fopen("BPxy.dat","wt"); FILE *test=fopen("test.dat","wt"); int k, i, j, spn, *pivot; double *BaseP_x, *BaseP_y, angle, arc; double *BP_sn, *BP_dests, *BP_un, **BP_N, **temp_BP_N, *N, plusminusone; double *x, *y, *u, **xdev, **ydev; double *ksi, *eta, *rhs; double *U, *Nonuni_U; double maxu, delu, **nders; double *nx, *ny, *kslope; BaseP_x = (double*)malloc(sizeof(double) * BP); BaseP_y = (double*)malloc(sizeof(double) * BP); BP_sn = (double*)malloc(sizeof(double) * BP); BP_dests = (double*)malloc(sizeof(double)); BP_un = (double*)malloc(sizeof(double) * BP); N = (double*)malloc(sizeof(double) * (ORD+1)); U = (double*)malloc(sizeof(double) * VER_ARR); Nonuni_U = (double*)malloc(sizeof(double) * VER_ARR); pivot = (int*)malloc(sizeof(int) * VER); rhs = (double*)malloc(sizeof(double) * VER); ksi = (double*)malloc(sizeof(double) * VER); eta = (double*)malloc(sizeof(double) * VER); x = (double*)malloc(sizeof(double) * Num); y = (double*)malloc(sizeof(double) * Num); u = (double*)malloc(sizeof(double) * Num); nx = (double*)malloc(sizeof(double) * Num); ny = (double*)malloc(sizeof(double) * Num); kslope = (double*)malloc(sizeof(double) * Num); nders = (double**)malloc(sizeof(double*) * (ORD+1)); nders[0] = (double*)malloc(sizeof(double) * (ORD+1) * (ORD+1)); for(i=1; i<(ORD+1); i++) { nders[i] = nders[i-1] + (ORD+1); } xdev = (double**)malloc(sizeof(double*) * 2); xdev[0] = (double*)malloc(sizeof(double) * 2 * Num); for(i=1; i<2; i++) { xdev[i] = xdev[i-1] + Num; } ydev = (double**)malloc(sizeof(double*) * 2); ydev[0] = (double*)malloc(sizeof(double) * 2 * Num); for(i=1; i<2; i++) { ydev[i] = ydev[i-1] + Num; } BP_N = (double**)malloc(sizeof(double*) * BP); BP_N[0] = (double*)malloc(sizeof(double) * BP * BP); for(i=1; i<BP; i++) { BP_N[i] = BP_N[i-1] + BP; } temp_BP_N = (double**)malloc(sizeof(double*) * BP); temp_BP_N[0] = (double*)malloc(sizeof(double) * BP * BP); for(i=1; i<BP; i++) { temp_BP_N[i] = temp_BP_N[i-1] + BP; } //...init datapoint .... bow shape BaseP_x[0] = 0.000; BaseP_x[1] = 0.000; BaseP_x[2] = 0.000; BaseP_x[3] = 0.000; BaseP_x[4] = 1.000; BaseP_x[5] = 1.600; BaseP_x[6] = 2.000; BaseP_x[7] = 2.000; BaseP_x[8] = 2.000; BaseP_x[9] = 2.300; BaseP_x[10] = 2.700; BaseP_x[11] = 4.500; BaseP_x[12] = 5.000; BaseP_y[0] = 0.000; BaseP_y[1] = 0.300; BaseP_y[2] = 2.000; BaseP_y[3] = 2.300; BaseP_y[4] = 3.000; BaseP_y[5] = 3.000; BaseP_y[6] = 2.600; BaseP_y[7] = 2.300; BaseP_y[8] = 2.000; BaseP_y[9] = 1.800; BaseP_y[10] = 1.800; BaseP_y[11] = 1.800; BaseP_y[12] = 1.800; /* BaseP_x[0] = 0.000; BaseP_x[1] = 0.250; BaseP_x[2] = 1.500; BaseP_x[3] = 2.500; BaseP_x[4] = 4.000; BaseP_x[5] = 4.500; BaseP_x[6] = 4.000; BaseP_y[0] = 0.000; BaseP_y[1] = 1.000; BaseP_y[2] = 1.500; BaseP_y[3] = 0.500; BaseP_y[4] = 0.150; BaseP_y[5] = 2.000; BaseP_y[6] = 2.100; *//* BaseP_x[0] = 0.000; BaseP_x[1] = 3.037; BaseP_x[2] = 5.941; BaseP_x[3] = 7.769; BaseP_x[4] = 8.406; BaseP_x[5] = 8.948; BaseP_x[6] = 9.075; BaseP_x[7] = 8.789; BaseP_x[8] = 7.705; BaseP_x[9] = 5.941; BaseP_x[10] = 3.037; BaseP_x[11] = 0.000; // BaseP_x[12] = 0.000; BaseP_y[0] = 1.252; BaseP_y[1] = 2.340; BaseP_y[2] = 4.206; BaseP_y[3] = 6.000; BaseP_y[4] = 7.000; BaseP_y[5] = 8.000; BaseP_y[6] = 9.000; BaseP_y[7] = 10.000; BaseP_y[8] = 11.000; BaseP_y[9] = 11.198; BaseP_y[10] = 11.516; BaseP_y[11] = 11.947; // BaseP_y[12] = 12.300; // BaseP_x[0] = -4.000; BaseP_x[1] = 0.000; BaseP_x[2] = 3.037; BaseP_x[3] = 5.941; BaseP_x[4] = 7.769; BaseP_x[5] = 8.406; BaseP_x[6] = 8.948; BaseP_x[7] = 9.075; BaseP_x[8] = 8.789; BaseP_x[9] = 7.705; BaseP_x[10] = 5.941; BaseP_x[11] = 3.037; BaseP_x[12] = 0.000; BaseP_x[13] = 0.000; BaseP_x[14] = 0.034; BaseP_x[15] = 0.524; BaseP_x[16] = 1.267; BaseP_x[17] = 3.037; BaseP_x[18] = 5.941; BaseP_y[0] = 0.000; BaseP_y[1] = 1.252; BaseP_y[2] = 2.340; BaseP_y[3] = 4.206; BaseP_y[4] = 6.000; BaseP_y[5] = 7.000; BaseP_y[6] = 8.000; BaseP_y[7] = 9.000; BaseP_y[8] = 10.000; BaseP_y[9] = 11.000; BaseP_y[10] = 11.198; BaseP_y[11] = 11.516; BaseP_y[12] = 11.947; BaseP_y[13] = 12.300; BaseP_y[14] = 13.000; BaseP_y[15] = 14.500; BaseP_y[16] = 16.000; BaseP_y[17] = 18.640; BaseP_y[18] = 23.013; */ for(i=0;i<BP;i++) { fprintf(BPxy, "%lf %lf\n", BaseP_x[i], BaseP_y[i]); } // cylinder shape /* angle = 0.0; for(i=0;i<BP;i++) { ang_to_rad(&angle, &arc); BaseP_x[i] = 1.0 * cos(arc); BaseP_y[i] = 1.0 * sin(arc); angle += 360.0 / (BP-1); fprintf(BPxy, "%lf %lf\n", BaseP_x[i], BaseP_y[i]); } */ *BP_dests = 0.0; for(i=1;i<BP;i++) { cacu_BP_dests(BaseP_x[i], BaseP_x[i-1], BaseP_y[i], BaseP_y[i-1], BP_dests); } for(i=0;i<BP;i++) { if(i==0) { BP_sn[i] = 0.0; } else { cacu_BP_sn(BP_dests, BP_sn[i-1], BaseP_x[i], BaseP_x[i-1], BaseP_y[i], BaseP_y[i-1], &BP_sn[i]); } // printf("%lf\n", BP_sn[i]); } create_Nonuni_Knot_Ver(BP, ORD, BP_sn, Nonuni_U); // for(i=0;i<VER_ARR;i++) // { // printf("%lf\n", Nonuni_U[i]); // } for(i=0;i<BP;i++) { for(j=0;j<BP;j++) { BP_N[i][j] = 0.0; temp_BP_N[i][j] = 0.0; } } for(j=0;j<BP;j++) { spn = FindSpan(BP-1, ORD, BP_sn[j], Nonuni_U); BasisFuns(spn, BP_sn[j], ORD, Nonuni_U, N); for(i=0;i<=ORD;i++) { BP_N[j][spn-ORD+i] = N[i]; } } // for(i=0;i<BP;i++) // { // for(j=0;j<BP;j++) // { // fprintf(test, "%lf ", BP_N[i][j]); // } // fprintf(test, "\n"); // } ludcmp(BP_N, temp_BP_N, BP, pivot, &plusminusone); for(i = 0; i < BP; i++) { rhs[i] = BaseP_x[i]; } lubksb(temp_BP_N, BP, pivot, rhs); for(i=0;i<BP;i++) { ksi[i] = rhs[i]; } for(i = 0; i < BP; i++) { rhs[i] = BaseP_y[i]; } lubksb(temp_BP_N, BP, pivot, rhs); for(i=0;i<BP;i++) { eta[i] = rhs[i]; } for(i=0;i<VER;i++) { fprintf(CP, "%lf %lf\n", ksi[i], eta[i]); } create_Uni_Knot_Ver(VER, ORD, U); maxu = (double)(VER - ORD); delu = maxu / (double)(Num-1); for(i=0;i<Num;i++) { u[i] = (double)i * delu; CurvePoint(VER-1, ORD, U, ksi, u[i], &x[i]); CurvePoint(VER-1, ORD, U, eta, u[i], &y[i]); fprintf(Bspline, "%lf %lf\n", x[i], y[i]); } for(k=0;k<2;k++) { for(i=0;i<Num;i++) { xdev[k][i] = 0.0; ydev[k][i] = 0.0; spn = FindSpan(VER-1, ORD, u[i], U); DersBasisFuns(spn, u[i], ORD, k+1, U, nders); for(j=0;j<=ORD;j++) { xdev[k][i] += nders[k+1][j] * ksi[spn-ORD+j]; ydev[k][i] += nders[k+1][j] * eta[spn-ORD+j]; } } } for(i=0;i<Num;i++) { fprintf(Bsplineslope, "zone t=\"Bsplineslope\"\n"); cacu_nx(xdev[0][i], ydev[0][i], &nx[i]); cacu_ny(xdev[0][i], ydev[0][i], &ny[i]); cacu_kslope(xdev[0][i], ydev[0][i], xdev[1][i], ydev[1][i], &kslope[i]); fprintf(Bsplineslope, "%lf %lf\n", x[i], y[i]); fprintf(Bsplineslope, "%lf %lf\n", x[i]+nx[i]*kslope[i]*rad, y[i]+ny[i]*kslope[i]*rad); } /* */ return 0; }