50 |
} |
} |
51 |
}; |
}; |
52 |
|
|
53 |
/** A connection. The node is assumed to be known. |
/** A connection. |
54 |
*/ |
*/ |
55 |
struct LinearConnectionHalf { |
struct LinearConnectionHalf { |
56 |
const CircularNode &node; |
const CircularNode &node; |
110 |
* node) on the connection |
* node) on the connection |
111 |
* line, it will be clamped to the center. |
* line, it will be clamped to the center. |
112 |
* Useful for generating internal points. |
* Useful for generating internal points. |
113 |
|
* XXX Z calculation needs thinking. |
114 |
*/ |
*/ |
115 |
ZVec projectToConnLine(ZVec v) const { |
ZVec projectToConnLine(ZVec v) const { |
116 |
float l = (v - node.ctr).xylength(); |
float l = (v - node.ctr).xylength(); |
125 |
}; |
}; |
126 |
|
|
127 |
/** A circular fillet edge span, for a circular node. |
/** A circular fillet edge span, for a circular node. |
128 |
|
* This is simply a circular arc from the connection to the point |
129 |
|
* where it is tangent to the circular node. |
130 |
*/ |
*/ |
131 |
struct CircleCircleFillet { |
struct CircleCircleFillet { |
132 |
const CircularNode &node; |
const CircularNode &node; |
133 |
const LinearConnectionHalf &conn; |
const LinearConnectionHalf &conn; |
134 |
|
|
135 |
|
/** Center of the circle of which the arc is taken. |
136 |
|
*/ |
137 |
Vec fcenter; |
Vec fcenter; |
138 |
|
|
139 |
|
/** Radius of the arc. |
140 |
|
*/ |
141 |
float frad; |
float frad; |
142 |
|
|
143 |
/** The direction vector from the center of the node |
/** The direction vector from the center of the node |
146 |
*/ |
*/ |
147 |
Vec dirtang; |
Vec dirtang; |
148 |
|
|
149 |
|
/** The sign: calculate cross product of a vector with dirtang, |
150 |
|
* if sign is same as here, then we it is on the same side as the |
151 |
|
* arc. |
152 |
|
*/ |
153 |
float dtsign; |
float dtsign; |
154 |
|
|
155 |
|
/** The start angle of the arc, looking from fcenter. |
156 |
|
*/ |
157 |
float astart; |
float astart; |
158 |
|
/** The end angle of the arc, looking from fcenter. |
159 |
|
*/ |
160 |
float aend; |
float aend; |
161 |
|
|
162 |
CircleCircleFillet( |
CircleCircleFillet( |
213 |
return in; |
return in; |
214 |
} |
} |
215 |
|
|
216 |
|
/** Whether the given direction vector from the center of the node is inside |
217 |
|
* the fillet. This does *not* guarantee that point(dir) will be a success: |
218 |
|
* this function includes vectors inside the connection to the fillet but point() |
219 |
|
* naturally does not. |
220 |
|
*/ |
221 |
bool infillet(Vec dir) const { |
bool infillet(Vec dir) const { |
222 |
return dirtang.cross(conn.dir) * dirtang.cross(dir) >= 0 && |
return dirtang.cross(conn.dir) * dirtang.cross(dir) >= 0 && |
223 |
conn.dir.cross(dirtang) * conn.dir.cross(dir) >= 0; |
conn.dir.cross(dirtang) * conn.dir.cross(dir) >= 0; |
224 |
} |
} |
225 |
/** Returns true if either of the directions where the circles |
/** Returns true if either of the directions where the circles |
226 |
* are tangent is inside the other fillet area. |
* are tangent is inside the other fillet area. |
227 |
|
* This is not *quite* the same as the trivial definition |
228 |
|
* of overlapping: it returns false if the tangent points are |
229 |
|
* past the connections. |
230 |
*/ |
*/ |
231 |
bool overlaps(const CircleCircleFillet &other) const { |
bool overlaps(const CircleCircleFillet &other) const { |
232 |
return infillet(other.dirtang) || other.infillet(dirtang); |
return infillet(other.dirtang) || other.infillet(dirtang); |
265 |
} |
} |
266 |
}; |
}; |
267 |
|
|
268 |
|
/** A linearly interpolated fillet span between two given |
269 |
|
* ones. |
270 |
|
*/ |
271 |
template<class S1, class S2> struct LerpFilletSpan { |
template<class S1, class S2> struct LerpFilletSpan { |
272 |
const S1 &s1; |
const S1 &s1; |
273 |
const S2 &s2; |
const S2 &s2; |
282 |
return res; |
return res; |
283 |
} |
} |
284 |
}; |
}; |
285 |
|
|
286 |
template<class S1, class S2> LerpFilletSpan<S1, S2> makeLerpFilletSpan( |
template<class S1, class S2> LerpFilletSpan<S1, S2> makeLerpFilletSpan( |
287 |
const S1 &s1, const S2 &s2, float fract) { |
const S1 &s1, const S2 &s2, float fract) { |
288 |
return LerpFilletSpan<S1,S2>(s1, s2, fract); |
return LerpFilletSpan<S1,S2>(s1, s2, fract); |
289 |
} |
} |
290 |
|
|
291 |
|
/** A span of the circular node shape. |
292 |
|
*/ |
293 |
struct CircularNodeSpan { |
struct CircularNodeSpan { |
294 |
const CircularNode &node; |
const CircularNode &node; |
295 |
float astart; |
float astart; |