Blame raster.cpp

57bda0
d2b2b5
#include <gl gl.h=""></gl>
d2b2b5
57bda0
#include "raster.h"
57bda0
57bda0
d2b2b5
void Raster::touch(const Painter &painter, const Vector2 &position, int index, TouchPointList &points) {
d2b2b5
    Vector2 rxy = painter.get_radius_xy();
d2b2b5
    rxy.x = fabs(rxy.x) + 0.52;
d2b2b5
    rxy.y = fabs(rxy.y) + 0.52;
d2b2b5
    
d2b2b5
    int x0, x1, y0, y1;
d2b2b5
    if (rxy.x < width) { // to handle values greater than INT_MAX
d2b2b5
        x0 = std::max(0     , (int)ceil(position.x - rxy.x));
d2b2b5
        x1 = std::min(width , (int)ceil(position.x + rxy.x));
d2b2b5
    } else {
d2b2b5
        x0 = 0; x1 = width;
d2b2b5
    }
d2b2b5
    if (rxy.y < height) {
d2b2b5
        y0 = std::max(0     , (int)ceil(position.y - rxy.y));
d2b2b5
        y1 = std::min(height, (int)ceil(position.y + rxy.y));
d2b2b5
    } else {
d2b2b5
        y0 = 0; y1 = height;
d2b2b5
    }
57bda0
    
57bda0
    for(int iy = y0; iy < y1; ++iy) {
57bda0
        for(int ix = x0; ix < x1; ++ix) {
d2b2b5
            Vector2 v(
d2b2b5
                std::max(0.0, fabs(ix - position.x) - 0.51),
d2b2b5
                std::max(0.0, fabs(iy - position.y) - 0.51) );
d2b2b5
            Real h = painter.get_height_xy(v);
d2b2b5
            Real &pixel = (*this)[iy][ix];
d2b2b5
            if (pixel > h) {
d2b2b5
                points.push_back( TouchPoint(index, iy, ix, pixel, h) );
d2b2b5
                pixel = h;
57bda0
            }
57bda0
        }
57bda0
    }
57bda0
}
d2b2b5
d2b2b5
0a0ecd
Vector4 FlatRaster::color_by_distance(Real d) const {
0a0ecd
    Real dv = max_value - min_value;
0a0ecd
    Real k = fabs(dv) < 1e-5 ? 0 : (d - min_value)/dv;
0a0ecd
    return Vector4(
0a0ecd
        1 - k,
0a0ecd
        1 - 2*fabs(0.5 - k),
0a0ecd
        k,
0a0ecd
        0.5 );
0a0ecd
}
0a0ecd
0a0ecd
void FlatRaster::draw() const
0a0ecd
{
0a0ecd
    int w = raster.get_width();
0a0ecd
    int h = raster.get_height();
0a0ecd
    if (w < 2 || h < 2) return;
0a0ecd
0a0ecd
    Vector3 v, v0, v1;
0a0ecd
    
0a0ecd
    Real kx = (x1 - x0)/w;
0a0ecd
    Real ky = (y1 - y0)/h;
0a0ecd
0a0ecd
    glEnable(GL_LIGHTING);
0a0ecd
    
0a0ecd
    glBegin(GL_TRIANGLE_STRIP);
0a0ecd
    for(int r = 1; r < h; ++r) {
0a0ecd
        v0.y = y0 + (r - 1)*ky;
0a0ecd
        v1.y = y0 + r*ky;
0a0ecd
        for(int c = 0; c < w; ++c) {
0a0ecd
            v0.x = v1.x = x0 + c*kx;
0a0ecd
            v0.z = raster[r-1][c];
0a0ecd
            v1.z = raster[r][c];
0a0ecd
            
0a0ecd
            if (r == 1 && c == 0) v = v0;
0a0ecd
            
0a0ecd
            Vector3 dv0(v0.x - v.x, v0.y - v.y, v0.z - v.z);
0a0ecd
            Vector3 dv1(v1.x - v.x, v1.y - v.y, v1.z - v.z);
0a0ecd
            Vector3 norm(
0a0ecd
                dv0.y*dv1.z - dv0.z*dv1.y,
0a0ecd
                dv0.z*dv1.x - dv0.x*dv1.z,
0a0ecd
                dv0.x*dv1.y - dv0.y*dv1.x );
0a0ecd
            Real l = sqrt(norm.x*norm.x + norm.y*norm.y + norm.z*norm.z);
0a0ecd
            l = l > 1e-5 ? 1/l : 0;
0a0ecd
            glNormal3d(norm.x*l, norm.y*l, norm.z*l);
0a0ecd
0a0ecd
            if (!c) glVertex3dv(v0.c);
0a0ecd
            glColor4dv(color_by_distance(v0.z).c);
0a0ecd
            glVertex3dv(v0.c);
0a0ecd
            glColor4dv(color_by_distance(v1.z).c);
0a0ecd
            glVertex3dv(v1.c);
0a0ecd
            v = v1;
0a0ecd
        }
0a0ecd
        glVertex3dv(v.c);
0a0ecd
    }
0a0ecd
    glEnd();
0a0ecd
    
0a0ecd
    glDisable(GL_LIGHTING);
0a0ecd
}
0a0ecd
0a0ecd
d2b2b5
Vector4 PolarRaster::color_by_distance(Real d) const {
d2b2b5
    Real dv = max_value - min_value;
d2b2b5
    Real k = fabs(dv) < 1e-5 ? 0 : (d - min_value)/dv;
d2b2b5
    return Vector4(
d2b2b5
        1 - k,
d2b2b5
        1 - 2*fabs(0.5 - k),
d2b2b5
        k,
d2b2b5
        0.5 );
d2b2b5
}
d2b2b5
d2b2b5
void PolarRaster::draw() const
d2b2b5
{
d2b2b5
    int w = raster.get_width();
d2b2b5
    int h = raster.get_height();
d2b2b5
    if (w < 2 || h < 2) return;
d2b2b5
d2b2b5
    Vector3 v, v0, v1;
d2b2b5
    
d2b2b5
    Real kx = (x1 - x0)/w;
d2b2b5
    Real ka = 2*M_PI/h;
d2b2b5
d2b2b5
    glEnable(GL_LIGHTING);
d2b2b5
    
d2b2b5
    glBegin(GL_TRIANGLE_STRIP);
d2b2b5
    for(int r = 0; r < h; ++r) {
d2b2b5
        int rr = r ? r-1 : h-1;
d2b2b5
        Real a0 = rr*ka;
d2b2b5
        Real a1 = r*ka;
d2b2b5
        Real s0 = sin(a0), s1 = sin(a1);
d2b2b5
        Real c0 = cos(a0), c1 = cos(a1);
d2b2b5
        for(int c = 0; c < w; ++c) {
d2b2b5
            v0.x = v1.x = x0 + c*kx;
d2b2b5
            Real r0 = raster[rr][c];
d2b2b5
            Real r1 = raster[r][c];
d2b2b5
            v0.y = -s0*r0, v0.z = c0*r0;
d2b2b5
            v1.y = -s1*r1, v1.z = c1*r1;
d2b2b5
            
d2b2b5
            Vector3 dv0(v0.x - v.x, v0.y - v.y, v0.z - v.z);
d2b2b5
            Vector3 dv1(v1.x - v.x, v1.y - v.y, v1.z - v.z);
d2b2b5
            Vector3 norm(
d2b2b5
                dv0.y*dv1.z - dv0.z*dv1.y,
d2b2b5
                dv0.z*dv1.x - dv0.x*dv1.z,
d2b2b5
                dv0.x*dv1.y - dv0.y*dv1.x );
d2b2b5
            Real l = sqrt(norm.x*norm.x + norm.y*norm.y + norm.z*norm.z);
d2b2b5
            l = l > 1e-5 ? 1/l : 0;
d2b2b5
            glNormal3d(norm.x*l, norm.y*l, norm.z*l);
d2b2b5
d2b2b5
            if (!c) glVertex3dv(v0.c);
d2b2b5
            glColor4dv(color_by_distance(r0).c);
d2b2b5
            glVertex3dv(v0.c);
d2b2b5
            glColor4dv(color_by_distance(r0).c);
d2b2b5
            glVertex3dv(v1.c);
d2b2b5
            v = v1;
d2b2b5
        }
d2b2b5
        glVertex3dv(v.c);
d2b2b5
    }
d2b2b5
    glEnd();
d2b2b5
    
d2b2b5
    glDisable(GL_LIGHTING);
d2b2b5
}