1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
// Begin License:
// Copyright (C) 2006-2014 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 either the GNU General
// Public License version 2 or 3 (at your option) as published by the
// Free Software Foundation and appearing in the files LICENSE.GPL2
// and LICENSE.GPL3 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); }
};
}
}
|