Package ch.sahits.game.graphic.image.impl

Source Code of ch.sahits.game.graphic.image.impl.PolygonScaling

package ch.sahits.game.graphic.image.impl;

import java.awt.Point;

import org.apache.log4j.Logger;

import ch.sahits.game.graphic.image.IPolygonScaling;
import ch.sahits.game.graphic.image.model.ImageData;
import ch.sahits.game.graphic.image.model.NamedPolygon;
import ch.sahits.game.image.ECrop;
import ch.sahits.game.image.EScaleDirection;
import ch.sahits.game.image.ImageScaleState;
/**
* Implementation class for recalculating poligons of a scaled, bordered and cropped image and
* on the absolute positioning of that image on the screen.
* @author Andi Hotz, (c) Sahits GmbH, 2012
* Created on Jul 1, 2012
*
*/
public class PolygonScaling implements IPolygonScaling {
 
  private final Logger logger = Logger.getLogger(PolygonScaling.class);

  @Override
  public ImageData recalculatePolygons(ImageData imgData,ImageScaleState state) {
    ImageData result=null;
    // order is important: we do not want to scale translocated polygons
    if (state.isScaled()){
      result = recalculatePolygonScale(imgData, state);
    }
    if (state.isBordered() && result==null){
      result = recalculatePolygonBorder(imgData, state);
    } else if (state.isBordered()){
      result = recalculatePolygonBorder(result, state);
    }
    if (state.isCropped() && result==null){
      result = recalculatePolygonCrop(imgData, state);
    } else if (state.isCropped() ){ // and bordered
      result = recalculatePolygonCrop(result, state);
    }
    if (result==null){ // no scaling operation at all
      result = createNewCopy(imgData);
    }
    return result;
  }

  @Override
  public ImageData recalculatePolygonsOffsett(ImageData imgData, Point offset) {
    if (offset.x==0 && offset.y==0){
      return createNewCopy(imgData);
    }
    ImageData result = createNewCopy(imgData);
    for (NamedPolygon poly : result.getPolygons().values()) {
      updateCoordinates(poly, offset.x, offset.y);
    }
    return result;
  }
  /**
   * Compute the polygon affected by the bordering of the image as stated in state
   * @param imgData Input data of the image containing a list of {@link NamedPolygon}s that are to be recalculated
   * @param state of the scaled image
   * @return new instance of ImageData containing the recalculated polygons
   */
  final ImageData recalculatePolygonBorder(ImageData imgData, ImageScaleState state){
    if (!state.isBordered()){
      logger.trace("Image has no border, no recalculation for borders");
      return createNewCopy(imgData);
    }
    if (state.getBordered()==0 || state.getBorderDirection()==null){
      throw new IllegalStateException("Border amount and direction must be specified");
    }
    final int amount = state.getBordered();
    ImageData result = createNewCopy(imgData);
    if (state.getBorderDirection()==EScaleDirection.HORIZONTAL){ // change x coordinate
      logger.trace("Borders on the side: update X coordinate by "+amount);
      for (NamedPolygon poly : result.getPolygons().values()) {
        updateXCoordinate(poly, amount);
      }       
    } else { // change y coordinate
      logger.trace("Borders at the top and bottom: update Y coordinate by "+amount);
      for (NamedPolygon poly : result.getPolygons().values()) {
        updateYCoordinate(poly, amount);
      }       
    }
    return result;
  }
 
  /**
   * Compute the polygon affected by the cropping of the image as stated in state
   * @param imgData Input data of the image containing a list of {@link NamedPolygon}s that are to be recalculated
   * @param state of the scaled image
   * @return new instance of ImageData containing the recalculated polygons
   */
  final ImageData recalculatePolygonCrop(ImageData imgData, ImageScaleState state){
    if (!state.isCropped() || state.getCrop()==ECrop.NONE){
      // not cropped at all => return new instance of imgData
      logger.trace("Image has no cropping, no recalculation for crop");
      return createNewCopy(imgData);
    }
    if (state.getCropped()==0 || state.getCrop()==ECrop.NONE){
      throw new IllegalStateException("Crop amount and crop side must be specified");
    }
    ImageData result = createNewCopy(imgData);
    final int amount = state.getCropped();
    if (state.getCrop()==ECrop.BOTTOM || state.getCrop()==ECrop.RIGHT){
      logger.trace("Image has was cropped at the bottom or the right side: no change");
      return result;
    } else if (state.getCrop()==ECrop.LEFT){ // change x coordinate
      logger.trace("Crop on the left side: update X coordinate by "+amount);
      for (NamedPolygon poly : result.getPolygons().values()) {
        updateXCoordinate(poly, (int)Math.rint(-amount*state.getScaleFactor()));
      }       
    } else { // change y coordinate
      logger.trace("Crop at the top: update Y coordinate by "+amount);
      for (NamedPolygon poly : result.getPolygons().values()) {
        updateYCoordinate(poly, (int)Math.rint(-amount*state.getScaleFactor()));
      }       
    }
    return result;
  }
  /**
   * Create a clone of the image data and handle the CloneNotSupportedException
   * @param imgData
   * @return
   */
  private ImageData createNewCopy(ImageData imgData) {
    try {
      return (ImageData) imgData.clone();
    } catch (CloneNotSupportedException e){
      System.err.println("Implementaion error");
      e.printStackTrace();
      return null;
    }
  }
 
