679 |
return 0.5 * t.getSqSize().x; |
return 0.5 * t.getSqSize().x; |
680 |
} |
} |
681 |
|
|
682 |
struct Conn { |
typedef Filletoid<StretchedCircleFillet> Conn; |
|
const CircularNode *node; |
|
|
LinearConnectionHalf c; |
|
|
StretchedCircleFillet f; |
|
|
ZVec dir; |
|
|
|
|
|
float da; |
|
|
vector<float> rtbl; |
|
|
|
|
|
Conn(const CircularNode &node, |
|
|
float d, |
|
|
float th, |
|
|
float a, |
|
|
ZVec dir) : |
|
|
node(&node), |
|
|
c(node, 0, d, th, -1, 0), |
|
|
f(node, c, a), dir(dir) { |
|
|
compute_rtbl(100); |
|
|
} |
|
|
|
|
|
Vec trans(ZVec v) const { |
|
|
float x = dir.dot(v); |
|
|
float y = (v - x * dir).length(); |
|
|
return Vec(x, y); |
|
|
} |
|
|
|
|
|
float rad(ZVec v, bool &success) const { |
|
|
Vec t = trans(v); |
|
|
if (rtbl.size()) { |
|
|
success = true; |
|
|
return rad_rtbl(t); |
|
|
} |
|
|
ZVec pt = f.point(t, success); |
|
|
if (success) return pt.length(); |
|
|
if (f.infillet(t)) { |
|
|
success = true; |
|
|
// return distance to the middle of the connection |
|
|
return c.d / v.normalized().dot(dir); |
|
|
} |
|
|
return node->r; |
|
|
} |
|
|
|
|
|
void compute_rtbl(int n) { |
|
|
rtbl.resize(n + 1); |
|
|
for (int i = 0; i < n; i++) { |
|
|
float t = i * (1.0 / n); |
|
|
float a = (t * t) * f.tangentAngle; |
|
|
bool success; |
|
|
float fract; |
|
|
ZVec pt = f.point(dirVec(a), success, &fract, .001); |
|
|
if (success) |
|
|
rtbl[i] = pt.length(); |
|
|
else |
|
|
rtbl[i] = c.d / cos(a); |
|
|
//cout << i << ": " << rtbl[i] << pt << fract << std::endl; |
|
|
} |
|
|
rtbl[n] = node->r; |
|
|
} |
|
|
|
|
|
float rad_rtbl(Vec v) const { |
|
|
int n = rtbl.size() - 1; |
|
|
float a = v.atan(); |
|
|
float t = sqrt(a / f.tangentAngle); |
|
|
int i = (int)(t * n); |
|
|
float fract = t * n - i; |
|
|
if (i >= n) return rtbl[n]; |
|
|
return (1 - fract) * rtbl[i] + fract * rtbl[i + 1]; |
|
|
} |
|
|
}; |
|
683 |
|
|
684 |
ZVec blend(Conn *conns[], int N, float r, ZVec pt) const { |
ZVec blend(Conn *conns[], int N, float r, ZVec pt) const { |
685 |
int i, num = 0; |
int i, num = 0; |
842 |
float d = (p1 - p0).length() / 2; |
float d = (p1 - p0).length() / 2; |
843 |
|
|
844 |
FilletSpan2::Conn conn(thick_t, angle_t, t0, t1, d); |
FilletSpan2::Conn conn(thick_t, angle_t, t0, t1, d); |
845 |
|
|
846 |
conns[i] = new Conn(node, d, conn.th, conn.a, |
conns[i] = new Conn(node, d, conn.th, conn.a, |
847 |
(p1 - p0).normalized()); |
(p1 - p0).normalized()); |
848 |
|
|
849 |
dirs.push_back((p1 - p0).normalized()); |
dirs.push_back((p1 - p0).normalized()); |
850 |
} |
} |
851 |
|
|
852 |
#if 1 // Old version without Dicer |
#if 0 |
853 |
|
|
854 |
|
for (int k = 0; k < N; k++) { |
855 |
|
std::vector<ZVec> pt((ndice + 1) * ndice); |
856 |
|
|
857 |
|
for (i = 0; i <= ndice; i++) { |
858 |
|
float f = (float)i / ndice; |
859 |
|
|
860 |
|
Vec v = conns[k]->f.point(f); |
861 |
|
|
862 |
|
ZVec e0 = conns[k]->dir; |
863 |
|
ZVec e1 = e0.crossp(ref).normalized(); |
864 |
|
ZVec e2 = e0.crossp(e1); |
865 |
|
|
866 |
|
for (j = 0; j < ndice; j++) { |
867 |
|
float a = j * 2 * M_PI / ndice; |
868 |
|
|
869 |
|
pt[i * ndice + j] = |
870 |
|
v.x * e0 |
871 |
|
+ v.y * cos(a) * e1 |
872 |
|
+ v.y * sin(a) * e2; |
873 |
|
} |
874 |
|
} |
875 |
|
|
876 |
|
for (i = 0; i < (ndice + 1) * ndice; i++) |
877 |
|
pt[i] = blend(conns, N, r, pt[i]) + p0; |
878 |
|
|
879 |
|
renderGrid(pt, ndice + 1, ndice); |
880 |
|
} |
881 |
|
|
882 |
|
#elif 1 // Old version without Dicer |
883 |
|
|
884 |
std::vector<ZVec> pt((ndice + 1) * (ndice * 2)); |
std::vector<ZVec> pt((ndice + 1) * (ndice * 2)); |
885 |
|
|