예제 #1
0
파일: nv_algebra.cpp 프로젝트: 2asoft/xray
 nv_scalar ffast_cos(const nv_scalar x)
{
    // assert:  0 <= fT <= PI/2
    // maximum absolute error = 1.1880e-03
    // speedup = 2.14

    nv_scalar x_sqr = x*x;
    nv_scalar res = nv_scalar(3.705e-02);
    res *= x_sqr;
    res -= nv_scalar(4.967e-01);
    res *= x_sqr;
    res += nv_one;
    return res;
}
예제 #2
0
파일: nv_algebra.cpp 프로젝트: 2asoft/xray
vec3& cube_map_normal(int i, int x, int y, int cubesize, vec3& v)
{
    nv_scalar s, t, sc, tc;
    s = (nv_scalar(x) + nv_zero_5) / nv_scalar(cubesize);
    t = (nv_scalar(y) + nv_zero_5) / nv_scalar(cubesize);
    sc = s * nv_two - nv_one;
    tc = t * nv_two - nv_one;

    switch (i) 
    {
        case 0:
            v.x = nv_one;
            v.y = -tc;
            v.z = -sc;
            break;
        case 1:
            v.x = -nv_one;
            v.y = -tc;
            v.z = sc;
            break;
        case 2:
            v.x = sc;
            v.y = nv_one;
            v.z = tc;
            break;
        case 3:
            v.x = sc;
            v.y = -nv_one;
            v.z = -tc;
            break;
        case 4:
            v.x = sc;
            v.y = -tc;
            v.z = nv_one;
            break;
        case 5:
            v.x = -sc;
            v.y = -tc;
            v.z = -nv_one;
            break;
    }
    normalize(v);
    return v;
}
예제 #3
0
파일: nv_algebra.cpp 프로젝트: 2asoft/xray
 nv_scalar fast_cos(const nv_scalar x)
{
    // assert:  0 <= fT <= PI/2
    // maximum absolute error = 2.3082e-09
    // speedup = 1.47

    nv_scalar x_sqr = x*x;
    nv_scalar res = nv_scalar(-2.605e-07);
    res *= x_sqr;
    res += nv_scalar(2.47609e-05);
    res *= x_sqr;
    res -= nv_scalar(1.3888397e-03);
    res *= x_sqr;
    res += nv_scalar(4.16666418e-02);
    res *= x_sqr;
    res -= nv_scalar(4.999999963e-01);
    res *= x_sqr;
    res += nv_one;
    return res;
}
예제 #4
0
파일: nv_algebra.cpp 프로젝트: 2asoft/xray
// v is normalized
// theta in radians
void mat3::set_rot(const nv_scalar& theta, const vec3& v) 
{
    nv_scalar ct = nv_scalar(_cos(theta));
    nv_scalar st = nv_scalar(_sin(theta));

    nv_scalar xx = v.x * v.x;
    nv_scalar yy = v.y * v.y;
    nv_scalar zz = v.z * v.z;
    nv_scalar xy = v.x * v.y;
    nv_scalar xz = v.x * v.z;
    nv_scalar yz = v.y * v.z;

    a00 = xx + ct*(1-xx);
    a01 = xy + ct*(-xy) + st*-v.z;
    a02 = xz + ct*(-xz) + st*v.y;

    a10 = xy + ct*(-xy) + st*v.z;
    a11 = yy + ct*(1-yy);
    a12 = yz + ct*(-yz) + st*-v.x;

    a20 = xz + ct*(-xz) + st*-v.y;
    a21 = yz + ct*(-yz) + st*v.x;
    a22 = zz + ct*(1-zz);
}
예제 #5
0
파일: nv_algebra.cpp 프로젝트: 2asoft/xray
/*
 * Ok, simulate a track-ball.  Project the points onto the virtual
 * trackball, then figure out the axis of rotation, which is the cross
 * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
 * Note:  This is a deformed trackball-- is a trackball in the center,
 * but is deformed into a hyperbolic sheet of rotation away from the
 * center.  This particular function was chosen after trying out
 * several variations.
 *
 * It is assumed that the arguments to this routine are in the range
 * (-1.0 ... 1.0)
 */
