dust3d/thirdparty/carve-1.4.0/include/carve/rescale.hpp

101 lines
2.9 KiB
C++
Raw Normal View History

// Begin License:
// Copyright (C) 2006-2008 Tobias Sargeant (tobias.sargeant@gmail.com).
// All rights reserved.
//
// This file is part of the Carve CSG Library (http://carve-csg.com/)
//
// This file may be used under the terms of the GNU General Public
// License version 2.0 as published by the Free Software Foundation
// and appearing in the file LICENSE.GPL2 included in the packaging of
// this file.
//
// This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
// INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE.
// End:
#pragma once
#include <carve/carve.hpp>
#include <carve/vector.hpp>
#include <carve/aabb.hpp>
#include <carve/matrix.hpp>
#include <limits>
namespace carve {
namespace rescale {
template<typename T>
T calc_scale(T max) {
const int radix = std::numeric_limits<T>::radix;
T div = T(1);
T m = fabs(max);
while (div < m) div *= radix;
m *= radix;
while (div > m) div /= radix;
return div;
}
template<typename T>
T calc_delta(T min, T max) {
const int radix = std::numeric_limits<T>::radix;
if (min >= T(0) || max <= T(0)) {
bool neg = false;
if (max <= T(0)) {
min = -min;
max = -max;
std::swap(min, max);
neg = true;
}
T t = T(1);
while (t > max) t /= radix;
while (t <= max/radix) t *= radix;
volatile T temp = t + min;
temp -= t;
if (neg) temp = -temp;
return temp;
} else {
return T(0);
}
}
struct rescale {
double dx, dy, dz, scale;
void init(double minx, double miny, double minz, double maxx, double maxy, double maxz) {
dx = calc_delta(minx, maxx); minx -= dx; maxx -= dx;
dy = calc_delta(miny, maxy); miny -= dy; maxy -= dy;
dz = calc_delta(minz, maxz); minz -= dz; maxz -= dz;
scale = calc_scale(std::max(std::max(fabs(minz), fabs(maxz)),
std::max(std::max(fabs(minx), fabs(maxx)),
std::max(fabs(miny), fabs(maxy)))));
}
rescale(double minx, double miny, double minz, double maxx, double maxy, double maxz) {
init(minx, miny, minz, maxx, maxy, maxz);
}
rescale(const carve::geom3d::Vector &min, const carve::geom3d::Vector &max) {
init(min.x, min.y, min.z, max.x, max.y, max.z);
}
};
struct fwd {
rescale r;
fwd(const rescale &_r) : r(_r) { }
carve::geom3d::Vector operator()(const carve::geom3d::Vector &v) const { return carve::geom::VECTOR((v.x - r.dx) / r.scale, (v.y - r.dy) / r.scale, (v.z - r.dz) / r.scale); }
};
struct rev {
rescale r;
rev(const rescale &_r) : r(_r) { }
carve::geom3d::Vector operator()(const carve::geom3d::Vector &v) const { return carve::geom::VECTOR((v.x * r.scale) + r.dx, (v.y * r.scale) + r.dy, (v.z * r.scale) + r.dz); }
};
}
}