  /**
   * Compute the polygon affected by the scaling of the image as stated in state
   * @param imgData Input data of the image containing a list of {@link NamedPolygon}s that are to be recalculated
   * @param state of the scaled image
   * @return new instance of ImageData containing the recalculated polygons
   */
  final ImageData recalculatePolygonScale(ImageData imgData, ImageScaleState state){
    if (!state.isScaled()){
      // not scaled at all => return new instance of imgData
      logger.trace("Image was not scaled, no recalculation for scale");
      return createNewCopy(imgData);
    }
    if (state.getScaleFactor()==1 ){
      throw new IllegalStateException("Scale factor must be specified");
    }
    ImageData result = createNewCopy(imgData);
    final double scaleFactor = state.getScaleFactor();
    logger.trace("Scale by factor "+scaleFactor);
    for (NamedPolygon poly : result.getPolygons().values()) {
      updateCoordinate(poly, scaleFactor);
    }       
    return result;
  }
  /**
   * Update the coordinates of the polygon by the specified values in x and y direction
   * @param poly polygon to be updated
   * @param diffX difference in x direction
   * @param diffY difference in y direction
   */
  private void updateCoordinates(NamedPolygon poly, int diffX, int diffY){
    for (int i = 0; i < poly.npoints; i++) {
      logger.trace("Move point by: ("+diffX+","+diffY+") ("+poly.xpoints[i]+","+poly.ypoints[i]+") => ("+(poly.xpoints[i]+diffX)+","+(poly.ypoints[i]+diffY)+")");
      poly.xpoints[i] += diffX;
      poly.ypoints[i] += diffY;
    }
  }
  /**
   * Update the x coordinate of each point within the polygon by amount
   * @param poly polygon to be updated
   * @param amount the X-coordinate is to be translated
   */
  private void updateXCoordinate(NamedPolygon poly,int amount){
    for (int i = 0; i < poly.npoints; i++) {
      logger.trace("Move point by: "+amount+" ("+poly.xpoints[i]+","+poly.ypoints[i]+") => ("+(poly.xpoints[i]+amount)+","+(poly.ypoints[i])+")");
      poly.xpoints[i] += amount;
    }
  }
  /**
   * Update the y coordinate of each point within the polygon by amount
   * @param poly polygon to be updated
   * @param amount the Y-coordinate is to be translated
   */
  private void updateYCoordinate(NamedPolygon poly,int amount){
    for (int i = 0; i < poly.npoints; i++) {
      logger.trace("Move point by: "+amount+" ("+poly.xpoints[i]+","+poly.ypoints[i]+") => ("+(poly.xpoints[i])+","+(poly.ypoints[i]+amount)+")");
      poly.ypoints[i] += amount;
    }
  }
 
  /**
   * Update the x and y coordinate of each point within the polygon by factor
   * @param poly polygon to be updated
   * @param factor that is to be multiplied with each coordinate
   */
  private void updateCoordinate(NamedPolygon poly,double factor){
    for (int i = 0; i < poly.npoints; i++) {
      final int newX = (int)Math.rint(poly.xpoints[i]*factor);
      final int newY = (int)Math.rint(poly.ypoints[i]*factor);     
      logger.trace("Update point factor: "+factor+" ("+poly.xpoints[i]+","+poly.ypoints[i]+") => ("+newX+","+newY+")");
      poly.xpoints[i] = newX;
      poly.ypoints[i] = newY;
    }
  }
}
TOP

Related Classes of ch.sahits.game.graphic.image.impl.PolygonScaling

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.