quat & trackball(quat& q, vec2& pt1, vec2& pt2, nv_scalar trackballsize)
{
    vec3 a; // Axis of rotation
    nv_scalar phi;  // how much to rotate about axis
    vec3 d;
    nv_scalar t;

    if (pt1.x == pt2.x && pt1.y == pt2.y) 
    {
        // Zero rotation
        q = quat_id;
        return q;
    }

    // First, figure out z-coordinates for projection of P1 and P2 to
    // deformed sphere
    vec3 p1(pt1.x,pt1.y,tb_project_to_sphere(trackballsize,pt1.x,pt1.y));
    vec3 p2(pt2.x,pt2.y,tb_project_to_sphere(trackballsize,pt2.x,pt2.y));

    //  Now, we want the cross product of P1 and P2
    cross(a,p1,p2);

    //  Figure out how much to rotate around that axis.
    d.x = p1.x - p2.x;
    d.y = p1.y - p2.y;
    d.z = p1.z - p2.z;
    t = _sqrt(d.x * d.x + d.y * d.y + d.z * d.z) / (trackballsize);

    // Avoid problems with out-of-control values...

    if (t > nv_one)
        t = nv_one;
    if (t < -nv_one) 
        t = -nv_one;
    phi = nv_two * nv_scalar(asin(t));
    axis_to_quat(q,a,phi);
    return q;
}
예제 #6
0
vec3 & spect_decomp(vec3 & kv, mat3 & S, mat3 & U)
{
#define X 0
#define Y 1
#define Z 2
#define W 3

    vec3 Diag,OffD; // OffD is off-diag (by omitted index)
    nv_scalar g,h,fabsh,fabsOffDi,t,theta,c,s,tau,ta,OffDq,a,b;
    static char nxt[] = {Y,Z,X};

    U = mat3_id;
    Diag[X] = S(X,X); Diag[Y] = S(Y,Y); Diag[Z] = S(Z,Z);
    OffD[X] = S(Y,Z); OffD[Y] = S(Z,X); OffD[Z] = S(X,Y);
    for (int sweep=20; sweep>0; --sweep) 
    {
        nv_scalar sm = (fabs(OffD[X])+fabs(OffD[Y])+fabs(OffD[Z]));
        if (sm == nv_zero) 
            break;
        for (int i=Z; i>=X; --i) 
        {
            int p = nxt[i]; 
            int q = nxt[p];
            fabsOffDi = fabs(OffD[i]);
            g = nv_scalar(100.0)*fabsOffDi;
            if (fabsOffDi > nv_zero) 
            {
                h = Diag[q] - Diag[p];
                fabsh = fabs(h);
                if (fabsh+g==fabsh) 
                {
                    t = OffD[i]/h;
                } 
                else 
                {
                    theta = nv_zero_5*h/OffD[i];
                    t = nv_one/(fabs(theta)+sqrt(theta*theta+nv_one));
                    if (theta < nv_zero) 
                        t = -t;
                }
                c = nv_one/sqrt(t*t+nv_one); 
                s = t*c;
                tau = s/(c+nv_one);
                ta = t*OffD[i]; 
                OffD[i] = nv_zero;
                Diag[p] -= ta; 
                Diag[q] += ta;
                OffDq = OffD[q];
                OffD[q] -= s*(OffD[p] + tau*OffD[q]);
                OffD[p] += s*(OffDq   - tau*OffD[p]);
                for (int j=Z; j>=X; --j) 
                {
                    a = U(j,p); b = U(j,q);
                    U(j,p) -= s*(b + tau*a);
                    U(j,q) += s*(a - tau*b);
                }
            }
        }
    }
    kv = Diag; 
    return kv;
}