]> Shamusworld >> Repos - architektonas/blobdiff - src/base/spline.cpp
Major refactor of Architektonas: Jettisoning old cruft.
[architektonas] / src / base / spline.cpp
diff --git a/src/base/spline.cpp b/src/base/spline.cpp
deleted file mode 100644 (file)
index 37d9ee0..0000000
+++ /dev/null
@@ -1,738 +0,0 @@
-// spline.cpp
-//
-// Part of the Architektonas Project
-// Originally part of QCad Community Edition by Andrew Mustun
-// Extensively rewritten and refactored by James L. Hammons
-// Portions copyright (C) 2001-2003 RibbonSoft
-// Copyright (C) 2010 Underground Software
-// See the README and GPLv2 files for licensing and warranty information
-//
-// JLH = James L. Hammons <jlhamm@acm.org>
-//
-// Who  When        What
-// ---  ----------  -----------------------------------------------------------
-// JLH  06/02/2010  Added this text. :-)
-//
-
-#include "spline.h"
-
-#include "debug.h"
-#include "graphicview.h"
-#include "drawing.h"
-#include "paintinterface.h"
-
-/**
- * Constructor.
- */
-Spline::Spline(EntityContainer * parent, const SplineData & d):
-       EntityContainer(parent), data(d)
-{
-       calculateBorders();
-}
-
-/**
- * Destructor.
- */
-Spline::~Spline()
-{
-}
-
-Entity * Spline::clone()
-{
-       Spline * l = new Spline(*this);
-#warning "!!! Need to deal with setAutoDelete() Qt3->Qt4 !!!"
-//     l->entities.setAutoDelete(entities.autoDelete());
-       l->initId();
-       l->detach();
-       return l;
-}
-
-/**    @return RS2::EntitySpline */
-/*virtual*/ RS2::EntityType Spline::rtti() const
-{
-       return RS2::EntitySpline;
-}
-
-/** @return false */
-/*virtual*/ bool Spline::isEdge() const
-{
-       return false;
-}
-
-/** @return Copy of data that defines the spline. */
-SplineData Spline::getData() const
-{
-       return data;
-}
-
-/** Sets the splines degree (1-3). */
-void Spline::setDegree(int deg)
-{
-       if (deg >= 1 && deg <= 3)
-               data.degree = deg;
-}
-
-/** @return Degree of this spline curve (1-3).*/
-int Spline::getDegree()
-{
-       return data.degree;
-}
-
-/** @return 0. */
-int Spline::getNumberOfKnots()
-{
-       return 0;
-}
-
-/** @return Number of control points. */
-int Spline::getNumberOfControlPoints()
-{
-       return data.controlPoints.count();
-}
-
-/**
- * @retval true if the spline is closed.
- * @retval false otherwise.
- */
-bool Spline::isClosed()
-{
-       return data.closed;
-}
-
-/**
- * Sets the closed falg of this spline.
- */
-void Spline::setClosed(bool c)
-{
-       data.closed = c;
-       update();
-}
-
-void Spline::calculateBorders()
-{
-    /*minV = Vector::minimum(data.startpoint, data.endpoint);
-    maxV = Vector::maximum(data.startpoint, data.endpoint);
-
-    Q3ValueList<Vector>::iterator it;
-    for (it = data.controlPoints.begin();
-    it!=data.controlPoints.end(); ++it) {
-
-    minV = Vector::minimum(*it, minV);
-    maxV = Vector::maximum(*it, maxV);
-}
-    */
-}
-
-VectorSolutions Spline::getRefPoints()
-{
-       VectorSolutions ret(data.controlPoints.count());
-
-       int i = 0;
-       QList<Vector>::iterator it;
-
-       for(it=data.controlPoints.begin(); it!=data.controlPoints.end(); ++it, ++i)
-       {
-               ret.set(i, (*it));
-       }
-
-       return ret;
-}
-
-Vector Spline::getNearestRef(const Vector & coord, double * dist)
-{
-       //return getRefPoints().getClosest(coord, dist);
-       return Entity::getNearestRef(coord, dist);
-}
-
-Vector Spline::getNearestSelectedRef(const Vector & coord, double * dist)
-{
-       //return getRefPoints().getClosest(coord, dist);
-       return Entity::getNearestSelectedRef(coord, dist);
-}
-
-/**
- * Updates the internal polygon of this spline. Called when the
- * spline or it's data, position, .. changes.
- */
-void Spline::update()
-{
-       DEBUG->print("Spline::update");
-
-       clear();
-
-       if (isUndone())
-               return;
-
-       if (data.degree < 1 || data.degree > 3)
-       {
-               DEBUG->print("Spline::update: invalid degree: %d", data.degree);
-               return;
-       }
-
-       if (data.controlPoints.count() < (uint)data.degree + 1)
-       {
-               DEBUG->print("Spline::update: not enough control points");
-               return;
-       }
-
-       resetBorders();
-
-//     Q3ValueList<Vector> tControlPoints = data.controlPoints;
-       QList<Vector> tControlPoints = data.controlPoints;
-
-       if (data.closed)
-       {
-               for(int i=0; i<data.degree; ++i)
-                       tControlPoints.append(data.controlPoints[i]);
-       }
-
-       int i;
-       int npts = tControlPoints.count();
-       // order:
-       int k = data.degree + 1;
-       // resolution:
-       int p1 = getGraphicVariableInt("$SPLINESEGS", 8) * npts;
-
-       double * b = new double[npts * 3 + 1];
-       double * h = new double[npts + 1];
-       double * p = new double[p1 * 3 + 1];
-
-//     Q3ValueList<Vector>::iterator it;
-       QList<Vector>::iterator it;
-       i = 1;
-
-       for(it=tControlPoints.begin(); it!=tControlPoints.end(); ++it)
-       {
-               b[i + 0] = (*it).x;
-               b[i + 1] = (*it).y;
-               b[i + 2] = 0.0;
-
-               DEBUG->print("Spline::update: b[%d]: %f/%f", i, b[i], b[i + 1]);
-               i += 3;
-       }
-
-       // set all homogeneous weighting factors to 1.0
-       for(i=1; i<=npts; i++)
-               h[i] = 1.0;
-
-       for(i=1; i<=3*p1; i++)
-               p[i] = 0.0;
-
-       if (data.closed)
-               rbsplinu(npts, k, p1, b, h, p);
-       else
-               rbspline(npts, k, p1, b, h, p);
-
-       Vector prev(false);
-
-       for(i=1; i<=3*p1; i=i+3)
-       {
-               if (prev.valid)
-               {
-                       Line * line = new Line(this, LineData(prev, Vector(p[i], p[i + 1])));
-                       line->setLayer(NULL);
-                       line->setPen(Pen(RS2::FlagInvalid));
-                       addEntity(line);
-               }
-
-               prev = Vector(p[i], p[i+1]);
-               minV = Vector::minimum(prev, minV);
-               maxV = Vector::maximum(prev, maxV);
-       }
-
-       delete[] b;
-       delete[] h;
-       delete[] p;
-}
-
-Vector Spline::getNearestEndpoint(const Vector & coord, double * dist)
-{
-    double minDist = RS_MAXDOUBLE;
-    double d;
-    Vector ret(false);
-
-    for (uint i=0; i<data.controlPoints.count(); i++) {
-        d = data.controlPoints[i].distanceTo(coord);
-
-        if (d<minDist) {
-            minDist = d;
-            ret = data.controlPoints[i];
-        }
-    }
-    if (dist!=NULL) {
-        *dist = minDist;
-    }
-       return ret;
-}
-
-/*
-// The default implementation of EntityContainer is inaccurate but
-//   has to do for now..
-Vector Spline::getNearestPointOnEntity(const Vector& coord,
-        bool onEntity, double* dist, Entity** entity) {
-}
-*/
-
-Vector Spline::getNearestCenter(const Vector & /*coord*/, double * dist)
-{
-       if (dist != NULL)
-               *dist = RS_MAXDOUBLE;
-
-       return Vector(false);
-}
-
-Vector Spline::getNearestMiddle(const Vector & /*coord*/, double * dist)
-{
-       if (dist!=NULL)
-               *dist = RS_MAXDOUBLE;
-
-       return Vector(false);
-}
-
-Vector Spline::getNearestDist(double /*distance*/, const Vector & /*coord*/, double * dist)
-{
-       if (dist != NULL)
-               *dist = RS_MAXDOUBLE;
-
-       return Vector(false);
-}
-
-void Spline::move(Vector offset)
-{
-//     Q3ValueList<Vector>::iterator it;
-       QList<Vector>::iterator it;
-
-       for(it=data.controlPoints.begin(); it!=data.controlPoints.end(); ++it)
-               (*it).move(offset);
-
-       update();
-}
-
-void Spline::rotate(Vector center, double angle)
-{
-//     Q3ValueList<Vector>::iterator it;
-       QList<Vector>::iterator it;
-
-       for(it=data.controlPoints.begin(); it!=data.controlPoints.end(); ++it)
-               (*it).rotate(center, angle);
-
-       update();
-}
-
-void Spline::scale(Vector center, Vector factor)
-{
-//     Q3ValueList<Vector>::iterator it;
-       QList<Vector>::iterator it;
-
-       for(it=data.controlPoints.begin(); it!=data.controlPoints.end(); ++it)
-               (*it).scale(center, factor);
-
-       update();
-}
-
-void Spline::mirror(Vector axisPoint1, Vector axisPoint2)
-{
-//     Q3ValueList<Vector>::iterator it;
-       QList<Vector>::iterator it;
-
-       for(it=data.controlPoints.begin(); it!=data.controlPoints.end(); ++it)
-               (*it).mirror(axisPoint1, axisPoint2);
-
-       update();
-}
-
-void Spline::moveRef(const Vector & ref, const Vector & offset)
-{
-//     Q3ValueList<Vector>::iterator it;
-       QList<Vector>::iterator it;
-
-       for(it=data.controlPoints.begin(); it!=data.controlPoints.end(); ++it)
-       {
-               if (ref.distanceTo(*it) < 1.0e-4)
-                       (*it).move(offset);
-       }
-
-       update();
-}
-
-void Spline::draw(PaintInterface * painter, GraphicView * view, double /*patternOffset*/)
-{
-       if (painter == NULL || view == NULL)
-               return;
-
-       Entity * e = firstEntity(RS2::ResolveNone);
-       double offset = 0.0;
-
-       if (e != NULL)
-       {
-               view->drawEntity(e);
-               offset += e->getLength();
-               //DEBUG->print("offset: %f\nlength was: %f", offset, e->getLength());
-       }
-
-       for (Entity * e=nextEntity(RS2::ResolveNone); e!=NULL; e = nextEntity(RS2::ResolveNone))
-       {
-               view->drawEntityPlain(e, -offset);
-               offset += e->getLength();
-               //DEBUG->print("offset: %f\nlength was: %f", offset, e->getLength());
-       }
-}
-
-/**
- * Todo: draw the spline, user patterns.
- */
-/*
-void Spline::draw(RS_Painter* painter, GraphicView* view) {
-   if (painter==NULL || view==NULL) {
-       return;
-   }
-
-   / *
-      if (data.controlPoints.count()>0) {
-          Vector prev(false);
-          Q3ValueList<Vector>::iterator it;
-          for (it = data.controlPoints.begin(); it!=data.controlPoints.end(); ++it) {
-              if (prev.valid) {
-                  painter->drawLine(view->toGui(prev),
-                                    view->toGui(*it));
-              }
-              prev = (*it);
-          }
-      }
-   * /
-
-   int i;
-   int npts = data.controlPoints.count();
-   // order:
-   int k = 4;
-   // resolution:
-   int p1 = 100;
-
-   double* b = new double[npts*3+1];
-   double* h = new double[npts+1];
-   double* p = new double[p1*3+1];
-
-   Q3ValueList<Vector>::iterator it;
-   i = 1;
-   for (it = data.controlPoints.begin(); it!=data.controlPoints.end(); ++it) {
-       b[i] = (*it).x;
-       b[i+1] = (*it).y;
-       b[i+2] = 0.0;
-
-       DEBUG->print("Spline::draw: b[%d]: %f/%f", i, b[i], b[i+1]);
-       i+=3;
-   }
-
-   // set all homogeneous weighting factors to 1.0
-   for (i=1; i <= npts; i++) {
-       h[i] = 1.0;
-   }
-
-   //
-   for (i = 1; i <= 3*p1; i++) {
-       p[i] = 0.0;
-   }
-
-   rbspline(npts,k,p1,b,h,p);
-
-   Vector prev(false);
-   for (i = 1; i <= 3*p1; i=i+3) {
-       if (prev.valid) {
-           painter->drawLine(view->toGui(prev),
-                             view->toGui(Vector(p[i], p[i+1])));
-       }
-       prev = Vector(p[i], p[i+1]);
-   }
-}
-*/
-
-/**
- * @return The reference points of the spline.
- */
-//Q3ValueList<Vector> Spline::getControlPoints()
-QList<Vector> Spline::getControlPoints()
-{
-       return data.controlPoints;
-}
-
-/**
- * Appends the given point to the control points.
- */
-void Spline::addControlPoint(const Vector & v)
-{
-       data.controlPoints.append(v);
-}
-
-/**
- * Removes the control point that was last added.
- */
-void Spline::removeLastControlPoint()
-{
-       data.controlPoints.pop_back();
-}
-
-/**
- * Generates B-Spline open knot vector with multiplicity
- * equal to the order at the ends.
- */
-void Spline::knot(int num, int order, int knotVector[])
-{
-       knotVector[1] = 0;
-
-       for(int i=2; i<=num+order; i++)
-       {
-               if ((i > order) && (i < num + 2))
-               {
-                       knotVector[i] = knotVector[i - 1] + 1;
-               }
-               else
-               {
-                       knotVector[i] = knotVector[i - 1];
-               }
-       }
-}
-
-/**
- * Generates rational B-spline basis functions for an open knot vector.
- */
-void Spline::rbasis(int c, double t, int npts, int x[], double h[], double r[])
-{
-       int nplusc;
-       int i, k;
-       double d, e;
-       double sum;
-       //double temp[36];
-
-       nplusc = npts + c;
-
-       double * temp = new double[nplusc + 1];
-
-       // calculate the first order nonrational basis functions n[i]
-       for(i=1; i<=nplusc-1; i++)
-       {
-               if ((t >= x[i]) && (t < x[i + 1]))
-                       temp[i] = 1;
-               else
-                       temp[i] = 0;
-       }
-
-       /* calculate the higher order nonrational basis functions */
-
-       for(k=2; k<=c; k++)
-       {
-               for(i=1; i<=nplusc-k; i++)
-               {
-                       // if the lower order basis function is zero skip the calculation
-                       if (temp[i] != 0)
-                               d = ((t - x[i]) * temp[i]) / (x[i + k - 1] - x[i]);
-                       else
-                               d = 0;
-
-                       // if the lower order basis function is zero skip the calculation
-                       if (temp[i + 1] != 0)
-                               e = ((x[i + k] - t) * temp[i + 1]) / (x[i + k] - x[i + 1]);
-                       else
-                               e = 0;
-
-                       temp[i] = d + e;
-               }
-       }
-
-       // pick up last point
-       if (t == (double)x[nplusc])
-               temp[npts] = 1;
-
-       // calculate sum for denominator of rational basis functions
-       sum = 0.;
-
-       for(i=1; i<=npts; i++)
-               sum = sum + temp[i] * h[i];
-
-       // form rational basis functions and put in r vector
-       for(i=1; i<=npts; i++)
-       {
-               if (sum != 0)
-                       r[i] = (temp[i] * h[i]) / (sum);
-               else
-                       r[i] = 0;
-       }
-
-       delete[] temp;
-}
-
-/**
- * Generates a rational B-spline curve using a uniform open knot vector.
- */
-void Spline::rbspline(int npts, int k, int p1, double b[], double h[], double p[])
-{
-       int i, j, icount, jcount;
-       int i1;
-       //int x[30]; /* allows for 20 data points with basis function of order 5 */
-       int nplusc;
-
-       double step;
-       double t;
-       //double nbasis[20];
-       double temp;
-
-       nplusc = npts + k;
-
-       int * x = new int[nplusc + 1];
-       double * nbasis = new double[npts + 1];
-
-       // zero and redimension the knot vector and the basis array
-
-       for(i = 0; i <= npts; i++)
-               nbasis[i] = 0.0;
-
-       for(i = 0; i <= nplusc; i++)
-               x[i] = 0;
-
-       // generate the uniform open knot vector
-       knot(npts, k, x);
-
-       icount = 0;
-
-       // calculate the points on the rational B-spline curve
-       t = 0;
-       step = ((double)x[nplusc]) / ((double)(p1 - 1));
-
-       for(i1=1; i1<= p1; i1++)
-       {
-               if ((double)x[nplusc] - t < 5e-6)
-                       t = (double)x[nplusc];
-
-               // generate the basis function for this value of t
-               rbasis(k, t, npts, x, h, nbasis);
-
-               // generate a point on the curve
-               for(j=1; j<=3; j++)
-               {
-                       jcount = j;
-                       p[icount + j] = 0.0;
-
-                       // Do local matrix multiplication
-                       for(i=1; i<=npts; i++)
-                       {
-                               temp = nbasis[i] * b[jcount];
-                               p[icount + j] = p[icount + j] + temp;
-                               jcount = jcount + 3;
-                       }
-               }
-
-               icount = icount + 3;
-               t = t + step;
-       }
-
-       delete[] x;
-       delete[] nbasis;
-}
-
-void Spline::knotu(int num, int order, int knotVector[])
-{
-       int nplusc = num + order;
-       int nplus2 = num + 2;
-       knotVector[1] = 0;
-
-       for(int i=2; i<=nplusc; i++)
-               knotVector[i] = i - 1;
-}
-
-void Spline::rbsplinu(int npts, int k, int p1, double b[], double h[], double p[])
-{
-       int i, j, icount, jcount;
-       int i1;
-       //int x[30];            /* allows for 20 data points with basis function of order 5 */
-       int nplusc;
-
-       double step;
-       double t;
-       //double nbasis[20];
-       double temp;
-
-       nplusc = npts + k;
-
-       int * x = new int[nplusc + 1];
-       double * nbasis = new double[npts + 1];
-
-       /*  zero and redimension the knot vector and the basis array */
-
-       for(i=0; i<=npts; i++)
-               nbasis[i] = 0.0;
-
-       for(i=0; i<=nplusc; i++)
-               x[i] = 0;
-
-       /* generate the uniform periodic knot vector */
-
-       knotu(npts, k, x);
-
-       /*
-               printf("The knot vector is ");
-               for (i = 1; i <= nplusc; i++){
-                       printf(" %d ", x[i]);
-               }
-               printf("\n");
-
-               printf("The usable parameter range is ");
-               for (i = k; i <= npts+1; i++){
-                       printf(" %d ", x[i]);
-               }
-               printf("\n");
-       */
-
-       icount = 0;
-
-       /*    calculate the points on the rational B-spline curve */
-
-       t = k - 1;
-       step = ((double)((npts) - (k - 1))) / ((double)(p1 - 1));
-
-       for(i1=1; i1<=p1; i1++)
-       {
-               if ((double)x[nplusc] - t < 5e-6)
-                       t = (double)x[nplusc];
-
-               rbasis(k, t, npts, x, h, nbasis);      /* generate the basis function for this value of t */
-               /*
-                               printf("t = %f \n",t);
-                               printf("nbasis = ");
-                               for (i = 1; i <= npts; i++){
-                                       printf("%f  ",nbasis[i]);
-                               }
-                               printf("\n");
-               */
-               for(j=1; j<=3; j++)      /* generate a point on the curve */
-               {
-                       jcount = j;
-                       p[icount + j] = 0.0;
-
-                       for(i=1; i<=npts; i++)  /* Do local matrix multiplication */
-                       {
-                               temp = nbasis[i] * b[jcount];
-                               p[icount + j] = p[icount + j] + temp;
-                               /*
-                                                               printf("jcount,nbasis,b,nbasis*b,p = %d %f %f %f %f\n",jcount,nbasis[i],b[jcount],temp,p[icount+j]);
-                               */
-                               jcount = jcount + 3;
-                       }
-               }
-               /*
-                               printf("icount, p %d %f %f %f \n",icount,p[icount+1],p[icount+2],p[icount+3]);
-               */
-               icount = icount + 3;
-               t = t + step;
-       }
-
-       delete[] x;
-       delete[] nbasis;
-}
-
-/**
- * Dumps the spline's data to stdout.
- */
-std::ostream & operator<<(std::ostream & os, const Spline & l)
-{
-       os << " Spline: " << l.getData() << "\n";
-       return os;
-}