/*
* Copyright (c) 2016 Vivid Solutions.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.locationtech.jtstest.function;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.geom.util.*;
public class AffineTransformationFunctions
{
public static Geometry transformByVectors(Geometry g, Geometry control)
{
int nControl = control.getNumGeometries();
Coordinate src[] = new Coordinate[nControl];
Coordinate dest[] = new Coordinate[nControl];
for (int i = 0; i < nControl; i++) {
Geometry contComp = control.getGeometryN(i);
Coordinate[] pts = contComp.getCoordinates();
src[i] = pts[0];
dest[i] = pts[1];
}
AffineTransformation trans = AffineTransformationFactory.createFromControlVectors(src, dest);
System.out.println(trans);
return trans.transform(g);
}
public static Geometry transformByBaseline(Geometry g, Geometry destBaseline)
{
Envelope env = g.getEnvelopeInternal();
Coordinate src0 = new Coordinate(env.getMinX(), env.getMinY());
Coordinate src1 = new Coordinate(env.getMaxX(), env.getMinY());
Coordinate[] destPts = destBaseline.getCoordinates();
Coordinate dest0 = destPts[0];
Coordinate dest1 = destPts[1];
AffineTransformation trans = AffineTransformationFactory.createFromBaseLines(src0, src1, dest0, dest1);
return trans.transform(g);
}
private static Coordinate envelopeCentre(Geometry g)
{
return g.getEnvelopeInternal().centre();
}
private static Coordinate envelopeLowerLeft(Geometry g)
{
Envelope env = g.getEnvelopeInternal();
return new Coordinate(env.getMinX(), env.getMinY());
}
public static Geometry viewport(Geometry g, Geometry gViewport)
{
Envelope viewEnv = gViewport.getEnvelopeInternal();
Envelope env = g.getEnvelopeInternal();
AffineTransformation trans = viewportTrans(env, viewEnv);
return trans.transform(g);
}
private static AffineTransformation viewportTrans(Envelope srcEnv, Envelope viewEnv) {
// works even if W or H are zero, thanks to Java infinity value.
double scaleW = viewEnv.getWidth() / srcEnv.getWidth();
double scaleH = viewEnv.getHeight() / srcEnv.getHeight();
// choose minimum scale to ensure source fits viewport
double scale = Math.min(scaleW, scaleH);
Coordinate centre = srcEnv.centre();
Coordinate viewCentre = viewEnv.centre();
// isotropic scaling
AffineTransformation trans = AffineTransformation.scaleInstance(scale, scale, centre.x, centre.y);
// translate using envelope centres
trans.translate(viewCentre.x - centre.x, viewCentre.y - centre.y);
return trans;
}
public static Geometry scale(Geometry g, double scale)
{
Coordinate centre = envelopeCentre(g);
AffineTransformation trans = AffineTransformation.scaleInstance(scale, scale, centre.x, centre.y);
return trans.transform(g);
}
public static Geometry reflectInX(Geometry g)
{
Coordinate centre = envelopeCentre(g);
AffineTransformation trans = AffineTransformation.scaleInstance(1, -1, centre.x, centre.y);
return trans.transform(g);
}
public static Geometry reflectInY(Geometry g)
{
Coordinate centre = envelopeCentre(g);
AffineTransformation trans = AffineTransformation.scaleInstance(-1, 1, centre.x, centre.y);
return trans.transform(g);
}
public static Geometry rotateByPiMultiple(Geometry g, double multipleOfPi)
{
Coordinate centre = envelopeCentre(g);
AffineTransformation trans = AffineTransformation.rotationInstance(multipleOfPi * Math.PI, centre.x, centre.y);
return trans.transform(g);
}
public static Geometry rotate(Geometry g, double angle)
{
Coordinate centre = envelopeCentre(g);
AffineTransformation trans = AffineTransformation.rotationInstance(angle, centre.x, centre.y);
return trans.transform(g);
}
public static Geometry translateCentreToOrigin(Geometry g)
{
Coordinate centre = envelopeCentre(g);
AffineTransformation trans = AffineTransformation.translationInstance(-centre.x, -centre.y);
return trans.transform(g);
}
public static Geometry translateToOrigin(Geometry g)
{
Coordinate lowerLeft = envelopeLowerLeft(g);
AffineTransformation trans = AffineTransformation.translationInstance(-lowerLeft.x, -lowerLeft.y);
return trans.transform(g);
}
}