/[libvob]/libvob/include/vob/geom/Fillets2.hxx
ViewVC logotype

Diff of /libvob/include/vob/geom/Fillets2.hxx

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.7 by tjl, Thu Jun 5 10:37:22 2003 UTC revision 1.8 by tjl, Fri Jun 6 08:30:59 2003 UTC
# Line 1  Line 1 
1  // (c) Tuomas J. Lukka  // (c) Tuomas J. Lukka
2    
3    #include <boost/format.hpp>
4    
5  #include <vob/Vec23.hxx>  #include <vob/Vec23.hxx>
6  #include <vob/geom/Quadrics.hxx>  #include <vob/geom/Quadrics.hxx>
7    
8  namespace Vob {  namespace Vob {
9  namespace Geom {  namespace Geom {
10      PREDBGVAR(dbg_fillets);      PREDBGVAR(dbg_fillets);
11        using boost::format;
12    
13      /** Concept: a span of edge.      /** Concept: a span of edge.
14       * Usually, the 0-side is the connection and 1 is       * Usually, the 0-side is the connection and 1 is
# Line 125  namespace Geom { Line 128  namespace Geom {
128      };      };
129    
130      /** An elliptical fillet meeting a circle.      /** An elliptical fillet meeting a circle.
131         * All the parameters that specify the shape come from outside.
132       */       */
133      struct EllipseCircleFillet {      struct EllipseCircleFillet {
134          const CircularNode &node;          const CircularNode &node;
135          const LinearConnectionHalf &conn;          const LinearConnectionHalf &conn;
136          float tangentAngle;          float tangentAngle;
137    
138            Vec dirTang;
139            float dtSign;
140    
141            Vec ept, eno;
142    
143            Vec elli;
144    
145            Vec ey;
146            Vec eydir;
147            Vec ex;
148            Vec exdir;
149    
150            Vec ecenter;
151    
152            float eangle;
153    
154          /** Make a new fillet.          /** Make a new fillet.
155           * @param ta The tangent angle, i.e. always positive angle between           * @param ta The tangent angle, i.e. always positive angle between
156           *      connection line and tangent line.           *      connection line and tangent line.
# Line 140  namespace Geom { Line 161  namespace Geom {
161                  float ta                  float ta
162                  ) : node(node), conn(conn), tangentAngle(ta)                  ) : node(node), conn(conn), tangentAngle(ta)
163                      {                      {
164              Vec pt = Vec(conn.d, 0) - dirVec(-tangentAngle);              eno = Vec(-cos(tangentAngle), sin(tangentAngle));
165              Vec no = dirVec(-tangentAngle);              ept = Vec(conn.d, -conn.t/2) + node.r * eno;
166    
167                elli = Geom::symmellipse__point_norm(ept, eno);
168    
169                ex = -conn.norm * elli.y;
170                exdir = ex.normalized();
171                ey = -conn.dir * elli.x;
172                eydir = ey.normalized();
173    
174                ecenter = conn.endPoint - ex;
175    
176                dirTang = dirVec(conn.a + conn.sign * tangentAngle);
177                dtSign = conn.sign;
178    
179                /* Now, the ellipse always starts at angle 0. Find
180                 * the other angle.
181                 */
182                Vec pt2 = ept;
183                pt2.x *= elli.y / elli.x;
184                pt2.y = elli.y - pt2.y;
185    
186                eangle = pt2.atan();
187    
188                DBG(dbg_fillets) << format("Ellipse: ept: %s, eno: %s, elli: %s, ecenter: %s, "
189                                    "dirtang: %s, dtsign: %s, eangle: %s\n") %
190                            ept % eno % elli % ecenter % dirTang % dtSign % eangle;
191            }
192    
193            float iAngle(Vec dir, bool &succ) const {
194                Vec pt = dir * node.r;
195                Vec ptRel = ecenter - pt;
196                Vec ptC;
197                ptC.x = exdir.dot(ptRel) / elli.y;
198                ptC.y = eydir.dot(ptRel) / elli.x;
199    
200                Vec norm;
201                norm.x = dir.x * elli.y;
202                norm.y = dir.y * elli.x;
203    
204                ZVec proj = project2circle(ptC + norm, ptC, Vec(0,0), 1, -1, &succ);
205    
206                return Vec(proj).atan();
207            }
208    
209            ZVec point(float fract, ZVec *intern = 0) const {
210                float angle = lerp(0, eangle, fract);
211                Vec v(cos(angle), sin(angle));
212                ZVec pt = ecenter + v.x * ex + v.y * ey;
213                ZVec proj = conn.projectToConnLine(pt);
214                pt.z = proj.z;
215                if(intern) {
216                    if(fract > .94)
217                        *intern = node.ctr;
218                    else
219                        *intern = proj;
220                }
221                return pt;
222    
223            }
224            void cutEnd(Vec dir) {
225                bool s;
226                eangle = iAngle(dir, s);
227            }
228            ZVec point(Vec dir, bool &success) const {
229                if(dirTang.cross(dir) * dtSign < 0) {
230                    success = false;
231                    return ZVec(0,0,0);
232                }
233    
234                float an = iAngle(dir, success);
235                if(!success) return ZVec(0,0,0);
236    
237              Vec elli = Geom::symmellipse__point_norm(pt, no);              return point(an / eangle);
238          }          }
239            bool infillet(Vec dir) const {
240                return dirTang.cross(conn.dir) * dirTang.cross(dir) >= 0 &&
241                    conn.dir.cross(dirTang) * conn.dir.cross(dir) >= 0;
242            }
243            /** Returns true if either of the directions where the circles
244             * are tangent is inside the other fillet area.
245             * This is not *quite* the same as the trivial definition
246             * of overlapping: it returns false if the tangent points are
247             * past the connections.
248             */
249            bool overlaps(const EllipseCircleFillet &other) const {
250                return infillet(other.dirTang) || other.infillet(dirTang);
251            }
252    
253      };      };
254    
255      /** A circular fillet edge span, for a circular node.      /** A circular fillet edge span, for a circular node.
# Line 167  namespace Geom { Line 272  namespace Geom {
272           * to the point where           * to the point where
273           * the two circles are tangent.           * the two circles are tangent.
274           */           */
275          Vec dirtang;          Vec dirTang;
276    
277          /** The sign: calculate cross product of a vector with dirtang,          /** The sign: calculate cross product of a vector with dirTang,
278           * if sign is same as here, then we it is on the same side as the           * if sign is same as here, then we it is on the same side as the
279           * arc.           * arc.
280           */           */
# Line 189  namespace Geom { Line 294  namespace Geom {
294                  circle__point_norm_circle(conn.endPoint, conn.norm, node.ctr, node.r);                  circle__point_norm_circle(conn.endPoint, conn.norm, node.ctr, node.r);
295              this->frad =              this->frad =
296                  (fcenter - conn.endPoint).length();                  (fcenter - conn.endPoint).length();
297              this->dirtang = (fcenter - node.ctr) . normalized();              this->dirTang = (fcenter - node.ctr) . normalized();
298              this->dtsign = dirtang.cross(conn.dir);              this->dtsign = dirTang.cross(conn.dir);
299              this->astart = Vec(conn.endPoint - fcenter).atan();              this->astart = Vec(conn.endPoint - fcenter).atan();
300              this->aend = Vec(node.ctr - fcenter).atan();              this->aend = Vec(node.ctr - fcenter).atan();
301              while(aend - astart >= M_PI) aend -= 2 * M_PI;              while(aend - astart >= M_PI) aend -= 2 * M_PI;
# Line 224  namespace Geom { Line 329  namespace Geom {
329          }          }
330    
331          ZVec point(Vec dir, bool &success) const {          ZVec point(Vec dir, bool &success) const {
332              if(dirtang.cross(dir) * dtsign < 0) {              if(dirTang.cross(dir) * dtsign < 0) {
333                  success = false;                  success = false;
334                  return ZVec(0,0,0);                  return ZVec(0,0,0);
335              }              }
# Line 242  namespace Geom { Line 347  namespace Geom {
347           * naturally does not.           * naturally does not.
348           */           */
349          bool infillet(Vec dir) const {          bool infillet(Vec dir) const {
350              return dirtang.cross(conn.dir) * dirtang.cross(dir) >= 0 &&              return dirTang.cross(conn.dir) * dirTang.cross(dir) >= 0 &&
351                  conn.dir.cross(dirtang) * conn.dir.cross(dir) >= 0;                  conn.dir.cross(dirTang) * conn.dir.cross(dir) >= 0;
352          }          }
353          /** Returns true if either of the directions where the circles          /** Returns true if either of the directions where the circles
354           * are tangent is inside the other fillet area.           * are tangent is inside the other fillet area.
# Line 252  namespace Geom { Line 357  namespace Geom {
357           * past the connections.           * past the connections.
358           */           */
359          bool overlaps(const CircleCircleFillet &other) const {          bool overlaps(const CircleCircleFillet &other) const {
360              return infillet(other.dirtang) || other.infillet(dirtang);              return infillet(other.dirTang) || other.infillet(dirTang);
361          }          }
362    
363      };      };
# Line 260  namespace Geom { Line 365  namespace Geom {
365      /** A blend of two fillets.      /** A blend of two fillets.
366       * Note that this is only one side of the blend!       * Note that this is only one side of the blend!
367       */       */
368      struct FilletBlend {      template<class S1, class S2> struct FilletBlend {
369          CircleCircleFillet main;          S1 main;
370          const CircleCircleFillet &other;          const S2 &other;
371    
372          FilletBlend(const CircleCircleFillet &main0,          FilletBlend(const S1 &main0,
373                      const CircleCircleFillet &other) :                      const S2 &other) :
374                  main(main0), other(other) {                  main(main0), other(other) {
375              Vec cutdir = (main.dirtang + other.dirtang).normalized();              Vec cutdir = (main.dirTang + other.dirTang).normalized();
376              main.cutEnd(cutdir);              main.cutEnd(cutdir);
377          }          }
378    
# Line 287  namespace Geom { Line 392  namespace Geom {
392              return res;              return res;
393          }          }
394      };      };
395        template<class S1, class S2> FilletBlend<S1, S2> makeFilletBlend(
396                    const S1 &s1, const S2 &s2) {
397            return FilletBlend<S1,S2>(s1, s2);
398        }
399    
400      /** A linearly interpolated fillet span between two given      /** A linearly interpolated fillet span between two given
401       * ones.       * ones.

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26