//----------------------------------------------------------------------------//
// //
// S k e w //
// //
//----------------------------------------------------------------------------//
// <editor-fold defaultstate="collapsed" desc="hdr"> //
// Copyright © Hervé Bitteur and others 2000-2013. All rights reserved. //
// This software is released under the GNU General Public License. //
// Goto http://kenai.com/projects/audiveris to report bugs or suggestions. //
//----------------------------------------------------------------------------//
// </editor-fold>
package omr.sheet;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
/**
* Class {@code Skew} handles the skew angle of a given sheet picture.
*
* @author Hervé Bitteur
*/
public class Skew
{
//~ Instance fields --------------------------------------------------------
/** Skew slope as measured */
private final double slope;
/** Corresponding angle (in radians) */
private final double angle;
/** Transform to deskew */
private final AffineTransform at;
/** Width of deskewed sheet */
private final double deskewedWidth;
/** Height of deskewed sheet */
private final double deskewedHeight;
//~ Constructors -----------------------------------------------------------
/**
* Creates a new Skew object.
*
* @param slope the sheet global slope
* @param sheet the related sheet
*/
public Skew (double slope,
Sheet sheet)
{
this.slope = slope;
angle = Math.atan(slope);
// Rotation for deskew
double deskewAngle = -angle;
at = AffineTransform.getRotateInstance(deskewAngle);
// Origin translation for deskew
int w = sheet.getWidth();
int h = sheet.getHeight();
Point2D topRight = at.transform(new Point2D.Double(w, 0), null);
Point2D bottomLeft = at.transform(new Point2D.Double(0, h), null);
Point2D bottomRight = at.transform(new Point2D.Double(w, h), null);
double dx = 0;
double dy = 0;
if (deskewAngle <= 0) { // Counter-clockwise deskew
deskewedWidth = bottomRight.getX();
dy = -topRight.getY();
deskewedHeight = bottomLeft.getY() + dy;
} else { // Clockwise deskew
dx = -bottomLeft.getX();
deskewedWidth = topRight.getX() + dx;
deskewedHeight = bottomRight.getY();
}
at.translate(dx, dy);
}
//~ Methods ----------------------------------------------------------------
//----------//
// deskewed //
//----------//
/**
* Apply rotation OPPOSITE to the measured global angle and use the
* new sheet origin.
*
* @param point the initial (skewed) point
* @return the deskewed point
*/
public Point2D deskewed (Point2D point)
{
return at.transform(point, null);
}
//----------//
// getAngle //
//----------//
/**
* Report the skew angle.
*
* @return the angle value, expressed in radians
*/
public double getAngle ()
{
return angle;
}
//-------------------//
// getDeskewedHeight //
//-------------------//
/**
* @return the deskewedHeight
*/
public double getDeskewedHeight ()
{
return deskewedHeight;
}
//------------------//
// getDeskewedWidth //
//------------------//
/**
* @return the deskewedWidth
*/
public double getDeskewedWidth ()
{
return deskewedWidth;
}
//----------//
// getSlope //
//----------//
/**
* @return the slope (tangent of angle)
*/
public double getSlope ()
{
return slope;
}
//----------//
// toString //
//----------//
@Override
public String toString ()
{
return "{Skew angle=" + angle + "}";
}
}