import java.awt.*; import java.awt.geom.*; import java.awt.image.*; /** * This class is for defining triangulated images and for interpolation * between two triangulated images with corresponding triangulations. * * @author Frank Klawonn * Last change 31.05.2005 * * @see MorphingCandS */ public class TriangulatedImage { //The initial image. BufferedImage bi; //The points needed for the triangulation. Point2D[] tPoints; //The triangles defining the triangulation. Each row of the arrays contains //indices of three points in the array tPoints. The i-th triangle of the //triangulation is defined by the three points in array tPoints with the indices //triangles[i][0], triangles[i][1], triangles[i][2]. int[][] triangles; /** * A method that computes for a point v and three additional noncollinear points * a representation of v as a linear combination of the three points. The three coefficents * for the representation of v are returned. * * @param v point to be represented. * @param triangle an array contain three noncollinear points. * * @return the three coefficients for the representation of v. */ public static double[] triangleCoordinates(Point2D v, Point2D[] triangle) { //The array for the three coefficients. double[] result = new double[3]; //Some values that are needed to solve the system of linear equations for //determining the coefficients. double d13x = triangle[0].getX() - triangle[2].getX(); double d23x = triangle[1].getX() - triangle[2].getX(); double dx3 = v.getX() - triangle[2].getX(); double d13y = triangle[0].getY() - triangle[2].getY(); double d23y = triangle[1].getY() - triangle[2].getY(); double dy3 = v.getY() - triangle[2].getY(); double delta = d13x*d23y - d23x*d13y; //When the three points are (almost) collinear, division by zero is avoided and //coefficients are returned which at least do not represent a convex combinaion. //Otherwise the coefficients cannot be computed. if (Math.abs(delta)<0.00000001) { result[0] = 10; } else { result[0] = (dx3*d23y - d23x*dy3)/delta; result[1] = (d13x*dy3 - dx3*d13y)/delta; } result[2] = 1 - result[0] - result[1]; return(result); } /** * Test, whether a given array of coefficienten represents a convex combination, * i.e. it is checked, whether all elements in the array are between 0 and 1 * and whether they sum up to 1. * * @param t array with the coefficients. * * @return true if and only if the coefficients represent a convex combination. */ public static boolean isConvexCombination(double[] t) { boolean result; double sum; //According to round-off errors, the coefficients will almost never sum up to 1 exactly. //The following value specifies how much deviation from the exact value 1 is still considered //as a convex combination. double tolerance = 0.000001; result = true; sum = 0; for (int i=0; i1) { result = false; } sum = sum + t[i]; } if (Math.abs(sum-1)>tolerance) { result = false; } return(result); } /** * Generates and interpolated image from two triangulated images (this and ti). * ti contribued to the interpolated image by alpha*100%. The two images must have the * same size, the same number of points for the triangulation and the number of triangles. * Furthermore, the triangles for both images must consist of the points with the same * indices. Only the position of the points does need to coincide for the two images. * * @param ti second triangulated image. * @param alpha proportion that ti should contribute to the interpolated image. * * @return the interpolated image. */ public BufferedImage mixWith(TriangulatedImage ti, double alpha) { TriangulatedImage mix = new TriangulatedImage(); //Here the interpolated image will be stored. mix.bi = new BufferedImage(this.bi.getWidth(),this.bi.getHeight(), BufferedImage.TYPE_INT_RGB); //Define the points for the triangulation points in the interpolated image as //convex combinations of the corresponding points in the images to be //interpolated. mix.tPoints = new Point2D[this.tPoints.length]; for (int i=0; i