import java.applet.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.util.*; import java.io.*; import java.lang.Math; /** * Reflect is an algorithm to reflect an image about an axis * @author Craig Strachan after Judy Robertson, SELLIC Online * @see code.iface.reflect */ public class Reflect extends Thread { public Reflect() { } private int get_point(int x, int y, int width, int height, int [] src_bitmap) { /* * returns the value of a int bitmap with width width at point * x, y; */ return src_bitmap[(((height - 1) - y) * width) + x]; } /* get_point */ private void put_point(int point, int x, int y, int width, int height, int [] bitmap) { /* * Sets point x,y of the bitmap bitmap to have the value of point. */ bitmap [(((height - 1) - y) * width) + x] = point; } /* put_point */ /** *Reflects the input image by the specified angle. This reflection *happens about a line defined through the specified point. *@param src The input pixel array *@param width The width of the input image *@param height The height of the input image *@param x The x co-ordiante used to find the reflection axis *@param y The y co-ordinate used to find the reflection axis *@param angle The angle of the reflection axis *@param wrap Boolean which determines if the reflected image is wrapped around *@return The reflected image array */ public int [] reflect_image (int [] src, int width, int height, int x, int y, double angle, boolean wrap) { /* * Reflects an image of width width and height height about an * axis which passes through point x,y at angle angle to the X axis. */ int [] dest = new int [width * height]; int real_angle; y = height - y; // If we're not wrapping, black out the dest image so that parts // not wrapped into will appear black if (wrap == false) { int black_colour = new Color(0,0,0).getRGB(); for (int i = 0; i < (width * height); i++) { dest [i] = black_colour; } } double rad_angle = angle * Math.PI / 180; double delta; int new_x, new_y; for (int j = 0; j < height; j++) { // y coord for (int i = 0; i < width; i++) { // x coord delta = ((i - x) * Math.sin(rad_angle)) - ((j - y) * Math.cos(rad_angle)); new_x = (int) Math.round((i + (2 * delta * (Math.sin(rad_angle)) * -1))); new_y = (int) Math.round((j + (2 * delta * (Math.cos(rad_angle)) ))); if (new_x >= 0 && new_x < width && new_y >= 0 && new_y < height) { put_point(get_point(i, j, width, height, src), new_x, new_y, width, height, dest); } else { if (wrap ==true) { //do something clever } } } } int [][] tmp_2d = new int[width][height]; //Convert array from 1_d to 2_d for ease of processing for(int i = 0; i < width; i++){ for(int j = 0; j < height; j++){ tmp_2d[i][j] = dest[i+(j*width)]; } } //Now go through image and fill in points which had no point reflected //to them. This should eliminate the black dots in the output image. for(int i = 1; i < (width-1); i++){ for(int j = 1; j < (height-1); j++){ if((tmp_2d[i][j] & 0x000000ff) == 0){ //If black point dest[i+(j*width)] = validatePoint(tmp_2d, i, j); } else { dest[i+(j*width)] = tmp_2d[i][j]; } } } return dest; } int validatePoint(int [][] array, int xPoint, int yPoint){ int count = 0; //If enough neighbours are non-black then set point to mean of them if(array[xPoint-1][yPoint-1] != 0xff000000){ count ++; } if(array[xPoint][yPoint-1] != 0xff000000){ count ++; } if(array[xPoint+1][yPoint-1] != 0xff000000){ count++; } if(array[xPoint-1][yPoint] != 0xff000000){ count++; } if(array[xPoint+1][yPoint] != 0xff000000){ count++; } if(array[xPoint-1][yPoint+1] != 0xff000000){ count++; } if(array[xPoint][yPoint+1] != 0xff000000){ count++; } if(array[xPoint+1][yPoint+1] != 0xff000000){ count++; } if(count >= 5){ int sum = (array[xPoint-1][yPoint-1] & 0x000000ff) + (array[xPoint][yPoint-1] & 0x000000ff) + (array[xPoint+1][yPoint-1] & 0x000000ff) + (array[xPoint-1][yPoint] & 0x000000ff) + (array[xPoint+1][yPoint] & 0x000000ff) + (array[xPoint-1][yPoint+1] & 0x000000ff) + (array[xPoint][yPoint+1] & 0x000000ff) + (array[xPoint+1][yPoint+1] & 0x000000ff); int answer = (int)(sum/count); return 0xff000000 | answer<<16 | answer<<8 | answer; } else { return array[xPoint][yPoint]; } } }