1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
// -*- c-basic-offset: 4 -*-
/*
Rosegarden-4
A sequencer and musical notation editor.
This program is Copyright 2000-2005
Guillaume Laurent <glaurent@telegraph-road.org>,
Chris Cannam <cannam@all-day-breakfast.com>,
Richard Bown <bownie@bownie.com>
The moral right of the authors to claim authorship of this work
has been asserted.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version. See the file
COPYING included with this distribution for more information.
*/
#include "spline.h"
Spline::PointList *
Spline::calculate(const QPoint &s, const QPoint &f, const PointList &cp,
QPoint &topLeft, QPoint &bottomRight)
{
if (cp.size() < 2) return 0;
int i;
PointList *acc = new PointList();
QPoint p(s);
topLeft = bottomRight = QPoint(0, 0);
for (i = 1; i < cp.size(); ++i) {
QPoint c(cp[i-1]);
int x = (c.x() + cp[i].x()) / 2;
int y = (c.y() + cp[i].y()) / 2;
QPoint n(x, y);
calculateSegment(acc, p, n, c, topLeft, bottomRight);
p = n;
}
calculateSegment(acc, p, f, cp[i-1], topLeft, bottomRight);
return acc;
}
void
Spline::calculateSegment(PointList *acc,
const QPoint &s, const QPoint &f, const QPoint &c,
QPoint &topLeft, QPoint &bottomRight)
{
int x, y, n;
x = c.x() - s.x();
y = c.y() - s.y();
if (x < 0) x = -x;
if (y < 0) y = -y;
if (x > y) n = x;
else n = y;
x = f.x() - c.x();
y = f.y() - c.y();
if (x < 0) x = -x;
if (y < 0) y = -y;
if (x > y) n += x;
else n += y;
calculateSegmentSub(acc, s, f, c, n, topLeft, bottomRight);
}
void
Spline::calculateSegmentSub(PointList *acc,
const QPoint &s, const QPoint &f, const QPoint &c,
int n, QPoint &topLeft, QPoint &bottomRight)
{
double ax = (double)(f.x() + s.x() - 2 * c.x()) / (double)n;
double ay = (double)(f.y() + s.y() - 2 * c.y()) / (double)n;
double bx = 2.0 * (double)(c.x() - s.x());
double by = 2.0 * (double)(c.y() - s.y());
for (int m = 0; m <= n; ++m) {
int x = s.x() + (int)((m * ((double)m * ax + bx)) / n);
int y = s.y() + (int)((m * ((double)m * ay + by)) / n);
if (x < topLeft.x()) topLeft.setX(x);
if (y < topLeft.y()) topLeft.setY(y);
if (x > bottomRight.x()) bottomRight.setX(x);
if (y > bottomRight.y()) bottomRight.setY(y);
acc->push_back(QPoint(x, y));
}
}
|