|
rpm-build |
8267b0 |
/*
|
|
rpm-build |
8267b0 |
libspiro - conversion between spiro control points and bezier's
|
|
rpm-build |
8267b0 |
CopySpiroPointType.RIGHT (C) 2007 Raph Levien
|
|
rpm-build |
8267b0 |
2009 converted to Java by George Williams
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
This program is free software; you can redistribute it and/or
|
|
rpm-build |
8267b0 |
modify it under the terms of the GNU General Public License
|
|
rpm-build |
8267b0 |
as published by the Free Software Foundation; either version 2
|
|
rpm-build |
8267b0 |
of the License, or (at your option) any later version.
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
This program is distributed in the hope that it will be useful,
|
|
rpm-build |
8267b0 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
8267b0 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
rpm-build |
8267b0 |
GNU General Public License for more details.
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
You should have received a copy of the GNU General Public License
|
|
rpm-build |
8267b0 |
along with this program; if not, write to the Free Software
|
|
rpm-build |
8267b0 |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
rpm-build |
8267b0 |
02110-1301, USA.
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
*/
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
package net.sourceforge.libspiro;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
import java.lang.Math;
|
|
rpm-build |
8267b0 |
import java.util.ArrayList;
|
|
rpm-build |
8267b0 |
import java.io.Writer;
|
|
rpm-build |
8267b0 |
import java.io.BufferedReader;
|
|
rpm-build |
8267b0 |
import java.io.IOException;
|
|
rpm-build |
8267b0 |
import static net.sourceforge.libspiro.SpiroPointType.*;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
public class Spiro {
|
|
rpm-build |
8267b0 |
// Spiro has no constructors. It simply provides (static) methods to convert
|
|
rpm-build |
8267b0 |
// between a spiro contour (an array of SpiroCP) and a cubic Bezier contour
|
|
rpm-build |
8267b0 |
// and routines for reading/writing plate files
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected class spiro_seg {
|
|
rpm-build |
8267b0 |
double x;
|
|
rpm-build |
8267b0 |
double y;
|
|
rpm-build |
8267b0 |
SpiroPointType type;
|
|
rpm-build |
8267b0 |
double bend_th;
|
|
rpm-build |
8267b0 |
double [/*4*/] ks;
|
|
rpm-build |
8267b0 |
double seg_ch;
|
|
rpm-build |
8267b0 |
double seg_th;
|
|
rpm-build |
8267b0 |
double l;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected class bandmat {
|
|
rpm-build |
8267b0 |
double [/*11*/] a; /* band-diagonal matrix */
|
|
rpm-build |
8267b0 |
double [/*5 */] al; /* lower part of band-diagonal decomposition */
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
void copyfrom(final bandmat from) {
|
|
rpm-build |
8267b0 |
System.arraycopy(a ,0,from.a ,0,11);
|
|
rpm-build |
8267b0 |
System.arraycopy(al,0,from.al,0,5 );
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static void arraycopy(bandmat [] from, int fromi, bandmat [] to, int toi, int nelem ) {
|
|
rpm-build |
8267b0 |
int i;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for ( i=0; i
|
|
rpm-build |
8267b0 |
to[i+toi].copyfrom( from[i+fromi] );
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static final int N = 4;
|
|
rpm-build |
8267b0 |
/* ORDER = 12; */
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* Integrate polynomial spiral curve over range -.5 .. .5. */
|
|
rpm-build |
8267b0 |
static protected void
|
|
rpm-build |
8267b0 |
integrate_spiro(final double [/*4*/] ks, double [/*2*/] xy) {
|
|
rpm-build |
8267b0 |
double th1 = ks[0];
|
|
rpm-build |
8267b0 |
double th2 = .5 * ks[1];
|
|
rpm-build |
8267b0 |
double th3 = (1./6) * ks[2];
|
|
rpm-build |
8267b0 |
double th4 = (1./24) * ks[3];
|
|
rpm-build |
8267b0 |
double x, y;
|
|
rpm-build |
8267b0 |
double ds = 1. / N;
|
|
rpm-build |
8267b0 |
double ds2 = ds * ds;
|
|
rpm-build |
8267b0 |
double ds3 = ds2 * ds;
|
|
rpm-build |
8267b0 |
double k0 = ks[0] * ds;
|
|
rpm-build |
8267b0 |
double k1 = ks[1] * ds;
|
|
rpm-build |
8267b0 |
double k2 = ks[2] * ds;
|
|
rpm-build |
8267b0 |
double k3 = ks[3] * ds;
|
|
rpm-build |
8267b0 |
int i;
|
|
rpm-build |
8267b0 |
double s = .5 * ds - .5;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
x = 0;
|
|
rpm-build |
8267b0 |
y = 0;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for (i = 0; i < N; i++) {
|
|
rpm-build |
8267b0 |
double u, v;
|
|
rpm-build |
8267b0 |
double km0, km1, km2, km3;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
km0 = (((1./6) * k3 * s + .5 * k2) * s + k1) * s + k0;
|
|
rpm-build |
8267b0 |
km1 = ((.5 * k3 * s + k2) * s + k1) * ds;
|
|
rpm-build |
8267b0 |
km2 = (k3 * s + k2) * ds2;
|
|
rpm-build |
8267b0 |
km3 = k3 * ds3;
|
|
rpm-build |
8267b0 |
{
|
|
rpm-build |
8267b0 |
double t1_1 = km0;
|
|
rpm-build |
8267b0 |
double t1_2 = .5 * km1;
|
|
rpm-build |
8267b0 |
double t1_3 = (1./6) * km2;
|
|
rpm-build |
8267b0 |
double t1_4 = (1./24) * km3;
|
|
rpm-build |
8267b0 |
double t2_2 = t1_1 * t1_1;
|
|
rpm-build |
8267b0 |
double t2_3 = 2 * (t1_1 * t1_2);
|
|
rpm-build |
8267b0 |
double t2_4 = 2 * (t1_1 * t1_3) + t1_2 * t1_2;
|
|
rpm-build |
8267b0 |
double t2_5 = 2 * (t1_1 * t1_4 + t1_2 * t1_3);
|
|
rpm-build |
8267b0 |
double t2_6 = 2 * (t1_2 * t1_4) + t1_3 * t1_3;
|
|
rpm-build |
8267b0 |
double t2_7 = 2 * (t1_3 * t1_4);
|
|
rpm-build |
8267b0 |
double t2_8 = t1_4 * t1_4;
|
|
rpm-build |
8267b0 |
double t3_4 = t2_2 * t1_2 + t2_3 * t1_1;
|
|
rpm-build |
8267b0 |
double t3_6 = t2_2 * t1_4 + t2_3 * t1_3 + t2_4 * t1_2 + t2_5 * t1_1;
|
|
rpm-build |
8267b0 |
double t3_8 = t2_4 * t1_4 + t2_5 * t1_3 + t2_6 * t1_2 + t2_7 * t1_1;
|
|
rpm-build |
8267b0 |
double t3_10 = t2_6 * t1_4 + t2_7 * t1_3 + t2_8 * t1_2;
|
|
rpm-build |
8267b0 |
double t4_4 = t2_2 * t2_2;
|
|
rpm-build |
8267b0 |
double t4_5 = 2 * (t2_2 * t2_3);
|
|
rpm-build |
8267b0 |
double t4_6 = 2 * (t2_2 * t2_4) + t2_3 * t2_3;
|
|
rpm-build |
8267b0 |
double t4_7 = 2 * (t2_2 * t2_5 + t2_3 * t2_4);
|
|
rpm-build |
8267b0 |
double t4_8 = 2 * (t2_2 * t2_6 + t2_3 * t2_5) + t2_4 * t2_4;
|
|
rpm-build |
8267b0 |
double t4_9 = 2 * (t2_2 * t2_7 + t2_3 * t2_6 + t2_4 * t2_5);
|
|
rpm-build |
8267b0 |
double t4_10 = 2 * (t2_2 * t2_8 + t2_3 * t2_7 + t2_4 * t2_6) + t2_5 * t2_5;
|
|
rpm-build |
8267b0 |
double t5_6 = t4_4 * t1_2 + t4_5 * t1_1;
|
|
rpm-build |
8267b0 |
double t5_8 = t4_4 * t1_4 + t4_5 * t1_3 + t4_6 * t1_2 + t4_7 * t1_1;
|
|
rpm-build |
8267b0 |
double t5_10 = t4_6 * t1_4 + t4_7 * t1_3 + t4_8 * t1_2 + t4_9 * t1_1;
|
|
rpm-build |
8267b0 |
double t6_6 = t4_4 * t2_2;
|
|
rpm-build |
8267b0 |
double t6_7 = t4_4 * t2_3 + t4_5 * t2_2;
|
|
rpm-build |
8267b0 |
double t6_8 = t4_4 * t2_4 + t4_5 * t2_3 + t4_6 * t2_2;
|
|
rpm-build |
8267b0 |
double t6_9 = t4_4 * t2_5 + t4_5 * t2_4 + t4_6 * t2_3 + t4_7 * t2_2;
|
|
rpm-build |
8267b0 |
double t6_10 = t4_4 * t2_6 + t4_5 * t2_5 + t4_6 * t2_4 + t4_7 * t2_3 + t4_8 * t2_2;
|
|
rpm-build |
8267b0 |
double t7_8 = t6_6 * t1_2 + t6_7 * t1_1;
|
|
rpm-build |
8267b0 |
double t7_10 = t6_6 * t1_4 + t6_7 * t1_3 + t6_8 * t1_2 + t6_9 * t1_1;
|
|
rpm-build |
8267b0 |
double t8_8 = t6_6 * t2_2;
|
|
rpm-build |
8267b0 |
double t8_9 = t6_6 * t2_3 + t6_7 * t2_2;
|
|
rpm-build |
8267b0 |
double t8_10 = t6_6 * t2_4 + t6_7 * t2_3 + t6_8 * t2_2;
|
|
rpm-build |
8267b0 |
double t9_10 = t8_8 * t1_2 + t8_9 * t1_1;
|
|
rpm-build |
8267b0 |
double t10_10 = t8_8 * t2_2;
|
|
rpm-build |
8267b0 |
u = 1;
|
|
rpm-build |
8267b0 |
v = 0;
|
|
rpm-build |
8267b0 |
v += (1./12) * t1_2 + (1./80) * t1_4;
|
|
rpm-build |
8267b0 |
u -= (1./24) * t2_2 + (1./160) * t2_4 + (1./896) * t2_6 + (1./4608) * t2_8;
|
|
rpm-build |
8267b0 |
v -= (1./480) * t3_4 + (1./2688) * t3_6 + (1./13824) * t3_8 + (1./67584) * t3_10;
|
|
rpm-build |
8267b0 |
u += (1./1920) * t4_4 + (1./10752) * t4_6 + (1./55296) * t4_8 + (1./270336) * t4_10;
|
|
rpm-build |
8267b0 |
v += (1./53760) * t5_6 + (1./276480) * t5_8 + (1./1.35168e+06) * t5_10;
|
|
rpm-build |
8267b0 |
u -= (1./322560) * t6_6 + (1./1.65888e+06) * t6_8 + (1./8.11008e+06) * t6_10;
|
|
rpm-build |
8267b0 |
v -= (1./1.16122e+07) * t7_8 + (1./5.67706e+07) * t7_10;
|
|
rpm-build |
8267b0 |
u += (1./9.28973e+07) * t8_8 + (1./4.54164e+08) * t8_10;
|
|
rpm-build |
8267b0 |
v += (1./4.08748e+09) * t9_10;
|
|
rpm-build |
8267b0 |
u -= (1./4.08748e+10) * t10_10;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
{
|
|
rpm-build |
8267b0 |
double th = (((th4 * s + th3) * s + th2) * s + th1) * s;
|
|
rpm-build |
8267b0 |
double cth = Math.cos(th);
|
|
rpm-build |
8267b0 |
double sth = Math.sin(th);
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
x += cth * u - sth * v;
|
|
rpm-build |
8267b0 |
y += cth * v + sth * u;
|
|
rpm-build |
8267b0 |
s += ds;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
xy[0] = x * ds;
|
|
rpm-build |
8267b0 |
xy[1] = y * ds;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected double
|
|
rpm-build |
8267b0 |
compute_ends(final double [/*4*/] ks, double [/*2*/][/*4*/] ends, double seg_ch) {
|
|
rpm-build |
8267b0 |
double [/*2*/] xy = new double[2];
|
|
rpm-build |
8267b0 |
double ch, th;
|
|
rpm-build |
8267b0 |
double l, l2, l3;
|
|
rpm-build |
8267b0 |
double th_even, th_odd;
|
|
rpm-build |
8267b0 |
double k0_even, k0_odd;
|
|
rpm-build |
8267b0 |
double k1_even, k1_odd;
|
|
rpm-build |
8267b0 |
double k2_even, k2_odd;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
integrate_spiro(ks, xy);
|
|
rpm-build |
8267b0 |
ch = Math.hypot(xy[0], xy[1]);
|
|
rpm-build |
8267b0 |
th = Math.atan2(xy[1], xy[0]);
|
|
rpm-build |
8267b0 |
l = ch / seg_ch;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
th_even = .5 * ks[0] + (1./48) * ks[2];
|
|
rpm-build |
8267b0 |
th_odd = .125 * ks[1] + (1./384) * ks[3] - th;
|
|
rpm-build |
8267b0 |
ends[0][0] = th_even - th_odd;
|
|
rpm-build |
8267b0 |
ends[1][0] = th_even + th_odd;
|
|
rpm-build |
8267b0 |
k0_even = l * (ks[0] + .125 * ks[2]);
|
|
rpm-build |
8267b0 |
k0_odd = l * (.5 * ks[1] + (1./48) * ks[3]);
|
|
rpm-build |
8267b0 |
ends[0][1] = k0_even - k0_odd;
|
|
rpm-build |
8267b0 |
ends[1][1] = k0_even + k0_odd;
|
|
rpm-build |
8267b0 |
l2 = l * l;
|
|
rpm-build |
8267b0 |
k1_even = l2 * (ks[1] + .125 * ks[3]);
|
|
rpm-build |
8267b0 |
k1_odd = l2 * .5 * ks[2];
|
|
rpm-build |
8267b0 |
ends[0][2] = k1_even - k1_odd;
|
|
rpm-build |
8267b0 |
ends[1][2] = k1_even + k1_odd;
|
|
rpm-build |
8267b0 |
l3 = l2 * l;
|
|
rpm-build |
8267b0 |
k2_even = l3 * ks[2];
|
|
rpm-build |
8267b0 |
k2_odd = l3 * .5 * ks[3];
|
|
rpm-build |
8267b0 |
ends[0][3] = k2_even - k2_odd;
|
|
rpm-build |
8267b0 |
ends[1][3] = k2_even + k2_odd;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
return l;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected void
|
|
rpm-build |
8267b0 |
compute_pderivs(final spiro_seg s, double [/*2*/][/*4*/] ends,
|
|
rpm-build |
8267b0 |
double [/*4*/][/*2*/][/*4*/] derivs, int jinc) {
|
|
rpm-build |
8267b0 |
double recip_d = 2e6;
|
|
rpm-build |
8267b0 |
double delta = 1./ recip_d;
|
|
rpm-build |
8267b0 |
double [] try_ks = new double[4];
|
|
rpm-build |
8267b0 |
double [][] try_ends = new double [2][4];
|
|
rpm-build |
8267b0 |
int i, j, k;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
compute_ends(s.ks, ends, s.seg_ch);
|
|
rpm-build |
8267b0 |
for (i = 0; i < jinc; i++) {
|
|
rpm-build |
8267b0 |
for (j = 0; j < 4; j++)
|
|
rpm-build |
8267b0 |
try_ks[j] = s.ks[j];
|
|
rpm-build |
8267b0 |
try_ks[i] += delta;
|
|
rpm-build |
8267b0 |
compute_ends(try_ks, try_ends, s.seg_ch);
|
|
rpm-build |
8267b0 |
for (k = 0; k < 2; k++)
|
|
rpm-build |
8267b0 |
for (j = 0; j < 4; j++)
|
|
rpm-build |
8267b0 |
derivs[j][k][i] = recip_d * (try_ends[k][j] - ends[k][j]);
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected double
|
|
rpm-build |
8267b0 |
mod_2pi(double th) {
|
|
rpm-build |
8267b0 |
double u = th / (2 * Math.PI);
|
|
rpm-build |
8267b0 |
return 2 * Math.PI * (u - Math.floor(u + 0.5));
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected spiro_seg []
|
|
rpm-build |
8267b0 |
setup_path(final SpiroCP [] src, int n) {
|
|
rpm-build |
8267b0 |
int n_seg = src[0].type == OPEN ? n - 1 : n;
|
|
rpm-build |
8267b0 |
spiro_seg [] r = new spiro_seg[n_seg +1];
|
|
rpm-build |
8267b0 |
int i;
|
|
rpm-build |
8267b0 |
int ilast;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for (i = 0; i < n_seg; i++) {
|
|
rpm-build |
8267b0 |
r[i] = new spiro_seg();
|
|
rpm-build |
8267b0 |
r[i].x = src[i].x;
|
|
rpm-build |
8267b0 |
r[i].y = src[i].y;
|
|
rpm-build |
8267b0 |
r[i].type = src[i].type;
|
|
rpm-build |
8267b0 |
r[i].ks = new double[] { 0., 0., 0., 0. };
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
r[n_seg] = new spiro_seg();
|
|
rpm-build |
8267b0 |
r[n_seg].x = src[n_seg % n].x;
|
|
rpm-build |
8267b0 |
r[n_seg].y = src[n_seg % n].y;
|
|
rpm-build |
8267b0 |
r[n_seg].type = src[n_seg % n].type;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for (i = 0; i < n_seg; i++) {
|
|
rpm-build |
8267b0 |
double dx = r[i + 1].x - r[i].x;
|
|
rpm-build |
8267b0 |
double dy = r[i + 1].y - r[i].y;
|
|
rpm-build |
8267b0 |
r[i].seg_ch = Math.hypot(dx, dy);
|
|
rpm-build |
8267b0 |
r[i].seg_th = Math.atan2(dy, dx);
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
ilast = n_seg - 1;
|
|
rpm-build |
8267b0 |
for (i = 0; i < n_seg; i++) {
|
|
rpm-build |
8267b0 |
if (r[i].type == OPEN || r[i].type == OPEN_END || r[i].type == CORNER)
|
|
rpm-build |
8267b0 |
r[i].bend_th = 0.;
|
|
rpm-build |
8267b0 |
else
|
|
rpm-build |
8267b0 |
r[i].bend_th = mod_2pi(r[i].seg_th - r[ilast].seg_th);
|
|
rpm-build |
8267b0 |
ilast = i;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
return r;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected void
|
|
rpm-build |
8267b0 |
bandec11(bandmat [] m, int [] perm, int n) {
|
|
rpm-build |
8267b0 |
int i, j, k;
|
|
rpm-build |
8267b0 |
int l;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* pack top triangle to the LEFT. */
|
|
rpm-build |
8267b0 |
for (i = 0; i < 5; i++) {
|
|
rpm-build |
8267b0 |
for (j = 0; j < i + 6; j++)
|
|
rpm-build |
8267b0 |
m[i].a[j] = m[i].a[j + 5 - i];
|
|
rpm-build |
8267b0 |
for (; j < 11; j++)
|
|
rpm-build |
8267b0 |
m[i].a[j] = 0.;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
l = 5;
|
|
rpm-build |
8267b0 |
for (k = 0; k < n; k++) {
|
|
rpm-build |
8267b0 |
int pivot = k;
|
|
rpm-build |
8267b0 |
double pivot_val = m[k].a[0];
|
|
rpm-build |
8267b0 |
double pivot_scale;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
l = l < n ? l + 1 : n;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for (j = k + 1; j < l; j++)
|
|
rpm-build |
8267b0 |
if (Math.abs(m[j].a[0]) > Math.abs(pivot_val)) {
|
|
rpm-build |
8267b0 |
pivot_val = m[j].a[0];
|
|
rpm-build |
8267b0 |
pivot = j;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
perm[k] = pivot;
|
|
rpm-build |
8267b0 |
if (pivot != k) {
|
|
rpm-build |
8267b0 |
for (j = 0; j < 11; j++) {
|
|
rpm-build |
8267b0 |
double tmp = m[k].a[j];
|
|
rpm-build |
8267b0 |
m[k].a[j] = m[pivot].a[j];
|
|
rpm-build |
8267b0 |
m[pivot].a[j] = tmp;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
if (Math.abs(pivot_val) < 1e-12) pivot_val = 1e-12;
|
|
rpm-build |
8267b0 |
pivot_scale = 1. / pivot_val;
|
|
rpm-build |
8267b0 |
for (i = k + 1; i < l; i++) {
|
|
rpm-build |
8267b0 |
double x = m[i].a[0] * pivot_scale;
|
|
rpm-build |
8267b0 |
m[k].al[i - k - 1] = x;
|
|
rpm-build |
8267b0 |
for (j = 1; j < 11; j++)
|
|
rpm-build |
8267b0 |
m[i].a[j - 1] = m[i].a[j] - x * m[k].a[j];
|
|
rpm-build |
8267b0 |
m[i].a[10] = 0.;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected void
|
|
rpm-build |
8267b0 |
banbks11(final bandmat [] m, final int [] perm, double [] v, int n) {
|
|
rpm-build |
8267b0 |
int i, k, l;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* forward substitution */
|
|
rpm-build |
8267b0 |
l = 5;
|
|
rpm-build |
8267b0 |
for (k = 0; k < n; k++) {
|
|
rpm-build |
8267b0 |
i = perm[k];
|
|
rpm-build |
8267b0 |
if (i != k) {
|
|
rpm-build |
8267b0 |
double tmp = v[k];
|
|
rpm-build |
8267b0 |
v[k] = v[i];
|
|
rpm-build |
8267b0 |
v[i] = tmp;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
if (l < n) l++;
|
|
rpm-build |
8267b0 |
for (i = k + 1; i < l; i++)
|
|
rpm-build |
8267b0 |
v[i] -= m[k].al[i - k - 1] * v[k];
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* back substitution */
|
|
rpm-build |
8267b0 |
l = 1;
|
|
rpm-build |
8267b0 |
for (i = n - 1; i >= 0; i--) {
|
|
rpm-build |
8267b0 |
double x = v[i];
|
|
rpm-build |
8267b0 |
for (k = 1; k < l; k++)
|
|
rpm-build |
8267b0 |
x -= m[i].a[k] * v[k + i];
|
|
rpm-build |
8267b0 |
v[i] = x / m[i].a[0];
|
|
rpm-build |
8267b0 |
if (l < 11) l++;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected int
|
|
rpm-build |
8267b0 |
compute_jinc(SpiroPointType ty0, SpiroPointType ty1) {
|
|
rpm-build |
8267b0 |
if (ty0 == G4 || ty1 == G4 ||
|
|
rpm-build |
8267b0 |
ty0 == RIGHT || ty1 == LEFT)
|
|
rpm-build |
8267b0 |
return 4;
|
|
rpm-build |
8267b0 |
else if (ty0 == G2 && ty1 == G2)
|
|
rpm-build |
8267b0 |
return 2;
|
|
rpm-build |
8267b0 |
else if (((ty0 == OPEN || ty0 == CORNER || ty0 == LEFT) && ty1 == G2) ||
|
|
rpm-build |
8267b0 |
(ty0 == G2 && (ty1 == OPEN_END || ty1 == CORNER || ty1 == RIGHT)))
|
|
rpm-build |
8267b0 |
return 1;
|
|
rpm-build |
8267b0 |
else
|
|
rpm-build |
8267b0 |
return 0;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected int
|
|
rpm-build |
8267b0 |
count_vec(final spiro_seg [] s, int nseg) {
|
|
rpm-build |
8267b0 |
int i;
|
|
rpm-build |
8267b0 |
int n = 0;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for (i = 0; i < nseg; i++)
|
|
rpm-build |
8267b0 |
n += compute_jinc(s[i].type, s[i + 1].type);
|
|
rpm-build |
8267b0 |
return n;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected void
|
|
rpm-build |
8267b0 |
add_mat_line(bandmat [] m, double [] v,
|
|
rpm-build |
8267b0 |
double [/*4*/] derivs, double x, double y, int j, int jj, int jinc,
|
|
rpm-build |
8267b0 |
int nmat) {
|
|
rpm-build |
8267b0 |
int k;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
if (jj >= 0) {
|
|
rpm-build |
8267b0 |
int joff = (j + 5 - jj + nmat) % nmat;
|
|
rpm-build |
8267b0 |
if (nmat < 6) {
|
|
rpm-build |
8267b0 |
joff = j + 5 - jj;
|
|
rpm-build |
8267b0 |
} else if (nmat == 6) {
|
|
rpm-build |
8267b0 |
joff = 2 + (j + 3 - jj + nmat) % nmat;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
v[jj] += x;
|
|
rpm-build |
8267b0 |
for (k = 0; k < jinc; k++)
|
|
rpm-build |
8267b0 |
m[jj].a[joff + k] += y * derivs[k];
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected double
|
|
rpm-build |
8267b0 |
spiro_iter(spiro_seg [] s, bandmat [] m, int [] perm, double [] v, int n) {
|
|
rpm-build |
8267b0 |
boolean cyclic = s[0].type != OPEN && s[0].type != CORNER;
|
|
rpm-build |
8267b0 |
int i, j, jj;
|
|
rpm-build |
8267b0 |
int nmat = count_vec(s, n);
|
|
rpm-build |
8267b0 |
double norm;
|
|
rpm-build |
8267b0 |
int n_invert;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for (i = 0; i < nmat; i++) {
|
|
rpm-build |
8267b0 |
v[i] = 0.;
|
|
rpm-build |
8267b0 |
m[i] = new bandmat();
|
|
rpm-build |
8267b0 |
m[i].a = new double[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
rpm-build |
8267b0 |
m[i].al = new double[] { 0, 0, 0, 0, 0 };
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
j = 0;
|
|
rpm-build |
8267b0 |
if (s[0].type == G4)
|
|
rpm-build |
8267b0 |
jj = nmat - 2;
|
|
rpm-build |
8267b0 |
else if (s[0].type == G2)
|
|
rpm-build |
8267b0 |
jj = nmat - 1;
|
|
rpm-build |
8267b0 |
else
|
|
rpm-build |
8267b0 |
jj = 0;
|
|
rpm-build |
8267b0 |
for (i = 0; i < n; i++) {
|
|
rpm-build |
8267b0 |
SpiroPointType ty0 = s[i].type;
|
|
rpm-build |
8267b0 |
SpiroPointType ty1 = s[i + 1].type;
|
|
rpm-build |
8267b0 |
int jinc = compute_jinc(ty0, ty1);
|
|
rpm-build |
8267b0 |
double th = s[i].bend_th;
|
|
rpm-build |
8267b0 |
double [][] ends = new double[2][4];
|
|
rpm-build |
8267b0 |
double [][][] derivs = new double[4][2][4];
|
|
rpm-build |
8267b0 |
int jthl = -1, jk0l = -1, jk1l = -1, jk2l = -1;
|
|
rpm-build |
8267b0 |
int jthr = -1, jk0r = -1, jk1r = -1, jk2r = -1;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
compute_pderivs(s[i], ends, derivs, jinc);
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* constraints crossing LEFT */
|
|
rpm-build |
8267b0 |
if (ty0 == G4 || ty0 == G2 || ty0 == LEFT || ty0 == RIGHT) {
|
|
rpm-build |
8267b0 |
jthl = jj++;
|
|
rpm-build |
8267b0 |
jj %= nmat;
|
|
rpm-build |
8267b0 |
jk0l = jj++;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
if (ty0 == G4) {
|
|
rpm-build |
8267b0 |
jj %= nmat;
|
|
rpm-build |
8267b0 |
jk1l = jj++;
|
|
rpm-build |
8267b0 |
jk2l = jj++;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* constraints on LEFT */
|
|
rpm-build |
8267b0 |
if ((ty0 == LEFT || ty0 == CORNER || ty0 == OPEN || ty0 == G2) &&
|
|
rpm-build |
8267b0 |
jinc == 4) {
|
|
rpm-build |
8267b0 |
if (ty0 != G2)
|
|
rpm-build |
8267b0 |
jk1l = jj++;
|
|
rpm-build |
8267b0 |
jk2l = jj++;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* constraints on RIGHT */
|
|
rpm-build |
8267b0 |
if ((ty1 == RIGHT || ty1 == CORNER || ty1 == OPEN_END || ty1 == G2) &&
|
|
rpm-build |
8267b0 |
jinc == 4) {
|
|
rpm-build |
8267b0 |
if (ty1 != G2)
|
|
rpm-build |
8267b0 |
jk1r = jj++;
|
|
rpm-build |
8267b0 |
jk2r = jj++;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* constraints crossing RIGHT */
|
|
rpm-build |
8267b0 |
if (ty1 == G4 || ty1 == G2 || ty1 == LEFT || ty1 == RIGHT) {
|
|
rpm-build |
8267b0 |
jthr = jj;
|
|
rpm-build |
8267b0 |
jk0r = (jj + 1) % nmat;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
if (ty1 == G4) {
|
|
rpm-build |
8267b0 |
jk1r = (jj + 2) % nmat;
|
|
rpm-build |
8267b0 |
jk2r = (jj + 3) % nmat;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
add_mat_line(m, v, derivs[0][0], th - ends[0][0], 1, j, jthl, jinc, nmat);
|
|
rpm-build |
8267b0 |
add_mat_line(m, v, derivs[1][0], ends[0][1], -1, j, jk0l, jinc, nmat);
|
|
rpm-build |
8267b0 |
add_mat_line(m, v, derivs[2][0], ends[0][2], -1, j, jk1l, jinc, nmat);
|
|
rpm-build |
8267b0 |
add_mat_line(m, v, derivs[3][0], ends[0][3], -1, j, jk2l, jinc, nmat);
|
|
rpm-build |
8267b0 |
add_mat_line(m, v, derivs[0][1], -ends[1][0], 1, j, jthr, jinc, nmat);
|
|
rpm-build |
8267b0 |
add_mat_line(m, v, derivs[1][1], -ends[1][1], 1, j, jk0r, jinc, nmat);
|
|
rpm-build |
8267b0 |
add_mat_line(m, v, derivs[2][1], -ends[1][2], 1, j, jk1r, jinc, nmat);
|
|
rpm-build |
8267b0 |
add_mat_line(m, v, derivs[3][1], -ends[1][3], 1, j, jk2r, jinc, nmat);
|
|
rpm-build |
8267b0 |
j += jinc;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
if (cyclic) {
|
|
rpm-build |
8267b0 |
bandmat.arraycopy(m, 0, m, nmat, nmat );
|
|
rpm-build |
8267b0 |
bandmat.arraycopy(m, 0, m, 2 * nmat, nmat );
|
|
rpm-build |
8267b0 |
System.arraycopy(v, 0, v, nmat, nmat);
|
|
rpm-build |
8267b0 |
System.arraycopy(v, 0, v, 2 * nmat, nmat);
|
|
rpm-build |
8267b0 |
n_invert = 3 * nmat;
|
|
rpm-build |
8267b0 |
j = nmat;
|
|
rpm-build |
8267b0 |
} else {
|
|
rpm-build |
8267b0 |
n_invert = nmat;
|
|
rpm-build |
8267b0 |
j = 0;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
bandec11(m, perm, n_invert);
|
|
rpm-build |
8267b0 |
banbks11(m, perm, v, n_invert);
|
|
rpm-build |
8267b0 |
norm = 0.;
|
|
rpm-build |
8267b0 |
for (i = 0; i < n; i++) {
|
|
rpm-build |
8267b0 |
SpiroPointType ty0 = s[i].type;
|
|
rpm-build |
8267b0 |
SpiroPointType ty1 = s[i + 1].type;
|
|
rpm-build |
8267b0 |
int jinc = compute_jinc(ty0, ty1);
|
|
rpm-build |
8267b0 |
int k;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for (k = 0; k < jinc; k++) {
|
|
rpm-build |
8267b0 |
double dk = v[j++];
|
|
rpm-build |
8267b0 |
s[i].ks[k] += dk;
|
|
rpm-build |
8267b0 |
norm += dk * dk;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
return norm;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected int
|
|
rpm-build |
8267b0 |
solve_spiro(spiro_seg [] s, int nseg) {
|
|
rpm-build |
8267b0 |
bandmat [] m;
|
|
rpm-build |
8267b0 |
double [] v;
|
|
rpm-build |
8267b0 |
int [] perm;
|
|
rpm-build |
8267b0 |
int nmat = count_vec(s, nseg);
|
|
rpm-build |
8267b0 |
int n_alloc = nmat;
|
|
rpm-build |
8267b0 |
double norm;
|
|
rpm-build |
8267b0 |
int i;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
if (nmat == 0)
|
|
rpm-build |
8267b0 |
return 0;
|
|
rpm-build |
8267b0 |
if (s[0].type != OPEN && s[0].type != CORNER)
|
|
rpm-build |
8267b0 |
n_alloc *= 3;
|
|
rpm-build |
8267b0 |
if (n_alloc < 5)
|
|
rpm-build |
8267b0 |
n_alloc = 5;
|
|
rpm-build |
8267b0 |
m = new bandmat[n_alloc];
|
|
rpm-build |
8267b0 |
v = new double [n_alloc];
|
|
rpm-build |
8267b0 |
perm = new int [n_alloc];
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for (i = 0; i < 10; i++) {
|
|
rpm-build |
8267b0 |
norm = spiro_iter(s, m, perm, v, nseg);
|
|
rpm-build |
8267b0 |
if (norm < 1e-12) break;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
return 0;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected void
|
|
rpm-build |
8267b0 |
spiro_seg_to_bpath(final double [/*4*/] ks,
|
|
rpm-build |
8267b0 |
double x0, double y0, double x1, double y1,
|
|
rpm-build |
8267b0 |
SpiroBezierContext bc, int depth) {
|
|
rpm-build |
8267b0 |
double bend = Math.abs(ks[0]) + Math.abs(.5 * ks[1]) + Math.abs(.125 * ks[2]) +
|
|
rpm-build |
8267b0 |
Math.abs((1./48) * ks[3]);
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
if ( bend <= 1e-8) {
|
|
rpm-build |
8267b0 |
bc.LineTo(x1, y1);
|
|
rpm-build |
8267b0 |
} else {
|
|
rpm-build |
8267b0 |
double seg_ch = Math.hypot(x1 - x0, y1 - y0);
|
|
rpm-build |
8267b0 |
double seg_th = Math.atan2(y1 - y0, x1 - x0);
|
|
rpm-build |
8267b0 |
double [] xy = new double[2];
|
|
rpm-build |
8267b0 |
double ch, th;
|
|
rpm-build |
8267b0 |
double scale, rot;
|
|
rpm-build |
8267b0 |
double th_even, th_odd;
|
|
rpm-build |
8267b0 |
double ul, vl;
|
|
rpm-build |
8267b0 |
double ur, vr;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
integrate_spiro(ks, xy);
|
|
rpm-build |
8267b0 |
ch = Math.hypot(xy[0], xy[1]);
|
|
rpm-build |
8267b0 |
th = Math.atan2(xy[1], xy[0]);
|
|
rpm-build |
8267b0 |
scale = seg_ch / ch;
|
|
rpm-build |
8267b0 |
rot = seg_th - th;
|
|
rpm-build |
8267b0 |
if (depth > 5 || bend < 1.) {
|
|
rpm-build |
8267b0 |
th_even = (1./384) * ks[3] + (1./8) * ks[1] + rot;
|
|
rpm-build |
8267b0 |
th_odd = (1./48) * ks[2] + .5 * ks[0];
|
|
rpm-build |
8267b0 |
ul = (scale * (1./3)) * Math.cos(th_even - th_odd);
|
|
rpm-build |
8267b0 |
vl = (scale * (1./3)) * Math.sin(th_even - th_odd);
|
|
rpm-build |
8267b0 |
ur = (scale * (1./3)) * Math.cos(th_even + th_odd);
|
|
rpm-build |
8267b0 |
vr = (scale * (1./3)) * Math.sin(th_even + th_odd);
|
|
rpm-build |
8267b0 |
bc.CubicTo(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1);
|
|
rpm-build |
8267b0 |
} else {
|
|
rpm-build |
8267b0 |
/* subdivide */
|
|
rpm-build |
8267b0 |
double [] ksub = new double[4];
|
|
rpm-build |
8267b0 |
double thsub;
|
|
rpm-build |
8267b0 |
double [] xysub = new double[2];
|
|
rpm-build |
8267b0 |
double xmid, ymid;
|
|
rpm-build |
8267b0 |
double cth, sth;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
ksub[0] = .5 * ks[0] - .125 * ks[1] + (1./64) * ks[2] - (1./768) * ks[3];
|
|
rpm-build |
8267b0 |
ksub[1] = .25 * ks[1] - (1./16) * ks[2] + (1./128) * ks[3];
|
|
rpm-build |
8267b0 |
ksub[2] = .125 * ks[2] - (1./32) * ks[3];
|
|
rpm-build |
8267b0 |
ksub[3] = (1./16) * ks[3];
|
|
rpm-build |
8267b0 |
thsub = rot - .25 * ks[0] + (1./32) * ks[1] - (1./384) * ks[2] + (1./6144) * ks[3];
|
|
rpm-build |
8267b0 |
cth = .5 * scale * Math.cos(thsub);
|
|
rpm-build |
8267b0 |
sth = .5 * scale * Math.sin(thsub);
|
|
rpm-build |
8267b0 |
integrate_spiro(ksub, xysub);
|
|
rpm-build |
8267b0 |
xmid = x0 + cth * xysub[0] - sth * xysub[1];
|
|
rpm-build |
8267b0 |
ymid = y0 + cth * xysub[1] + sth * xysub[0];
|
|
rpm-build |
8267b0 |
spiro_seg_to_bpath(ksub, x0, y0, xmid, ymid, bc, depth + 1);
|
|
rpm-build |
8267b0 |
ksub[0] += .25 * ks[1] + (1./384) * ks[3];
|
|
rpm-build |
8267b0 |
ksub[1] += .125 * ks[2];
|
|
rpm-build |
8267b0 |
ksub[2] += (1./16) * ks[3];
|
|
rpm-build |
8267b0 |
spiro_seg_to_bpath(ksub, xmid, ymid, x1, y1, bc, depth + 1);
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected spiro_seg []
|
|
rpm-build |
8267b0 |
run_spiro(final SpiroCP []src, int n) {
|
|
rpm-build |
8267b0 |
int nseg = src[0].type == OPEN ? n - 1 : n;
|
|
rpm-build |
8267b0 |
spiro_seg [] s = setup_path(src, n);
|
|
rpm-build |
8267b0 |
if (nseg > 1)
|
|
rpm-build |
8267b0 |
solve_spiro(s, nseg);
|
|
rpm-build |
8267b0 |
return s;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected void
|
|
rpm-build |
8267b0 |
spiro_to_bpath(final spiro_seg []s, int n, SpiroBezierContext bc) {
|
|
rpm-build |
8267b0 |
int i;
|
|
rpm-build |
8267b0 |
int nsegs = s[n - 1].type == OPEN_END ? n - 1 : n;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for (i = 0; i < nsegs; i++) {
|
|
rpm-build |
8267b0 |
double x0 = s[i].x;
|
|
rpm-build |
8267b0 |
double y0 = s[i].y;
|
|
rpm-build |
8267b0 |
double x1 = s[i + 1].x;
|
|
rpm-build |
8267b0 |
double y1 = s[i + 1].y;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
if (i == 0)
|
|
rpm-build |
8267b0 |
bc.MoveTo(x0, y0, s[0].type == OPEN);
|
|
rpm-build |
8267b0 |
bc.MarkKnot(i);
|
|
rpm-build |
8267b0 |
spiro_seg_to_bpath(s[i].ks, x0, y0, x1, y1, bc, 0);
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static protected double
|
|
rpm-build |
8267b0 |
get_knot_th(final spiro_seg []s, int i) {
|
|
rpm-build |
8267b0 |
double [][] ends = new double[2][4];
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
if (i == 0) {
|
|
rpm-build |
8267b0 |
compute_ends(s[i].ks, ends, s[i].seg_ch);
|
|
rpm-build |
8267b0 |
return s[i].seg_th - ends[0][0];
|
|
rpm-build |
8267b0 |
} else {
|
|
rpm-build |
8267b0 |
compute_ends(s[i - 1].ks, ends, s[i - 1].seg_ch);
|
|
rpm-build |
8267b0 |
return s[i - 1].seg_th + ends[1][0];
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* ************************************************************************* */
|
|
rpm-build |
8267b0 |
/* *************************** public interface **************************** */
|
|
rpm-build |
8267b0 |
/* ************************************************************************* */
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static public void
|
|
rpm-build |
8267b0 |
SpiroCPsToBezier(SpiroCP [] spiros,int n,boolean isclosed,SpiroBezierContext bc) {
|
|
rpm-build |
8267b0 |
spiro_seg []s;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
if ( n<1 )
|
|
rpm-build |
8267b0 |
return;
|
|
rpm-build |
8267b0 |
if ( !isclosed ) {
|
|
rpm-build |
8267b0 |
SpiroPointType oldty_start = spiros[0].type;
|
|
rpm-build |
8267b0 |
SpiroPointType oldty_end = spiros[n-1].type;
|
|
rpm-build |
8267b0 |
spiros[0].type= OPEN;
|
|
rpm-build |
8267b0 |
spiros[n-1].type= OPEN_END;
|
|
rpm-build |
8267b0 |
s = run_spiro(spiros,n);
|
|
rpm-build |
8267b0 |
spiros[n-1].type= oldty_end;
|
|
rpm-build |
8267b0 |
spiros[0].type= oldty_start;
|
|
rpm-build |
8267b0 |
} else
|
|
rpm-build |
8267b0 |
s = run_spiro(spiros,n);
|
|
rpm-build |
8267b0 |
spiro_to_bpath(s,n,bc);
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static public void
|
|
rpm-build |
8267b0 |
TaggedSpiroCPsToBezier(SpiroCP [] spiros,SpiroBezierContext bc) {
|
|
rpm-build |
8267b0 |
spiro_seg []s;
|
|
rpm-build |
8267b0 |
int n;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
for ( n=0; spiros[n].type!=END && spiros[n].type!=OPEN_END; ++n );
|
|
rpm-build |
8267b0 |
if ( spiros[n].type == OPEN_END ) ++n;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
if ( n<1 )
|
|
rpm-build |
8267b0 |
return;
|
|
rpm-build |
8267b0 |
s = run_spiro(spiros,n);
|
|
rpm-build |
8267b0 |
spiro_to_bpath(s,n,bc);
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
/* ************************************************************************* */
|
|
rpm-build |
8267b0 |
/* ***************************** plate file IO ***************************** */
|
|
rpm-build |
8267b0 |
/* ************************************************************************* */
|
|
rpm-build |
8267b0 |
static public void
|
|
rpm-build |
8267b0 |
SavePlateFile(Writer output,SpiroCP [][] spirocontours) throws IOException {
|
|
rpm-build |
8267b0 |
int i,j;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
output.write("(plate\n");
|
|
rpm-build |
8267b0 |
for ( i=0; i
|
|
rpm-build |
8267b0 |
SpiroCP [] spiros = spirocontours[i];
|
|
rpm-build |
8267b0 |
for ( j=0; j
|
|
rpm-build |
8267b0 |
if ( spiros[j].type==END )
|
|
rpm-build |
8267b0 |
break;
|
|
rpm-build |
8267b0 |
output.write(" " + spiros[j].toString() + "\n" );
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
if ( spiros.length>0 && spiros[0].type!=OPEN )
|
|
rpm-build |
8267b0 |
output.write(" (z)\n");
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
output.write(")\n");
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
static public SpiroCP [][]
|
|
rpm-build |
8267b0 |
ReadPlateFile(BufferedReader input) throws IOException {
|
|
rpm-build |
8267b0 |
ArrayList<SpiroCP []> sofar;
|
|
rpm-build |
8267b0 |
ArrayList<SpiroCP> contour;
|
|
rpm-build |
8267b0 |
int i,j;
|
|
rpm-build |
8267b0 |
String str;
|
|
rpm-build |
8267b0 |
char ch;
|
|
rpm-build |
8267b0 |
SpiroPointType pt;
|
|
rpm-build |
8267b0 |
double x,y;
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
str = input.readLine();
|
|
rpm-build |
8267b0 |
if ( str==null )
|
|
rpm-build |
8267b0 |
return( null ); /* EOF already? */
|
|
rpm-build |
8267b0 |
if ( !str.trim().equals("(plate") ) {
|
|
rpm-build |
8267b0 |
// Doesn't look like a plate file
|
|
rpm-build |
8267b0 |
return( null );
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
|
|
rpm-build |
8267b0 |
sofar = new ArrayList<SpiroCP []>();
|
|
rpm-build |
8267b0 |
contour = new ArrayList<SpiroCP>();
|
|
rpm-build |
8267b0 |
while ( true ) {
|
|
rpm-build |
8267b0 |
while( true ) {
|
|
rpm-build |
8267b0 |
str = input.readLine();
|
|
rpm-build |
8267b0 |
if ( str==null )
|
|
rpm-build |
8267b0 |
break;
|
|
rpm-build |
8267b0 |
str = str.trim();
|
|
rpm-build |
8267b0 |
if ( str.equals(")") || str.equals("(z)") )
|
|
rpm-build |
8267b0 |
break;
|
|
rpm-build |
8267b0 |
if ( str.charAt(0)!='(' )
|
|
rpm-build |
8267b0 |
return( null );
|
|
rpm-build |
8267b0 |
for ( i=1; i
|
|
rpm-build |
8267b0 |
if ( i>=str.length())
|
|
rpm-build |
8267b0 |
return( null );
|
|
rpm-build |
8267b0 |
ch = str.charAt(i);
|
|
rpm-build |
8267b0 |
if ( ch=='v' )
|
|
rpm-build |
8267b0 |
pt = CORNER;
|
|
rpm-build |
8267b0 |
else if ( ch=='o' )
|
|
rpm-build |
8267b0 |
pt = G4;
|
|
rpm-build |
8267b0 |
else if ( ch=='c' )
|
|
rpm-build |
8267b0 |
pt = G2;
|
|
rpm-build |
8267b0 |
else if ( ch=='[' )
|
|
rpm-build |
8267b0 |
pt = LEFT;
|
|
rpm-build |
8267b0 |
else if ( ch==']' )
|
|
rpm-build |
8267b0 |
pt = RIGHT;
|
|
rpm-build |
8267b0 |
else if ( ch=='{' )
|
|
rpm-build |
8267b0 |
pt = OPEN;
|
|
rpm-build |
8267b0 |
else if ( ch=='}' )
|
|
rpm-build |
8267b0 |
pt = OPEN_END;
|
|
rpm-build |
8267b0 |
else
|
|
rpm-build |
8267b0 |
return( null );
|
|
rpm-build |
8267b0 |
for ( ++i ; i
|
|
rpm-build |
8267b0 |
for ( j=i ; j
|
|
rpm-build |
8267b0 |
if ( j>=str.length() )
|
|
rpm-build |
8267b0 |
return( null );
|
|
rpm-build |
8267b0 |
try {
|
|
rpm-build |
8267b0 |
x = Double.parseDouble(str.substring(i,j-1));
|
|
rpm-build |
8267b0 |
} catch ( NumberFormatException e ) {
|
|
rpm-build |
8267b0 |
return( null );
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
for ( i=j+1 ; i
|
|
rpm-build |
8267b0 |
for ( j=i ; j
|
|
rpm-build |
8267b0 |
if ( j>=str.length() )
|
|
rpm-build |
8267b0 |
return( null );
|
|
rpm-build |
8267b0 |
try {
|
|
rpm-build |
8267b0 |
y = Double.parseDouble(str.substring(i,j-1));
|
|
rpm-build |
8267b0 |
} catch ( NumberFormatException e ) {
|
|
rpm-build |
8267b0 |
return( null );
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
contour.add( new SpiroCP(x,y,pt));
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
contour.add( new SpiroCP(0,0,END));
|
|
rpm-build |
8267b0 |
sofar.add( contour.toArray(new SpiroCP[contour.size()]));
|
|
rpm-build |
8267b0 |
contour.clear();
|
|
rpm-build |
8267b0 |
if ( str==null || str.equals(")") )
|
|
rpm-build |
8267b0 |
break;
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
return ( sofar.toArray( new SpiroCP [sofar.size()][] ) );
|
|
rpm-build |
8267b0 |
}
|
|
rpm-build |
8267b0 |
}
|