21# include "config_auto.h"
30#include <allheaders.h>
35#define QSPLINE_PRECISION 16
51 xcoords =
new int32_t[
count + 1];
54 for (index = 0; index < segments; index++) {
56 xcoords[index] = xstarts[index];
58 QUAD_COEFFS(coeffs[index * 3], coeffs[index * 3 + 1], coeffs[index * 3 + 2]);
61 xcoords[index] = xstarts[index];
74 int ypts[],
int pointcount,
83 xcoords =
new int32_t[segcount + 1];
84 ptcounts =
new int32_t[segcount + 1];
86 memmove(xcoords, xstarts, (segcount + 1) *
sizeof(int32_t));
88 for (segment = 0, pointindex = 0; pointindex < pointcount; pointindex++) {
89 while (segment < segcount && xpts[pointindex] >= xstarts[segment]) {
92 ptcounts[segment] = ptcounts[segment - 1];
96 while (segment < segcount) {
99 ptcounts[segment] = ptcounts[segment - 1];
102 for (segment = 0; segment < segcount; segment++) {
105 pointindex = ptcounts[segment];
106 if (pointindex > 0 && xpts[pointindex] != xpts[pointindex - 1] &&
107 xpts[pointindex] != xstarts[segment]) {
108 qlsq.
add(xstarts[segment],
109 ypts[pointindex - 1] + (ypts[pointindex] - ypts[pointindex - 1]) *
110 (xstarts[segment] - xpts[pointindex - 1]) /
111 (xpts[pointindex] - xpts[pointindex - 1]));
113 for (; pointindex < ptcounts[segment + 1]; pointindex++) {
114 qlsq.
add(xpts[pointindex], ypts[pointindex]);
116 if (pointindex > 0 && pointindex < pointcount && xpts[pointindex] != xstarts[segment + 1]) {
117 qlsq.
add(xstarts[segment + 1],
118 ypts[pointindex - 1] + (ypts[pointindex] - ypts[pointindex - 1]) *
119 (xstarts[segment + 1] - xpts[pointindex - 1]) /
120 (xpts[pointindex] - xpts[pointindex - 1]));
123 quadratics[segment].
a = qlsq.
get_a();
124 quadratics[segment].
b = qlsq.
get_b();
125 quadratics[segment].
c = qlsq.
get_c();
140 quadratics =
nullptr;
166 segments = source.segments;
167 xcoords =
new int32_t[segments + 1];
169 memmove(xcoords, source.xcoords, (segments + 1) *
sizeof(int32_t));
170 memmove(quadratics, source.quadratics, segments *
sizeof(
QUAD_COEFFS));
186 index1 = spline_index(x1);
187 index2 = spline_index(x2);
189 while (index1 < index2) {
190 total +=
static_cast<double>(quadratics[index1 + 1].
y(
static_cast<float>(xcoords[index1 + 1])));
191 total -=
static_cast<double>(quadratics[index1].
y(
static_cast<float>(xcoords[index1 + 1])));
208 index = spline_index(
x);
209 return quadratics[index].
y(
x);
218int32_t QSPLINE::spline_index(
227 while (top - bottom > 1) {
228 index = (top + bottom) / 2;
229 if (
x >= xcoords[index]) {
248 int16_t x_shift = vec.
x();
250 for (segment = 0; segment < segments; segment++) {
251 xcoords[segment] += x_shift;
252 quadratics[segment].
move(vec);
254 xcoords[segment] += x_shift;
268 int leftlimit = xcoords[1];
269 int rightlimit = xcoords[segments - 1];
271 return !(spline2->segments < 3 ||
272 spline2->xcoords[1] > leftlimit + fraction * (rightlimit - leftlimit) ||
273 spline2->xcoords[spline2->segments - 1] <
274 rightlimit - fraction * (rightlimit - leftlimit));
295 increment = xmin < xcoords[0] ? 1 : 0;
296 if (xmax > xcoords[segments]) {
299 if (increment == 0) {
302 xstarts =
new int32_t[segments + 1 + increment];
304 if (xmin < xcoords[0]) {
307 quads[0].
b = gradient;
308 quads[0].
c =
y(xcoords[0]) - quads[0].
b * xcoords[0];
313 for (segment = 0; segment < segments; segment++) {
314 xstarts[dest_segment] = xcoords[segment];
315 quads[dest_segment] = quadratics[segment];
318 xstarts[dest_segment] = xcoords[segment];
319 if (xmax > xcoords[segments]) {
320 quads[dest_segment].
a = 0;
321 quads[dest_segment].
b = gradient;
322 quads[dest_segment].
c =
y(xcoords[segments]) - quads[dest_segment].
b * xcoords[segments];
324 xstarts[dest_segment] = xmax + 1;
326 segments = dest_segment;
339#ifndef GRAPHICS_DISABLED
350 for (segment = 0; segment < segments; segment++) {
351 increment =
static_cast<double>(xcoords[segment + 1] - xcoords[segment]) /
QSPLINE_PRECISION;
352 x = xcoords[segment];
354 if (segment == 0 &&
step == 0) {
357 window->
DrawTo(
x, quadratics[segment].
y(
x));
366 if (pix ==
nullptr) {
374 auto height =
static_cast<double>(pixGetHeight(pix));
376 const int kLineWidth = 5;
378 for (segment = 0; segment < segments; segment++) {
379 increment =
static_cast<double>((xcoords[segment + 1] - xcoords[segment])) /
QSPLINE_PRECISION;
380 x = xcoords[segment];
382 double y = height - quadratics[segment].
y(
x);
383 ptaAddPt(points,
x,
y);
388 switch (pixGetDepth(pix)) {
390 pixRenderPolyline(pix, points, kLineWidth, L_SET_PIXELS, 1);
393 pixRenderPolylineArb(pix, points, kLineWidth, 255, 0, 0, 1);
396 pixRenderPolyline(pix, points, kLineWidth, L_CLEAR_PIXELS, 1);
#define QSPLINE_PRECISION
TDimension x() const
access function
void add(double x, double y)
void plot(ScrollView *window, ScrollView::Color colour) const
bool overlap(QSPLINE *spline2, double fraction)
double step(double x1, double x2)
void extrapolate(double gradient, int left, int right)
QSPLINE & operator=(const QSPLINE &source)
void SetCursor(int x, int y)
void DrawTo(int x, int y)