use of imagingbook.lib.math.Complex in project imagingbook-common by imagingbook.
the class FourierDescriptorFromPolygon method makeDftSpectrumTrigonometric.
void makeDftSpectrumTrigonometric(int Mp) {
// number of polygon vertices
final int N = g.length;
// number of Fourier coefficients
final int M = 2 * Mp + 1;
// dx[k] is the delta-x for polygon segment <k,k+1>
double[] dx = new double[N];
// dy[k] is the delta-y for polygon segment <k,k+1>
double[] dy = new double[N];
// lambda[k] is the length of the polygon segment <k,k+1>
double[] lambda = new double[N];
// T[k] is the cumulated path length at polygon vertex k in [0,K]
double[] L = new double[N + 1];
G = new Complex[M];
L[0] = 0;
for (int i = 0; i < N; i++) {
// compute Dx, Dy, Dt and t tables
dx[i] = g[(i + 1) % N].re - g[i].re;
dy[i] = g[(i + 1) % N].im - g[i].im;
lambda[i] = sqrt(sqr(dx[i]) + sqr(dy[i]));
if (abs(lambda[i]) < EPSILON_DOUBLE) {
throw new Error("Zero-length polygon segment!");
}
L[i + 1] = L[i] + lambda[i];
}
// Ln is the closed polygon length
double Ln = L[N];
// calculate DFT coefficient G[0]:
// V[0].getX();
double x0 = g[0].re;
// V[0].getY();
double y0 = g[0].im;
double a0 = 0;
double c0 = 0;
for (int i = 0; i < N; i++) {
// for each polygon vertex
double s = (sqr(L[i + 1]) - sqr(L[i])) / (2 * lambda[i]) - L[i];
// V[i].getX();
double xi = g[i].re;
// V[i].getY();
double yi = g[i].im;
a0 = a0 + s * dx[i] + (xi - x0) * lambda[i];
c0 = c0 + s * dy[i] + (yi - y0) * lambda[i];
}
// G[0] = new Complex(x0 + a0/Ln, y0 + c0/Ln);
this.setCoefficient(0, new Complex(x0 + a0 / Ln, y0 + c0 / Ln));
// calculate remaining FD pairs G[-m], G[+m] for m = 1,...,Mp
for (int m = 1; m <= Mp; m++) {
// for each FD pair
double w = 2 * PI * m / Ln;
double a = 0, c = 0;
double b = 0, d = 0;
for (int i = 0; i < N; i++) {
// for each polygon vertex
double w0 = w * L[i];
double w1 = w * L[(i + 1) % N];
double dCos = cos(w1) - cos(w0);
a = a + dCos * (dx[i] / lambda[i]);
c = c + dCos * (dy[i] / lambda[i]);
double dSin = sin(w1) - sin(w0);
b = b + dSin * (dx[i] / lambda[i]);
d = d + dSin * (dy[i] / lambda[i]);
}
double s = Ln / sqr(2 * PI * m);
this.setCoefficient(+m, new Complex(s * (a + d), s * (c - b)));
this.setCoefficient(-m, new Complex(s * (a - d), s * (b + c)));
}
}
use of imagingbook.lib.math.Complex in project imagingbook-common by imagingbook.
the class FourierDescriptorUniform method DFT.
// -------------------------------------------------------------------
/**
* DFT with the resulting spectrum (signal, if inverse) of the same length
* as the input vector g. Not using sin/cos tables.
*
* @param g signal vector
* @return DFT spectrum
*/
private Complex[] DFT(Complex[] g) {
int M = g.length;
// double[] cosTable = makeCosTable(M); // cosTable[m] == cos(2*pi*m/M)
// double[] sinTable = makeSinTable(M);
Complex[] G = new Complex[M];
// common scale factor (fwd/inverse differ!)
double s = 1.0 / M;
for (int m = 0; m < M; m++) {
double Am = 0;
double Bm = 0;
for (int k = 0; k < M; k++) {
double x = g[k].re;
double y = g[k].im;
double phi = 2 * Math.PI * m * k / M;
double cosPhi = Math.cos(phi);
double sinPhi = Math.sin(phi);
Am = Am + x * cosPhi + y * sinPhi;
Bm = Bm - x * sinPhi + y * cosPhi;
}
G[m] = new Complex(s * Am, s * Bm);
}
return G;
}
use of imagingbook.lib.math.Complex in project imagingbook-common by imagingbook.
the class Dft2d method doDft2d.
// ------------------------------------------------
public void doDft2d() {
// in-place 2D Dft
// do the rows:
Complex[] row = makeComplexVector(width);
Dft1d dftR = new Dft1d(width);
for (int v = 0; v < height; v++) {
getRow(v, row);
Complex[] rowDft = dftR.DFT(row, forward);
putRow(v, rowDft);
}
// do the columns:
Complex[] col = makeComplexVector(height);
Dft1d dftC = new Dft1d(height);
for (int u = 0; u < width; u++) {
getCol(u, col);
Complex[] colDft = dftC.DFT(col, forward);
putCol(u, colDft);
}
}
use of imagingbook.lib.math.Complex in project imagingbook-common by imagingbook.
the class FourierDescriptor method setCoefficient.
public void setCoefficient(int m, Complex z) {
int mm = Arithmetic.mod(m, G.length);
G[mm] = new Complex(z);
}
use of imagingbook.lib.math.Complex in project imagingbook-common by imagingbook.
the class FourierDescriptor method distanceComplex.
public double distanceComplex(FourierDescriptor fd2, int Mp) {
FourierDescriptor fd1 = this;
Mp = Math.min(Mp, G.length / 2);
double sum = 0;
for (int m = -Mp; m <= Mp; m++) {
if (m != 0) {
Complex G1m = fd1.getCoefficient(m);
Complex G2m = fd2.getCoefficient(m);
double dRe = G1m.re - G2m.re;
double dIm = G1m.im - G2m.im;
sum = sum + dRe * dRe + dIm * dIm;
}
}
return Math.sqrt(sum);
}