|
 |
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 |
}
|