COIN-OR::LEMON - Graph Library

Ticket #310: 1121710e18c9.patch

File 1121710e18c9.patch, 5.3 KB (added by Balazs Dezso, 11 years ago)
  • lemon/bits/bezier.h

    # HG changeset patch
    # User Balazs Dezso <deba@inf.elte.hu>
    # Date 1250538012 -7200
    # Node ID 1121710e18c925ab3cdcbcfcad3a12a776a8865c
    # Parent  9f529abcaebf13f19e61ba24fdd2c3631860af91
    Bounding box functions for bezier curves
    
    diff -r 9f529abcaebf -r 1121710e18c9 lemon/bits/bezier.h
    a b  
    1919#ifndef LEMON_BEZIER_H
    2020#define LEMON_BEZIER_H
    2121
     22#include <cmath>
     23
    2224//\ingroup misc
    2325//\file
    2426//\brief Classes to compute with Bezier curves.
     
    6668  Point norm() const { return rot90(p2-p1); }
    6769  Point grad(double) const { return grad(); }
    6870  Point norm(double t) const { return rot90(grad(t)); }
     71  Box<double> boundingBox() const {
     72    double minx, miny;
     73    double maxx, maxy;
     74    if (p1.x < p2.x) {
     75      minx = p1.x; maxx = p2.x;
     76    } else {
     77      minx = p2.x; maxx = p1.x;
     78    }
     79    if (p1.y < p2.y) {
     80      miny = p1.y; maxy = p2.y;
     81    } else {
     82      miny = p2.y; maxy = p1.y;
     83    }
     84    return Box<double>(minx, miny, maxx, maxy);
     85  }
    6986};
    7087
    7188class Bezier2 : public BezierBase
     
    100117  Bezier1 norm() const { return Bezier1(2.0*rot90(p2-p1),2.0*rot90(p3-p2)); }
    101118  Point grad(double t) const { return grad()(t); }
    102119  Point norm(double t) const { return rot90(grad(t)); }
     120  Box<double> boundingBox() const {
     121    double minx, miny;
     122    double maxx, maxy;
     123    if (p1.x < p3.x) {
     124      minx = p1.x; maxx = p3.x;
     125    } else {
     126      minx = p3.x; maxx = p1.x;
     127    }
     128    if (p1.y < p3.y) {
     129      miny = p1.y; maxy = p3.y;
     130    } else {
     131      miny = p3.y; maxy = p1.y;
     132    }
     133    if (p1.x + p3.x - 2 * p2.x != 0.0) {
     134      double t = (p1.x - p2.x) / (p1.x + p3.x - 2 * p2.x);
     135      if (t >= 0.0 && t <= 1.0) {
     136        double x = ((1-t)*(1-t))*p1.x+(2*(1-t)*t)*p2.x+(t*t)*p3.x;
     137        if (x < minx) minx = x;
     138        if (x > maxx) maxx = x;
     139      }
     140    }
     141    if (p1.y + p3.y - 2 * p2.y != 0.0) {
     142      double t = (p1.y - p2.y) / (p1.y + p3.y - 2 * p2.y);
     143      if (t >= 0.0 && t <= 1.0) {
     144        double y = ((1-t)*(1-t))*p1.y+(2*(1-t)*t)*p2.y+(t*t)*p3.y;
     145        if (y < miny) miny = y;
     146        if (y > maxy) maxy = y;
     147      }
     148    }
     149    return Box<double>(minx, miny, maxx, maxy);
     150  }
    103151};
    104152
    105153class Bezier3 : public BezierBase
     
    150198                                  3.0*rot90(p4-p3)); }
    151199  Point grad(double t) const { return grad()(t); }
    152200  Point norm(double t) const { return rot90(grad(t)); }
     201  Box<double> boundingBox() const {
     202    double minx, miny;
     203    double maxx, maxy;
     204    if (p1.x < p4.x) {
     205      minx = p1.x; maxx = p4.x;
     206    } else {
     207      minx = p4.x; maxx = p1.x;
     208    }
     209    if (p1.y < p4.y) {
     210      miny = p1.y; maxy = p4.y;
     211    } else {
     212      miny = p4.y; maxy = p1.y;
     213    }
     214    if (p1.x - 3 * p2.x + 3 * p3.x - p4.x != 0.0) {
     215      double disc = p2.x * p2.x + p3.x * p3.x - p1.x * p3.x
     216        + p1.x * p4.x - p2.x * p3.x - p2.x * p4.x;
     217      if (disc >= 0.0) {
     218        double t = (p1.x + p3.x - 2 * p2.x + std::sqrt(disc)) /
     219          (p1.x - 3 * p2.x + 3 * p3.x - p4.x);
     220        if (t >= 0.0 && t <= 1.0) {
     221          double x = ((1-t)*(1-t)*(1-t))*p1.x+(3*t*(1-t)*(1-t))*p2.x+
     222            (3*t*t*(1-t))*p3.x+(t*t*t)*p4.x;
     223          if (x < minx) minx = x;
     224          if (x > maxx) maxx = x;
     225        }
     226        t = (p1.x + p3.x - 2 * p2.x - std::sqrt(disc)) /
     227          (p1.x - 3 * p2.x + 3 * p3.x - p4.x);
     228        if (t >= 0.0 && t <= 1.0) {
     229          double x = ((1-t)*(1-t)*(1-t))*p1.x+(3*t*(1-t)*(1-t))*p2.x+
     230            (3*t*t*(1-t))*p3.x+(t*t*t)*p4.x;
     231          if (x < minx) minx = x;
     232          if (x > maxx) maxx = x;
     233        }
     234      }
     235    } else if (p1.x + p3.x - 2 * p2.x != 0.0) {
     236      double t = (p1.x - p2.x) / (2 * p1.x + 2 * p3.x - 4 * p2.x);
     237      if (t >= 0.0 && t <= 1.0) {
     238        double x = ((1-t)*(1-t)*(1-t))*p1.x+(3*t*(1-t)*(1-t))*p2.x+
     239          (3*t*t*(1-t))*p3.x+(t*t*t)*p4.x;
     240        if (x < minx) minx = x;
     241        if (x > maxx) maxx = x;
     242      }     
     243    }
     244    if (p1.y - 3 * p2.y + 3 * p3.y - p4.y != 0.0) {
     245      double disc = p2.y * p2.y + p3.y * p3.y - p1.y * p3.y
     246        + p1.y * p4.y - p2.y * p3.y - p2.y * p4.y;
     247      if (disc >= 0.0) {
     248        double t = (p1.y + p3.y - 2 * p2.y + std::sqrt(disc)) /
     249          (p1.y - 3 * p2.y + 3 * p3.y - p4.y);
     250        if (t >= 0.0 && t <= 1.0) {
     251          double y = ((1-t)*(1-t)*(1-t))*p1.y+(3*t*(1-t)*(1-t))*p2.y+
     252            (3*t*t*(1-t))*p3.y+(t*t*t)*p4.y;
     253          if (y < miny) miny = y;
     254          if (y > maxy) maxy = y;
     255        }
     256        t = (p1.y + p3.y - 2 * p2.y - std::sqrt(disc)) /
     257          (p1.y - 3 * p2.y + 3 * p3.y - p4.y);
     258        if (t >= 0.0 && t <= 1.0) {
     259          double y = ((1-t)*(1-t)*(1-t))*p1.y+(3*t*(1-t)*(1-t))*p2.y+
     260            (3*t*t*(1-t))*p3.y+(t*t*t)*p4.y;
     261          if (y < miny) miny = y;
     262          if (y > maxy) maxy = y;
     263        }
     264      }
     265    } else if (p1.y + p3.y - 2 * p2.y != 0.0) {
     266      double t = (p1.y - p2.y) / (2 * p1.y + 2 * p3.y - 4 * p2.y);
     267      if (t >= 0.0 && t <= 1.0) {
     268        double y = ((1-t)*(1-t)*(1-t))*p1.y+(3*t*(1-t)*(1-t))*p2.y+
     269          (3*t*t*(1-t))*p3.y+(t*t*t)*p4.y;
     270        if (y < miny) miny = y;
     271        if (y > maxy) maxy = y;
     272      }     
     273    }
     274    return Box<double>(minx, miny, maxx, maxy);
     275  }
    153276
    154277  template<class R,class F,class S,class D>
    155278  R recSplit(F &_f,const S &_s,D _d) const