This commit is contained in:
watrabi
2025-09-18 17:55:52 -04:00
commit 977f1ff4b8
15030 changed files with 17324420 additions and 0 deletions
+307
View File
@@ -0,0 +1,307 @@
#include "../sg.h"
// ROBLOX change
#if (SG_CURRENT_PLATFORM!=SG_PLATFORM_IOS)
sgFloat eps_d = 1.e-5, eps_n = 1.e-3; // if sgFloat = double
#else
sgFloat eps_d = 1.e-10, eps_n = 1.e-6; // if sgFloat = float
#endif
short isg(short r) {
if (r < 0) return -1;
if (r > 0) return 1;
return 0;
}
short sg(sgFloat r, sgFloat eps)
{
if (r < -eps) return -1;
if (r > eps) return 1;
return 0;
}
void d_minmax(sgFloat * b, short numb,
sgFloat * min, sgFloat * max)
{
register short i;
*min= 1.e35;
*max=-1.e35;
for ( i=0 ; i < numb ; i++ ) {
if ( *min > b[i] ) *min=b[i];
if ( *max < b[i] ) *max=b[i];
}
}
void dpoint_minmax(lpD_POINT b, short numb,
lpD_POINT min, lpD_POINT max)
{
register short i;
min->x= 1.e35;
min->y= 1.e35;
min->z= 1.e35;
max->x=-1.e35;
max->y=-1.e35;
max->z=-1.e35;
for ( i=0 ; i < numb ; i++ ) {
if ( min->x > b[i].x ) min->x=b[i].x;
if ( max->x < b[i].x ) max->x=b[i].x;
if ( min->y > b[i].y ) min->y=b[i].y;
if ( max->y < b[i].y ) max->y=b[i].y;
if ( min->z > b[i].z ) min->z=b[i].z;
if ( max->z < b[i].z ) max->z=b[i].z;
}
}
BOOL dnormal_vector (lpD_POINT v)
{
sgFloat cs;
cs = sqrt(v->x*v->x + v->y*v->y + v->z*v->z);
// if ( cs < eps_d/10000) {
if ( cs < MINsgFloat*1000) {
v->x = v->y = v->z = 0.;
return FALSE;
}
v->x /= cs;
v->y /= cs;
v->z /= cs;
return TRUE;
}
BOOL dnormal_vector1 (lpD_POINT v)
{
sgFloat cs;
cs = sqrt(v->x*v->x + v->y*v->y + v->z*v->z);
if ( cs < eps_d/10000) {
// if ( cs < MINsgFloat*1000) {
v->x = v->y = v->z = 0.;
return FALSE; //
}
v->x /= cs; //
v->y /= cs;
v->z /= cs;
return TRUE;
}
BOOL dpoint_eq(lpD_POINT p1, lpD_POINT p2, sgFloat eps)
{
if (fabs(p1->x - p2->x) > eps ) return FALSE;
if (fabs(p1->y - p2->y) > eps ) return FALSE;
if (fabs(p1->z - p2->z) > eps ) return FALSE;
return TRUE;
}
lpF_PLPOINT dpoint_to_plpoint(lpD_POINT p1, lpF_PLPOINT p2)
{
p2->x = (float)p1->x;
p2->y = (float)p1->y;
return p2;
}
lpD_POINT dpoint_inv(lpD_POINT p1, lpD_POINT p2)
{
p2->x = - p1->x;
p2->y = - p1->y;
p2->z = - p1->z;
return p2;
}
lpD_POINT dpoint_sub(lpD_POINT p1, lpD_POINT p2, lpD_POINT p3)
{
p3->x = p1->x - p2->x;
p3->y = p1->y - p2->y;
p3->z = p1->z - p2->z;
return p3;
}
lpD_POINT dpoint_add(lpD_POINT p1, lpD_POINT p2, lpD_POINT p3)
{
p3->x = p1->x + p2->x;
p3->y = p1->y + p2->y;
p3->z = p1->z + p2->z;
return p3;
}
lpD_POINT dpoint_parametr(lpD_POINT p1, lpD_POINT p2, sgFloat t, lpD_POINT p3)
{
p3->x = p1->x + (p2->x - p1->x)*t;
p3->y = p1->y + (p2->y - p1->y)*t;
p3->z = p1->z + (p2->z - p1->z)*t;
return p3;
}
sgFloat dpoint_distance(lpD_POINT p1, lpD_POINT p2)
{
sgFloat pr;
pr = sqrt((p1->x-p2->x)*(p1->x-p2->x)+
(p1->y-p2->y)*(p1->y-p2->y)+
(p1->z-p2->z)*(p1->z-p2->z));
return pr;
}
sgFloat dskalar_product(lpD_POINT v1, lpD_POINT v2)
{
sgFloat pr;
pr = v1->x * v2->x + v1->y * v2->y + v1->z * v2->z;
return pr;
}
lpD_POINT dvector_product(lpD_POINT v1, lpD_POINT v2, lpD_POINT v3)
{
D_POINT v;
v.x = v1->y * v2->z - v1->z * v2->y;
v.y = v1->z * v2->x - v1->x * v2->z;
v.z = v1->x * v2->y - v1->y * v2->x;
*v3 = v;
return v3;
}
BOOL fnormal_vector (lpF_POINT v)
{
float cs;
cs = (float)sqrt(v->x*v->x + v->y*v->y + v->z*v->z);
if ( cs < MINFLOAT*10) return FALSE; //
v->x /= cs; //
v->y /= cs;
v->z /= cs;
return TRUE;
}
float fskalar_product(lpF_POINT v1, lpF_POINT v2)
{
float pr;
pr = v1->x * v2->x + v1->y * v2->y + v1->z * v2->z;
return pr;
}
lpF_POINT fvector_product(lpF_POINT v1, lpF_POINT v2, lpF_POINT v3)
{
F_POINT v;
v.x = v1->y * v2->z - v1->z * v2->y;
v.y = v1->z * v2->x - v1->x * v2->z;
v.z = v1->x * v2->y - v1->y * v2->x;
*v3 = v;
return v3;
}
void define_eps(lpD_POINT min,lpD_POINT max)
{
sgFloat x;
x=fabs(min->x);
if (x < fabs(min->y)) x=fabs(min->y);
if (x < fabs(min->z)) x=fabs(min->z);
if (x < fabs(max->x)) x=fabs(max->x);
if (x < fabs(max->y)) x=fabs(max->y);
if (x < fabs(max->z)) x=fabs(max->z);
// ROBLOX change
#if (SG_CURRENT_PLATFORM!=SG_PLATFORM_IOS)
eps_d = x * 1.e-5; // if sgFloat = double
#else
eps_d = x * 1.e-5; // if sgFloat = float
#endif
}
BOOL dpoint_cplane(lpD_POINT p1, lpD_POINT p2, lpD_POINT p3,
lpD_POINT pr)
{
pr->x=(p2->y-p1->y)*(p3->z-p1->z)-(p2->z-p1->z)*(p3->y-p1->y);
pr->y=(p2->z-p1->z)*(p3->x-p1->x)-(p2->x-p1->x)*(p3->z-p1->z);
pr->z=(p2->x-p1->x)*(p3->y-p1->y)-(p2->y-p1->y)*(p3->x-p1->x);
if ( !dnormal_vector (pr)) return FALSE;
return TRUE;
}
float calc_body_angle(lpD_POINT p1, lpD_POINT p2, lpD_POINT p3,
lpD_POINT p4)
{
sgFloat cs,alfa,ip;
D_POINT r1,r2;
D_POINT f1; // ,
D_POINT f2; // ,
if ( !dpoint_cplane(p1, p2, p3, &f1)) return 0.;
if ( !dpoint_cplane(p3, p2, p4, &f2)) return 0.;
cs = dskalar_product(&f1, &f2);
if (cs <= eps_n - 1.) return 0;
if (cs >= 1. - eps_n) alfa = M_PI;
else {
alfa = acos(cs);
dpoint_sub(p3,p2,&r1); // r
if (!(dnormal_vector(&r1))) return 0; //
dvector_product(&f1, &f2, &r2); //
if (!(dnormal_vector(&r2))) return 0; //
ip = dskalar_product(&r1, &r2);
if (ip < 0.) alfa = M_PI - alfa;
else alfa = M_PI + alfa;
}
return (float)alfa;
}
void modify_limits_by_point(lpD_POINT p, lpD_POINT min, lpD_POINT max)
{
if (p->x < min->x) min->x = p->x;
if (p->y < min->y) min->y = p->y;
if (p->z < min->z) min->z = p->z;
if (p->x > max->x) max->x = p->x;
if (p->y > max->y) max->y = p->y;
if (p->z > max->z) max->z = p->z;
}
sgFloat round(sgFloat din, short precision)
{
sgFloat DEGREE, d;
DEGREE = pow(10.0, precision);
d = din * DEGREE + 0.5;
return floor(d)/DEGREE;
}
BOOL gauss_classic( sgFloat **A, sgFloat *y, int u ){
int i, j, k, l, n, m;
sgFloat s;
u--;
for(n=0; n<=u; n++){
for( k=-1, l=n; l<=u; l++ ){
if( fabs(A[l][n]) > eps_n ){
k=l;
break;
}
}
if( k == -1 ) return FALSE;
if( k != n ){
for( m=n; m<=u; m++ ) change_AB(&A[n][m], &A[k][m]);
change_AB(&y[n], &y[k]);
}
s=1./A[n][n];
for(j=u; j>=n; j-- ) A[n][j] *= s;
y[n] *= s;
for( i=k+1; i<=u; i++){
for( j=n+1; j<=u; j++) A[i][j] -= A[i][n]*A[n][j];
y[i] -= A[i][n]*y[n];
}
}
for( i=u; i>=0; i--)
for( k=i-1; k>=0; k-- ) if( fabs(A[k][i]) > eps_n ) y[k] -= A[k][i]*y[i];
return TRUE;
}
+487
View File
@@ -0,0 +1,487 @@
#include "../sg.h"
#define DIVIDE_BY_ZERO 1.e-35
BOOL o_trans_vector(lpMATR t,lpD_POINT base, lpD_POINT vector)
{
D_POINT pn;
sgFloat dist;
dpoint_add(base,vector,&pn);
dist = dpoint_distance(base, &pn);
if ( !o_hcncrd(t,base,base) ) return FALSE;
if ( !o_hcncrd(t,&pn,&pn) ) return FALSE;
if (dist < eps_d) {
memset(vector, 0, sizeof(D_POINT));
return TRUE;
}
dpoint_sub(&pn,base,&pn);
if (!dnormal_vector(&pn)) return FALSE;
dpoint_scal(&pn, dist, vector);
return TRUE;
}
BOOL o_hcncrd(lpMATR t,lpD_POINT v,lpD_POINT vp)
{
sgFloat vx, vy, vz;
vx = v->x; vy = v->y; vz = v->z;
vp->x = vx*t[0] + vy*t[1] + vz*t[2] + t[3];
vp->y = vx*t[4] + vy*t[5] + vz*t[6] + t[7];
vp->z = vx*t[8] + vy*t[9] + vz*t[10] + t[11];
return TRUE;
}
BOOL o_hcncrdf(lpMATR t,lpD_POINT v,lpF_POINT vp)
{
sgFloat vx, vy, vz;
vx = v->x; vy = v->y; vz = v->z;
vp->x = (float)(vx*t[0] + vy*t[1] + vz*t[2] + t[3]);
vp->y = (float)(vx*t[4] + vy*t[5] + vz*t[6] + t[7]);
vp->z = (float)(vx*t[8] + vy*t[9] + vz*t[10] + t[11]);
return TRUE;
}
BOOL o_hcncrd2(lpMATR t,lpD_POINT v,lpF_PLPOINT vp)
{
sgFloat vx, vy, vz;
vx = v->x; vy = v->y; vz = v->z;
vp->x = (float)(vx*t[0] + vy*t[1] + vz*t[2] + t[3]);
vp->y = (float)(vx*t[4] + vy*t[5] + vz*t[6] + t[7]);
return TRUE;
}
BOOL o_move_xyz(lpMATR matr, lpD_POINT a,lpD_POINT p)
{
sgFloat axp,azp;
MATR m;
o_hcunit(m);
if ( !o_hcrot_angle(a,&axp,&azp) ) return FALSE;
o_tdrot(m,-3,azp);
o_tdrot(m,-1,axp);
o_tdtran(m,p);
o_tdrot(m,-1,-axp);
o_tdrot(m,-3,-azp);
o_hcmult(matr,m);
return TRUE;
}
BOOL o_rotate_xyz(lpMATR matr,
lpD_POINT p,lpD_POINT a,
sgFloat alfa)
{
sgFloat axp,azp;
sgFloat m[16];
o_hcunit(m);
p->x = -p->x; p->y = -p->y; p->z = -p->z;
o_tdtran(m,p);
if ( !o_hcrot_angle(a,&axp,&azp)) return FALSE;
o_tdrot(m,-3,azp);
o_tdrot(m,-1,axp);
o_tdrot(m,-3,alfa);
o_tdrot(m,-1,-axp);
o_tdrot(m,-3,-azp);
p->x = -p->x; p->y = -p->y; p->z = -p->z;
o_tdtran(m,p);
o_hcmult(matr,m);
return TRUE;
}
BOOL o_get_param(lpMATR matr,
lpD_POINT p,
sgFloat *az1,sgFloat *ax,sgFloat *az2,
sgFloat *sx,sgFloat *sy,sgFloat *sz)
{
sgFloat m[16];
D_POINT pw,pwz;
memcpy(m,matr,sizeof(m));
pw.x = pw.y = pw.z = 0;
o_hcncrd(m,&pw,p);
pw.x = -p->x; pw.y = -p->y; pw.z = -p->z;
o_tdtran(m,&pw); /* */
pw.x = pw.y = 0; pw.z = 1;
o_hcncrd(m,&pw,&pwz);
if ( !o_hcrot_angle( &pwz, ax, az1)) return FALSE; /* 2 */
o_tdrot(m,-3,*az1);
o_tdrot(m,-1,*ax);
pw.x = 1; pw.y = 0; pw.z = 0;
o_hcncrd(m,&pw,&pwz);
*az2 = -atan2(pwz.y,pwz.x);
o_tdrot(m,-3,*az2);
pw.x = 1; pw.y = 0; pw.z = 0;
o_hcncrd(m,&pw,&pwz);
o_tdscal(m,1,pwz.x);
*sx = pwz.x;
pw.x = 0; pw.y = 1; pw.z = 0;
o_hcncrd(m,&pw,&pwz);
o_tdscal(m,2,pwz.y);
*sy = pwz.y;
pw.x = 0; pw.y = 0; pw.z = 1;
o_hcncrd(m,&pw,&pwz);
o_tdscal(m,3,pwz.z);
*sz = pwz.z;
return TRUE;
}
BOOL o_rot(lpD_POINT a,lpD_POINT c, sgFloat fi,
lpD_POINT b)
{
sgFloat cs,s;
/* B = [ C , A ] */
b->x = c->y*a->z - c->z*a->y;
b->y = c->z*a->x - c->x*a->z;
b->z = c->x*a->y - c->y*a->x;
if ( !dnormal_vector (b) ) return FALSE;
cs = cos(fi);
s = sin(fi);
/* B=COS(FI)*A+SIN(FI)*B */
b->x = cs*a->x + s*b->x;
b->y = cs*a->y + s*b->y;
b->z = cs*a->z + s*b->z;
return TRUE;
}
BOOL o_minv(lpMATR a,lpMATR ai)
{
sgFloat d, biga, hold;
short nk, kk, ki, k, kj;
short i, ij, ik, iz;
short j, ji, jk, jp, jq, jr;
short n = 4; //
short l[4], m[4]; // "n"
memcpy(ai,a,sizeof(sgFloat)*16);
//
d = 1.0;
nk = -n;
for (k = 0; k < n; k++) { // do 80 k=1,n
nk=nk+n;
l[k]=k;
m[k]=k;
kk=nk+k;
biga=ai[kk];
for (j = k; j < n; j++) { // do 20 j=k,n
iz=n*j;
for (i = k; i < n; i++) { // do 20 i=k,n
ij=iz+i;
if (fabs(biga) >= fabs(ai[ij])) continue;
biga=ai[ij];
l[k]=i;
m[k]=j;
}
} // 20 continue
//
j=l[k];
if (j > k) {
ki=k-n;
for (i = 0; i < n; i++) { // do 30 i=1,n
ki=ki+n;
hold=-ai[ki];
ji=ki-k+j;
ai[ki]=ai[ji];
ai[ji]=hold;
}
}
//
i=m[k];
if (i > k) {
jp=n*i;
for (j = 0; j < n; j++) { // do 40 j=1,n
jk=nk+j;
ji=jp+j;
hold=-ai[jk];
ai[jk]=ai[ji];
ai[ji]=hold;
}
}
// (
// biga)
if (fabs(biga) < DIVIDE_BY_ZERO) {
// stop ' '
return FALSE;
}
for (i = 0; i < n; i++) { // do 55 i=1,n
if (i == k) continue;
ik=nk+i;
ai[ik]=ai[ik]/(-biga);
} // 55 continue
//
for (i = 0; i < n; i++) { // do 65 i=1,n
ik=nk+i;
hold=ai[ik];
ij=i-n;
for (j = 0; j < n; j++) { // do 65 j=1,n
ij=ij+n;
if (i == k) continue;
if (j == k) continue;
kj=ij-i+k;
ai[ij]=hold*ai[kj]+ai[ij];
}
} // 65 continue
//
kj=k-n;
for (j = 0; j < n; j++) { // do 75 j=1,n
kj=kj+n;
if (j == k) continue;
ai[kj]=ai[kj]/biga;
} // 75 continue
//
d=d*biga;
//
ai[kk]=1.0/biga;
} // 80 continue
//
k=n-1;
while (1) {
k=k-1;
if (k < 0)
break;
i=l[k];
if (i > k) {
jq=n*k;
jr=n*i;
for (j = 0; j < n; j++) { // do 110 j=1,n
jk=jq+j;
hold=ai[jk];
ji=jr+j;
ai[jk]=-ai[ji];
ai[ji]=hold;
}
}
j=m[k];
if (j <= k) continue;
ki=k-n;
for (i = 0; i < n; i++) { // do 130 i=1,n
ki=ki+n;
hold=ai[ki];
ji=ki-k+j;
ai[ki]=-ai[ji];
ai[ji]=hold;
}
}
return TRUE;
}
BOOL o_hcrot1(lpMATR t,lpD_POINT p)
{
sgFloat ax,az;
if ( !o_hcrot_angle( p, &ax,&az) ) return FALSE;
o_tdrot(t,-3,az);
o_tdrot(t,-1,ax);
return TRUE;
}
BOOL o_hcrot_angle(lpD_POINT p,sgFloat * axp,sgFloat * azp)
{
D_POINT v = *p;
sgFloat d;
*azp = 0.; *axp = 0.;
if(!dnormal_vector(&v)) return FALSE;
if((d = hypot(v.x, v.y)) < eps_n) *azp = M_PI;
else *azp = -M_PI/2. - v_angle(v.x, v.y);
*axp = M_PI/2. - v_angle(-d, v.z);
return TRUE;
}
/*
BOOL o_hcrot_angle(lpD_POINT p,sgFloat * axp,sgFloat * azp)
{
sgFloat ax,az;
*axp=0.;
*azp=0.;
ax=sqrt(p->x*p->x+p->y*p->y);
if ( ax < eps_d ) ax=0.;
else ax=atan2(fabs(p->z),ax);
az=fabs(p->y);
if ( az < eps_d ) az=0.;
else az=atan2(fabs(p->x),az);
if( fabs(p->y) < eps_d ){
if( fabs(p->x) < eps_d ){
if( fabs(p->z) < eps_d ) return FALSE;
ax=M_PI/2;
az=M_PI; // 0.;
goto met;
}
else {
az=M_PI/2;
}
}
if( p->x <= 0. ) {
if( p->y <= 0. ) goto met;
if( p->x != 0. ) {
az=M_PI-az;
goto met;
}
else {
az=az+M_PI;
goto met;
}
}
if ( p->y < 0. ) az=-az;
else az=az+M_PI;
met:
if ( p->z < 0. ) ax=-ax;
*axp=ax - M_PI/2;
*azp=az;
return TRUE;
}
*/
void o_hcmult(lpMATR a, lpMATR b)
{
sgFloat c[4];
register short i,j,k;
sgFloat aw,bw;
for ( i=0 ; i < 4 ; i++ ) {
for ( j=0 ; j < 4 ; j++ ) {
c[j]=0;
for ( k=0 ; k < 4 ; k++ ) {
aw=a[i+k*4];
bw=b[k+j*4];
c[j]=c[j]+aw*bw;
}
}
for ( j=0 ; j < 4 ; j++ )
a[i+j*4]=c[j];
}
}
void o_tdrot(lpMATR t, int naxes, sgFloat alpha)
{
int i[] = {1,2,0,1};
int k, l, naxe;
sgFloat GFa[16];
naxe = abs(naxes);
if (naxes > 0 ) alpha = M_PI/180*alpha;
o_hcunit(GFa);
k = i[naxe-1];
l = i[naxe];
GFa[k+k*4] = cos(alpha);
GFa[l+l*4] = cos(alpha);
GFa[k+l*4] = sin(alpha);
GFa[l+k*4] = -sin(alpha);
o_hcmult(t,GFa);
}
void o_tdscal(lpMATR t, int naxis, sgFloat scale)
{
sgFloat GFa[16];
if (naxis == 4) scale = 1.0/scale;
o_hcunit(GFa);
GFa[5*naxis-5] = scale;
o_hcmult(t,GFa);
}
void o_scale( lpMATR t,sgFloat scale)
{
o_tdscal(t,1, scale);
o_tdscal(t,2, scale);
o_tdscal(t,3, scale);
}
void o_tdtran(lpMATR t,lpD_POINT v)
{
sgFloat GFa[16];
o_hcunit(GFa);
GFa[3] = v->x;
GFa[7] = v->y;
GFa[11] = v->z;
o_hcmult(t,GFa);
}
void o_hcunit(lpMATR matr)
{
memset(matr,0,sizeof(sgFloat)*16);
matr[0] = matr[5] = matr[10] = matr[15] = 1;
}
BOOL o_hcprsp(lpMATR matr,sgFloat h)
{
if ( fabs(h) < eps_d ) return FALSE;
matr[14] = -1/h;
return TRUE;
}
void f3d_gabar_project1(lpMATR matr, lpD_POINT min1, lpD_POINT max1,
lpD_POINT min2, lpD_POINT max2)
// (min2, max2),
// (min1, max1),
// matr ( )
{
D_POINT p, pmin, pmax;
short i;
o_hcncrd(matr, min1, &pmin);
pmax = pmin;
for(i = 1; i < 8; i++){
get_box_vertex(min1, max1, i, &p);
o_hcncrd(matr, &p, &p);
if(p.x < pmin.x) pmin.x = p.x;
if(p.y < pmin.y) pmin.y = p.y;
if(p.z < pmin.z) pmin.z = p.z;
if(p.x > pmax.x) pmax.x = p.x;
if(p.y > pmax.y) pmax.y = p.y;
if(p.z > pmax.z) pmax.z = p.z;
}
*min2 = pmin;
*max2 = pmax;
}
void get_box_vertex(lpD_POINT p1, lpD_POINT p2, short num, lpD_POINT v)
{ // 1---------5 |
v->x = (num & 4) ? p2->x : p1->x; // | | | |
v->y = (num & 2) ? p2->y : p1->y; // z | | |
v->z = (num & 1) ? p2->z : p1->z; // | 2-------|-6
}
/*BOOL o_view_init(lpMATR t,sgFloat r)
{
o_hcunit(t);
if ( fabs(r) < eps_d ) return FALSE;
t[14]=-1/r;
return TRUE;
}*/
/*BOOL o_view(lpMATR matr,lpD_POINT p)
{
o_hcrot1(matr,p);
if ( !o_hcprsp(matr,sqrt(p->x*p->x+p->y*p->y+p->z*p->z)) ) return FALSE;
return TRUE;
}*/
+535
View File
@@ -0,0 +1,535 @@
#include "../sg.h"
BOOL eq_line(lpD_POINT p1, lpD_POINT p2, sgFloat *a, sgFloat *b, sgFloat *c) {
sgFloat r;
*a = (p1->y - p2->y);
*b = (p2->x - p1->x);
r = hypot(*a, *b);
if (r < MINsgFloat*10) return FALSE;
*a /= r; *b /= r;
*c = - *a * p1->x - *b * p1->y;
return TRUE;
}
//
BOOL eq_pe_line(lpD_POINT p1, lpD_POINT p2, sgFloat *a, sgFloat *b, sgFloat *c) {
sgFloat w;
if(!eq_line(p1, p2, a, b, c)) return FALSE;
*c = ((*a)*(p1->y + p2->y) - (*b)*(p1->x + p2->x))/2.;
w = *a; *a = *b; *b = -w;
return TRUE;
}
//----------------------------------------------
//
short p_int_lines(sgFloat a1, sgFloat b1, sgFloat c1,
sgFloat a2, sgFloat b2, sgFloat c2,
lpD_POINT p) {
sgFloat d;
d = a1 * b2 - a2 * b1;
if (fabs(d) < eps_n * eps_n) return FALSE;
p->x = (- c1 * b2 + c2 * b1) / d;
p->y = (- a1 * c2 + a2 * c1) / d;
p->z = 0.;
return TRUE;
}
//-------------------------------------------------
BOOL normv(BOOL flag_3d, lpD_POINT v, lpD_POINT n)
{
sgFloat r, z = 0.;
if(flag_3d)
z = v->z;
if((r = sqrt(v->x*v->x + v->y*v->y + z*z)) < MINsgFloat*10){
n->x = n->y = n->z = 0.;
return FALSE;
}
n->x = v->x/r;
n->y = v->y/r;
n->z = z/r;
return TRUE;
}
//-------------------------------------------------------------
sgFloat v_angle(sgFloat x, sgFloat y)
{
sgFloat a;
if(fabs(x) < MINsgFloat*10 && fabs(y) < MINsgFloat*10)
return 0.;
a = atan2(y, x);
if(fabs(a) < eps_n) a = 0.;
else
while(a < 0.)
a += 2.*M_PI;
return a;
}
//----------------------------------------------------------
void min_max_2(sgFloat x1, sgFloat x2, sgFloat *mn, sgFloat *mx)
//
{
if(x1 > x2){
*mx = x1;
*mn = x2;
}
else{
*mx = x2;
*mn = x1;
}
}
//--------------------------------------------------------------------
sgFloat dist_p_l(lpD_POINT vl, lpD_POINT cl, lpD_POINT p, lpD_POINT pl)
{
sgFloat d;
d = - cl->x*p->x - cl->y*p->y - cl->z*p->z;
intersect_3d_pl(cl, d, vl, cl, pl);
return dpoint_distance(p, pl);
}
//----------------------------------------------------------------------
short intersect_3d_pl(lpD_POINT np, sgFloat dp, lpD_POINT vl, lpD_POINT cl,
lpD_POINT p)
{
sgFloat c, d;
c = np->x*cl->x + np->y*cl->y + np->z*cl->z;
d = np->x*vl->x + np->y*vl->y + np->z*vl->z + dp;
if(fabs(c) < eps_n){
if(fabs(d) < eps_d)
return 0;
return -1;
}
d = -d/c;
dpoint_add(vl, dpoint_scal(cl, d, p), p);
return 1;
}
//----------------------------------------------------
BOOL eq_plane(lpD_POINT p1, lpD_POINT p2, lpD_POINT p3,
lpD_POINT np, sgFloat *dp)
{
np->x = (p1->y - p2->y)*(p1->z - p3->z) - (p1->y - p3->y)*(p1->z - p2->z);
np->y = (p1->z - p2->z)*(p1->x - p3->x) - (p1->z - p3->z)*(p1->x - p2->x);
np->z = (p1->x - p2->x)*(p1->y - p3->y) - (p1->x - p3->x)*(p1->y - p2->y);
*dp = hypot(hypot(np->x, np->y), np->z);
if(*dp < MINsgFloat*10)
return FALSE;
dpoint_scal(np, 1./(*dp), np);
*dp = -p1->x*(np->x) - p1->y*(np->y) - p1->z*(np->z);
return TRUE;
}
//--------------------------------------------------
sgFloat dist_p_pl(lpD_POINT p, lpD_POINT n, sgFloat d)
// (p) - (n, d)
{
return n->x*p->x + n->y*p->y + n->z*p->z + d;
}
//--------------------------------------------------
sgFloat dcoef_pl(lpD_POINT p, lpD_POINT n)
{
return -(n->x*p->x + n->y*p->y + n->z*p->z);
}
//---------------------------
short best_crd_pln(lpD_POINT n)
{
sgFloat amn, a1;
short ret = 3;
if((a1 = fabs(n->x) + fabs(n->z)) < (amn = fabs(n->x) + fabs(n->y))){
amn = a1;
ret = 2;
}
if(fabs(n->y) + fabs(n->z) < amn)
ret = 1;
return ret;
}
short coll_tst(lpD_POINT v1, BOOL norm1,
lpD_POINT v2, BOOL norm2)
{
D_POINT w1, w2;
if(!norm1){
if(!normv(TRUE, v1, &w1))
return 1;
}
else
w1 = *v1;
if(!norm2){
if(!normv(TRUE, v2, &w2))
return 1;
}
else
w2 = *v2;
if(dpoint_eq(&w1, &w2, eps_n))
return 1;
if(dpoint_eq(&w1, dpoint_inv(&w2, &w2), eps_n))
return -1;
return 0;
}
sgFloat det3_3(sgFloat *a, sgFloat *b, sgFloat *c){
return a[0]*b[1]*c[2] + b[0]*c[1]*a[2] + c[0]*a[1]*b[2] -
c[0]*b[1]*a[2] - a[0]*c[1]*b[2] - b[0]*a[1]*c[2];
}
short qwadr_eq(sgFloat a, sgFloat b, sgFloat c, sgFloat* x){
// a*x*x + b*x +c = 0
sgFloat d;
if(fabs(a) < eps_n){
if(fabs(b) < eps_d) return 0;
x[0] = -c/b;
return 1;
}
b /= a; c /= a;
if(fabs(d = (b*b)/4 - c) < eps_d*eps_d) d = 0.;
if(d < 0.) return 0;
x[0] = -b/2;
d = sqrt(d);
if(fabs(d) < eps_d) return 1;
x[1] = x[0] - d; x[0] = x[0] + d;
return 2;
}
sgFloat dpoint_distance_2d(lpD_POINT p1, lpD_POINT p2){
return hypot(p1->x - p2->x, p1->y - p2->y);
}
lpD_POINT dpoint_scal(lpD_POINT p1, sgFloat r, lpD_POINT p2){
p2->x = p1->x*r;
p2->y = p1->y*r;
p2->z = p1->z*r;
return p2;
}
sgFloat dist_point_to_segment(lpD_POINT p, lpD_POINT v1, lpD_POINT v2,
lpD_POINT p_min)
{
int i; //
sgFloat f1, f2;
D_POINT n; //
D_POINT pp_min;
DA_POINT vn, vk, vp;
dpoint_sub(v1, v2, &n); //
if ( !dnormal_vector(&n) ) { //
*p_min = *v1;
return ( dpoint_distance(v1, p) );
}
f1 = dist_p_l( v1, &n, p, &pp_min); //
i = best_crd_pln(&n) - 1;
memcpy(&vn,v1,sizeof(vn));
memcpy(&vk,v2,sizeof(vk));
if ( vn[i] > vk[i]) {
memcpy(&vn,v2,sizeof(vn));
memcpy(&vk,v1,sizeof(vk));
}
memcpy(&vp,&pp_min,sizeof(vp));
if ( vp[i] >= vn[i] && vp[i] <= vk[i] ) { //
*p_min = pp_min;
return ( f1 );
} else { //
f1 = dpoint_distance(v1, p);
f2 = dpoint_distance(v2, p);
if ( f1 > f2 ) { *p_min = *v2; return f2; }
else { *p_min = *v1; return f1; }
}
}
sgFloat floor_crd_par(sgFloat crd, sgFloat step){
short sign = 1;
if(crd < 0.) {
crd = -crd;
sign = -1;
}
return sign*floor(crd/step + 0.5)*step;
}
#define MAX_FAF 4
static char faf_num;
static char faf_type[MAX_FAF];
static D_PLPOINT faf_p[MAX_FAF];
void faf_init(void){
//
faf_num = 0;
}
void faf_set(short type, sgFloat x, sgFloat y){
faf_p[faf_num].x = x;
faf_p[faf_num].y = y;
faf_type[faf_num++] = (BYTE)type;
}
void faf_point(lpD_POINT p1, lpD_POINT p2){
short num = faf_num - 1;
sgFloat d;
*p2 = *p1;
if(faf_num){
switch(faf_type[num]){
case FAF_MOVE:
p2->x = p1->x + faf_p[num].x;
p2->y = p1->y + faf_p[num].y;
break;
case FAF_ROTATE:
d = p1->x*faf_p[num].y - p1->y*faf_p[num].x;
p2->y = p1->x*faf_p[num].x + p1->y*faf_p[num].y;
p2->x = d;
}
}
return;
}
void faf_line(lpD_POINT p1, lpD_POINT p2){
short num = faf_num - 1;
sgFloat d;
*p2 = *p1;
if(faf_num){
switch(faf_type[num]){
case FAF_MOVE:
p2->x = p1->x;
p2->y = p1->y;
p2->z = p1->z - p1->x*faf_p[num].x - p1->y*faf_p[num].y;
break;
case FAF_ROTATE:
d = p1->x*faf_p[num].y - p1->y*faf_p[num].x;
p2->y = p1->x*faf_p[num].x + p1->y*faf_p[num].y;
p2->x = d;
d = hypot(p2->x, p2->y);
p2->x /= d;
p2->y /= d;
p2->z = p1->z/d;
}
}
return;
}
void faf_inv(lpD_POINT p1, lpD_POINT p2){
short num = faf_num;
sgFloat d;
*p2 = *p1;
if(faf_num){
do{
switch(faf_type[--num]){
case FAF_MOVE:
p2->x = p2->x - faf_p[num].x;
p2->y = p2->y - faf_p[num].y;
break;
case FAF_ROTATE:
d = p2->x*faf_p[num].y + p2->y*faf_p[num].x;
p2->y = -p2->x*faf_p[num].x + p2->y*faf_p[num].y;
p2->x = d;
}
}while (num);
}
return;
}
void faf_exe(lpD_POINT p1, lpD_POINT p2){
short i;
sgFloat d;
*p2 = *p1;
for(i = 0; i < faf_num; i++){
switch(faf_type[i]){
case FAF_MOVE:
p2->x = p2->x + faf_p[i].x;
p2->y = p2->y + faf_p[i].y;
break;
case FAF_ROTATE:
d = p2->x*faf_p[i].y - p2->y*faf_p[i].x;
p2->y = p2->x*faf_p[i].x + p2->y*faf_p[i].y;
p2->x = d;
}
}
return;
}
sgFloat get_point_par(lpD_POINT pb, lpD_POINT pe, lpD_POINT p)
{
sgFloat lx, ly, a;
lx = pe->x - pb->x;
ly = pe->y - pb->y;
if(fabs(lx) > fabs(ly)){
if(fabs(lx) < eps_d) return 0.;
a = (p->x - pb->x)/lx;
}
else{
if(fabs(ly) < eps_d) return 0.;
a = (p->y - pb->y)/ly;
}
return a;
}
sgFloat get_point_par_3d(lpD_POINT pb, lpD_POINT pe, lpD_POINT p)
{
sgFloat lx, ly, lz, a;
lx = pe->x - pb->x;
ly = pe->y - pb->y;
lz = pe->z - pb->z;
if ( fabs(lx) > fabs(ly) ) {
if ( fabs(lx) > fabs(lz) ) {
if ( fabs(lx) < eps_d ) return 0.;
a = (p->x - pb->x)/lx;
} else {
if ( fabs(lz) < eps_d ) return 0.;
a = (p->z - pb->z)/lz;
}
} else {
if ( fabs(ly) > fabs(lz) ) {
if ( fabs(ly) < eps_d ) return 0.;
a = (p->y - pb->y)/ly;
} else {
if ( fabs(lz) < eps_d ) return 0.;
a = (p->z - pb->z)/lz;
}
}
return a;
}
BOOL get_point_proection(lpD_POINT pb, lpD_POINT pe, lpD_POINT p,
lpD_POINT pp)
{
sgFloat a, b, c, c1;
if(!eq_line(pb, pe, &a, &b, &c))
return FALSE;
c1 = -(p->x*(-b) + p->y*a);
if(!p_int_lines(a, b, c, -b, a, c1, pp))
return FALSE;
return TRUE;
}
BOOL correct_line_tails(lpD_POINT p1, lpD_POINT p2, sgFloat h1, sgFloat h2)
{
sgFloat l, a1, a2;
D_POINT wp1, wp2;
l = dpoint_distance(p1, p2);
if (l < eps_d) return FALSE;
a1 = h1/l;
a2 = h2/l + 1;
if((a2 - a1) < eps_n) return FALSE;
dpoint_parametr(p1, p2, a1, &wp1);
dpoint_parametr(p1, p2, a2, &wp2);
*p1 = wp1;
*p2 = wp2;
return TRUE;
}
sgFloat z_poly(sgFloat x, int degree, sgFloat* coeffs)
// poly Borlnda
{
int i = 1;
sgFloat num;
if(degree < 0)
return 0.;
num = coeffs[0];
while(i <= degree){
num += pow(x, i)*coeffs[i];
i++;
}
return num;
}
bool Is2DPointInside2DPolygon(const SG_POINT *polygon,int N, const SG_POINT& p)
{
int counter = 0;
int i;
sgFloat xinters;
SG_POINT p1,p2;
p1 = polygon[0];
for (i=1;i<=N;i++)
{
p2 = polygon[i % N];
if (p.y > min(p1.y,p2.y))
{
if (p.y <= max(p1.y,p2.y))
{
if (p.x <= max(p1.x,p2.x))
{
if (fabs(p1.y-p2.y)>eps_d)
{
xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
if (fabs(p1.x-p2.x)<eps_d || p.x <= xinters)
counter++;
}
}
}
}
p1 = p2;
}
if (counter % 2 == 0)
return false;
else
return true;
}
bool CalcPointOf3PlanesInter(lpD_PLANE pPln1, lpD_PLANE pPln2, lpD_PLANE pPln3, lpD_POINT pPnt)
{
sgFloat a[3], b[3], c[3], d[3], det;
D_POINT Pnt;
a[0] = pPln1->v.x; a[1] = pPln2->v.x; a[2] = pPln3->v.x;
b[0] = pPln1->v.y; b[1] = pPln2->v.y; b[2] = pPln3->v.y;
c[0] = pPln1->v.z; c[1] = pPln2->v.z; c[2] = pPln3->v.z;
d[0] = pPln1->d; d[1] = pPln2->d; d[2] = pPln3->d;
det = det3_3(a, b, c);
if(fabs(det) < eps_n)
return false;
Pnt.x = -det3_3(d, b, c)/det;
Pnt.y = -det3_3(a, d, c)/det;
Pnt.z = -det3_3(a, b, d)/det;
*pPnt = Pnt;
return true;
}
bool CalcAxisOfPlanesInter(lpD_PLANE pPln1, lpD_PLANE pPln2, pD_AXIS pAx)
{
D_AXIS Ax;
D_PLANE Pln;
dvector_product(&pPln1->v, &pPln2->v, &Ax.v);
if(!normv(TRUE, &Ax.v, &Ax.v))
return false;
Pln.v = Ax.v; Pln.d = 0.;
if(!CalcPointOf3PlanesInter(pPln1, pPln2, &Pln, &Ax.p))
return false;
*pAx = Ax;
return true;
}
+637
View File
@@ -0,0 +1,637 @@
#include "../sg.h"
char rus_up[] = "";
char rus_dn[] = "";
static short z_charint(char c);
static void compress_sgFloat_gtext(char *txt, char *buf, char f);
static void compress_sgFloat_ftext(char *txt, char *buf,
BOOL delspace, BOOL delnull);
static unsigned char ANSI2OEM_Nice[256] = {
// 0 1 2 3 4 5 6 7
// ==============================================
0, 1, 2, 3, 4, 5, 6, 7, // 0
8, 9, 10, 11, 12, 13, 14, 15, // 8
16, 17, 18, 19, 20, 21, 22, 23, // 16
24, 25, 26, 27, 28, 29, 30, 31, // 24
32, 33, 34, 35, 36, 37, 38, 39, // 32
40, 41, 42, 43, 44, 45, 46, 47, // 40
48, 49, 50, 51, 52, 53, 54, 55, // 48
56, 57, 58, 59, 60, 61, 62, 63, // 56
64, 65, 66, 67, 68, 69, 70, 71, // 64
72, 73, 74, 75, 76, 77, 78, 79, // 72
80, 81, 82, 83, 84, 85, 86, 87, // 80
88, 89, 90, 91, 92, 93, 94, 95, // 88
96, 97, 98, 99, 100, 101, 102, 103, // 96
104, 105, 106, 107, 108, 109, 110, 111, // 104
112, 113, 114, 115, 116, 117, 118, 119, // 112
120, 121, 122, 123, 124, 125, 126, 127, // 120
219, 254, 254, 254, 254, 254, 254, 254, // 128
254, 254, 254, 254, 254, 254, 254, 254, // 136
254, 254, 254, 254, 254, 176, 249, 254, // 144
254, 253, 254, 254, 254, 254, 254, 254, // 152
254, 246, 247, 254, 254, 254, 254, 254, // 160
240, 254, 244, 254, 251, 254, 254, 242, // 168
248, 254, 254, 254, 254, 254, 254, 250, // 176
241, 252, 245, 254, 254, 254, 255, 243, // 184
128, 129, 130, 131, 132, 133, 134, 135, // 192
136, 137, 138, 139, 140, 141, 142, 143, // 200
144, 145, 146, 147, 148, 149, 150, 151, // 208
152, 153, 154, 155, 156, 157, 158, 159, // 216
160, 161, 162, 163, 164, 165, 166, 167, // 224
168, 169, 170, 171, 172, 173, 174, 175, // 232
224, 225, 226, 227, 228, 229, 230, 231, // 240
232, 233, 234, 235, 236, 237, 238, 239 // 248
};
unsigned char OEM2ANSI_Nice[256] = {
// 0 1 2 3 4 5 6 7
// ==============================================
0, 1, 2, 3, 4, 5, 6, 7, // 0
8, 9, 10, 11, 12, 13, 14, 15, // 8
16, 17, 18, 19, 20, 21, 22, 23, // 16
24, 25, 26, 27, 28, 29, 30, 31, // 24
32, 33, 34, 35, 36, 37, 38, 39, // 32
40, 41, 42, 43, 44, 45, 46, 47, // 40
48, 49, 50, 51, 52, 53, 54, 55, // 48
56, 57, 58, 59, 60, 61, 62, 63, // 56
64, 65, 66, 67, 68, 69, 70, 71, // 64
72, 73, 74, 75, 76, 77, 78, 79, // 72
80, 81, 82, 83, 84, 85, 86, 87, // 80
88, 89, 90, 91, 92, 93, 94, 95, // 88
96, 97, 98, 99, 100, 101, 102, 103, // 96
104, 105, 106, 107, 108, 109, 110, 111, // 104
112, 113, 114, 115, 116, 117, 118, 119, // 112
120, 121, 122, 123, 124, 125, 126, 127, // 120
192, 193, 194, 195, 196, 197, 198, 199, // 128
200, 201, 202, 203, 204, 205, 206, 207, // 136
208, 209, 210, 211, 212, 213, 214, 215, // 144
216, 217, 218, 219, 220, 221, 222, 223, // 152
224, 225, 226, 227, 228, 229, 230, 231, // 160
232, 233, 234, 235, 236, 237, 238, 239, // 168
149, 149, 149, 124, 43, 43, 43, 43, // 176
43, 43, 124, 43, 43, 43, 43, 43, // 184
43, 43, 43, 43, 45, 43, 43, 43, // 192
43, 43, 43, 43, 43, 45, 43, 43, // 200
43, 43, 43, 43, 43, 43, 43, 43, // 208
43, 43, 43, 128, 128, 128, 128, 128, // 216
240, 241, 242, 243, 244, 245, 246, 247, // 224
248, 249, 250, 251, 252, 253, 254, 255, // 232
168, 184, 175, 191, 170, 186, 161, 162, // 240
176, 150, 183, 172, 185, 153, 182, 190 // 248
};
//
char z_tolower(char c){
char* d;
if(c && (d = strchr(rus_up, c)) != NULL)
return rus_dn[(short)(d - rus_up)];
if(isascii(c))if(isupper(c))
return (BYTE)(_tolower(c));
return c;
}
char z_toupper(char c){
char* d;
if(c && (d = strchr(rus_dn, c)) != NULL)
return rus_up[(short)(d - rus_dn)];
if(isascii(c))if(islower(c))
return (BYTE)(_toupper(c));
return c;
}
BOOL z_isupper(char c){
if(c && strchr(rus_up, c) != NULL) return TRUE;
if(isascii(c))if(isupper(c)) return TRUE;
return FALSE;
}
BOOL z_islower(char c){
if(c && strchr(rus_dn, c) != NULL) return TRUE;
if(isascii(c))if(islower(c)) return TRUE;
return FALSE;
}
short z_charicmp(char c1, char c2){
return z_charint(z_tolower(c1)) - z_charint(z_tolower(c2));
}
short z_stricmp(char *s1, char *s2){
short i;
while(!(i = z_charicmp(*s1, *s2)) && (*s1 || *s2)){
s1++;
s2++;
}
return i;
}
BOOL z_isalpha(char c)
{
if(isalpha(c)) return TRUE;
if(!c) return FALSE;
if(strchr(rus_up, c)) return TRUE;
if(strchr(rus_dn, c)) return TRUE;
return FALSE;
}
BOOL z_isalnum(char c)
{
if(isdigit(c)) return TRUE;
return z_isalpha(c);
}
BOOL z_isalpha_id(char c)
{
return z_isalpha_ext(c, ID_ALFA_EXT);
}
BOOL z_isalnum_id(char c)
{
return z_isalnum_ext(c, ID_ALFA_EXT);
}
BOOL z_isalpha_ext(char c, char *ext)
{
if(z_isalpha(c)) return TRUE;
if(c && strchr(ext, c)) return TRUE;
return FALSE;
}
BOOL z_isalnum_ext(char c, char *ext)
{
if(isdigit(c)) return TRUE;
return z_isalpha_ext(c, ext);
}
char* z_trim_space(char *txt){
char *inp;
short len;
inp = txt;
while (*inp == ' ' || *inp == '\t') inp++;
len = strlen(inp);
memcpy(txt, inp, len + 1);
while (--len >= 0)
if(txt[len] != ' ' && txt[len] != '\t') break;
txt[len + 1] = 0;
return txt;
}
BOOL z_text_to_long(char *txtnum, long *num, short *errcode){
sgFloat wnum;
if(!z_text_to_sgFloat(txtnum, &wnum, errcode)) return FALSE;
if(wnum != floor(wnum))
{*errcode = 2; return FALSE;}
if(fabs(wnum) > (sgFloat)(MAXLONG))
{*errcode = 3; return FALSE;}
*num = (long)wnum;
return TRUE;
}
BOOL z_text_to_int(char *txtnum, int *num, short *errcode){
long lnum;
BOOL ret;
ret = z_text_to_long(txtnum, &lnum, errcode);
if(ret)
*num = (int)lnum;
return ret;
}
BOOL z_text_to_short(char *txtnum, short *num, short *errcode){
sgFloat wnum;
if(!z_text_to_sgFloat(txtnum, &wnum, errcode)) return FALSE;
if(wnum != floor(wnum))
{*errcode = 2; return FALSE;}
if(fabs(wnum) > (sgFloat)(MAXSHORT))
{*errcode = 3; return FALSE;}
*num = (short)wnum;
return TRUE;
}
BOOL z_text_to_sgFloat(char *txtnum, sgFloat *num, short *errcode){
char *inp;
sgFloat wnum;
inp = txtnum;
while (*inp == ' ' || *inp == 9) inp++;
if(!(*inp)){ *errcode = 0; return FALSE;}
if(0 ==(inp = z_atof(inp, &wnum))) { *errcode = 1; return FALSE;}
while (*inp == ' ' || *inp == 9) inp++;
if(*inp) {*errcode = 1; return FALSE;}
*num = wnum;
return TRUE;
}
char* z_atof(char *txtnum, sgFloat *num)
{
BOOL flagd = FALSE;
BOOL flagdp = FALSE;
BOOL flagnonul = FALSE;
BOOL flagp = FALSE;
BOOL flagpoint = FALSE;
char* inp;
char ch;
sgFloat wnum;
inp = txtnum;
if(*inp == '+' || *inp == '-') inp++;
for( ; ; inp++){
if(*inp <= '9' && *inp >= '0'){
if(!flagp){
flagd = TRUE;
if(*inp != '0') flagnonul = TRUE;
}
else flagdp = TRUE;
continue;
}
if(*inp == '.'){
if(flagpoint) return NULL;
else {
flagpoint = TRUE;
continue;
}
}
if(flagp) break;
if(*inp == 'e' || *inp == 'E'){
flagp = TRUE;
inp++;
if(!(*inp == '+') && !(*inp == '-')) inp--;
continue;
}
break;
}
if(inp == txtnum || !flagd) return NULL; //
if(flagp && !flagdp) return NULL; //
ch = *inp; *inp = 0; wnum = atof(txtnum); *inp = ch;
if(wnum == 0. && flagnonul) return NULL; // atof
*num = wnum;
return inp;
}
char *sgFloat_output(sgFloat num, int size, int precision, BOOL delspace,
BOOL upper, char *txt)
{
return sgFloat_output1(num, size, precision, delspace, TRUE, upper, txt);
}
char *sgFloat_output1(sgFloat num, int size, int precision,
BOOL delspace, BOOL delnull, BOOL upper, char *txt)
{
int lp = 1, s, p;
char eformat[] = {"%-.*lE"};
char fformat[] = {"%*.*lf"};
char buf[MAX_sgFloat_STRING + 5];
BOOL eflag = FALSE;
eformat[5] = (BYTE)((upper) ? 'E' : 'e');
if(size <= 0){
delspace = TRUE;
size = MAX_sgFloat_STRING - 1;
}
if(size > MAX_sgFloat_STRING - 1) size = MAX_sgFloat_STRING - 1;
if(precision < 0){ // "E"
precision = -precision;
eflag = TRUE;
}
s = size;
if(num != floor(num) || !delnull) s--; //
if(num < 0.) s--; // "-"; s =
p = (fabs(num) > 0.) ? (short)(log10(fabs(num))) : 0; //
if(abs(p) > 10) lp++; if(abs(p) > 100) lp++; //
if(precision > MAX_sgFloat_DIGITS) precision = MAX_sgFloat_DIGITS;
if(eflag) goto met_e;
if(p < 0) p = 0;
if(++p <= s) { // "F"
p = s - p;
if(p > precision) p = precision;
sprintf(buf, fformat, size, p , num);
compress_sgFloat_ftext(buf, txt, delspace, delnull);
return txt;
}
met_e: // "E"
p = s - lp - 3; // E+123
if(p > precision) p = precision;
while(TRUE){ //
if(p <= 0){ //
memset(txt, '*', size);
txt[size] = 0;
return txt;
}
sprintf(buf, eformat, p, num);
compress_sgFloat_gtext(buf, txt, eformat[5]);
lp = strlen(txt);
if(lp <= size) break;
p--;
}
if(!delspace){
while(lp < size) txt[lp++] = ' ';
txt[lp] = 0;
}
return txt;
}
static void compress_sgFloat_gtext(char *txt, char *buf, char f)
{
char *t, *e;
e = strchr(txt, f);
if(e) *e = 0;
if(strchr(txt, '.')) { // -
t = txt + strlen(txt);
while(*(--t) == '0');
if(*t != '.') t++;
*t = 0;
}
t = txt;
if(!strcmp(txt, "-0")) t++;
strcpy(buf, t);
if(e){
*e = f; t = e + 1;
if (*t == '+') strcpy(t, t + 1);
else if(*t == '-') t++;
while(*t == '0') strcpy(t, t + 1); //
if(*t) strcat(buf, e);
}
}
static void compress_sgFloat_ftext(char *txt, char *buf,
BOOL delspace, BOOL delnull)
{
char s, *b, *t;
b = txt;
while(*b == ' ') b++;
t = txt + strlen(txt);
if(strchr(txt, '.') && delnull){// -
while(*(--t) == '0');
if(*t != '.') t++;
}
s = *t; *t = 0;
if(!strcmp(b, "-0")){
if(delspace) b++;
else *b = ' ';
}
if(!delspace){
b = txt;
*t = s;
while(*t) *(t++) = ' ';
}
strcpy(buf, b);
}
static short z_charint(char c){
short i;
i = (UCHAR)c;
return i;
}
void z_str_decompress(char *strin, char *strout, short size, BOOL delbspace)
{
short lenstr, lspace, nspace, lwst, nadd, i, j;
char c, *s, *sb, *se, *sout;
memset(strout, ' ', size);
strout[size] = 0;
sb = strin;
while(*sb == ' ') sb++; //
lenstr = strlen(sb);
if(!lenstr) return;
se = sb + (lenstr - 1);
while(*se == ' ') se--; //
se++; c = *se; *se = 0;
if(!delbspace){
i = (short)(sb - strin);
sout = strout + i;
size -= i;
}
else
sout = strout;
lenstr = strlen(sb);
if(lenstr > size) { //
strncpy(sout, sb, size);
goto ret;
}
if(!(lspace = size - lenstr)) goto met; //
s = sb; nspace = 0;
while((s = strchr(s, ' ')) != NULL){ //
nspace++; //
while(*s == ' ') s++;
}
if(nspace){
lwst = lspace/nspace; //
nadd = lspace - lwst*nspace; // nadd
s = sb; i = 0;
while(*s){
while((*s) && (*s != ' ')) { sout[i++] = *s; s++;}
if(!(*s)) break;
for(j = 0; j < lwst; j++) i++;
if(nadd >= nspace) i++;
while(*s == ' ') { i++; s++;}
nspace--;
}
return;
}
met:
strncpy(sout, sb, lenstr);
ret:
*se = c;
return;
}
int OemToAnsiBuffNice(LPSTR from, LPSTR to, UINT len)
{
int c;
UINT i;
for (i = 0; i < len; i++)
{
c = *from++;
if (c < 0)
c += 256;
*to++ = OEM2ANSI_Nice[c];
}
return -1;
}
void z_OemToAnsi(char *oemstr, char *ansistr, ULONG len)
{
//nb+
if (len)
OemToAnsiBuffNice(oemstr, ansistr, len);
else
OemToAnsiBuffNice(oemstr, ansistr, strlen(oemstr));
//nb-
}
int AnsiToOemBuffNice(LPSTR from, LPSTR to, UINT len)
{
int c;
UINT i;
for (i = 0; i < len; i++)
{
c = *from++;
if (c < 0)
c += 256;
*to++ = ANSI2OEM_Nice[c];
}
return -1;
}
void z_AnsiToOem(char *ansistr, char *oemstr, ULONG len)
{
//nb+
if (len)
AnsiToOemBuffNice(ansistr, oemstr, len);
else
AnsiToOemBuffNice(ansistr, oemstr, strlen(oemstr));
//nb-
}
void z_str_to_str_constant(char *str, char *sc)
// sc str
{
*(sc++) = '\"';
while(*str){
if(*str == '\"' || *str == '\\')
*(sc++) = '\\';
*(sc++) = *(str++);
}
*(sc++) = '\"';
*sc = 0;
}
BOOL z_text_to_COLORREF(char *txtnum, COLORREF *num, short *errcode){
char *inp;
sgFloat wnum;
BYTE bnum[3] = {0, 0, 0};
short i;
inp = txtnum;
for (i = 0; i < 3; i++){
while (*inp == ' ' || *inp == 9) inp++;
if(!(*inp))break;
if(0 ==(inp = z_atof(inp, &wnum))) { *errcode = 1; return FALSE;}
if(wnum != floor(wnum))
{*errcode = 2; return FALSE;}
if(wnum > (sgFloat)(255) || wnum < 0)
{*errcode = 3; return FALSE;}
bnum[i] = (BYTE)wnum;
}
if(i == 0) {*errcode = 0; return FALSE;}
if(i == 3){
while (*inp == ' ' || *inp == 9) inp++;
if(*inp) {*errcode = 1; return FALSE;}
}
*num = RGB(bnum[0], bnum[1], bnum[2]);
return TRUE;
}
char *z_COLORREF_to_text(COLORREF num, char *txtnum){
if (!sprintf(txtnum, "%u %u %u", GetRValue(num),
GetGValue(num),
GetBValue(num)))
txtnum[0]= 0;
return txtnum;
}
BOOL z_GetFilePath(char* path, char* pathonly)
{
char fname[129];
short i, l, elen;
// if(GetFileTitle(path, fname, 128))
return FALSE;
l = strlen(fname);
if(!l)
return FALSE;
elen = 0;
for(i = l - 1; i >= 0; i--){
if(fname[i] == '.')
goto met1;
if(l - i > 3)
break;
}
//
l = strlen(path);
if(!l)
return FALSE;
for(i = l - 1; i >= 0; i--){
if(path[i] == '.'){
elen = l - i;
break;
}
if(l - i > 3)
break;
}
met1:
l = strlen(path) - strlen(fname) - elen;
if(l > 0)
strncpy(pathonly, path, l);
pathonly[l] = 0;
return TRUE;
}
BOOL z_GetFileTitle(char* path, char* title)
//
{
char pathonly[256];
if(!z_GetFilePath(path, pathonly))
return FALSE;
strcpy(title, &path[strlen(pathonly)]);
return TRUE;
}