|
|
|
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
|
|
|
|
|
|
|
/*
|
|
|
|
Rosegarden
|
|
|
|
A MIDI and audio sequencer and musical notation editor.
|
|
|
|
|
|
|
|
This program is Copyright 2000-2008
|
|
|
|
Guillaume Laurent <glaurent@telegraph-road.org>,
|
|
|
|
Chris Cannam <cannam@all-day-breakfast.com>,
|
|
|
|
Richard Bown <richard.bown@ferventsoftware.com>
|
|
|
|
|
|
|
|
The moral rights of Guillaume Laurent, Chris Cannam, and Richard
|
|
|
|
Bown to claim authorship of this work have been asserted.
|
|
|
|
|
|
|
|
Other copyrights also apply to some parts of this work. Please
|
|
|
|
see the AUTHORS file and individual file headers for details.
|
|
|
|
|
|
|
|
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"
|
|
|
|
|
|
|
|
#include <tqpoint.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace Rosegarden
|
|
|
|
{
|
|
|
|
|
|
|
|
Spline::PointList *
|
|
|
|
|
|
|
|
Spline::calculate(const TQPoint &s, const TQPoint &f, const PointList &cp,
|
|
|
|
TQPoint &topLeft, TQPoint &bottomRight)
|
|
|
|
{
|
|
|
|
if (cp.size() < 2)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
PointList *acc = new PointList();
|
|
|
|
TQPoint p(s);
|
|
|
|
|
|
|
|
topLeft = bottomRight = TQPoint(0, 0);
|
|
|
|
|
|
|
|
for (i = 1; i < cp.size(); ++i) {
|
|
|
|
|
|
|
|
TQPoint c(cp[i - 1]);
|
|
|
|
|
|
|
|
int x = (c.x() + cp[i].x()) / 2;
|
|
|
|
int y = (c.y() + cp[i].y()) / 2;
|
|
|
|
TQPoint 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 TQPoint &s, const TQPoint &f, const TQPoint &c,
|
|
|
|
TQPoint &topLeft, TQPoint &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 TQPoint &s, const TQPoint &f, const TQPoint &c,
|
|
|
|
int n, TQPoint &topLeft, TQPoint &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(TQPoint(x, y));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|