-
Amandine TOURNAY authoredAmandine TOURNAY authored
AnglePainter.java 9.22 KiB
package plugins.fab.anglehelper;
import icy.canvas.IcyCanvas;
import icy.canvas.IcyCanvas2D;
import icy.gui.util.GuiUtil;
import icy.main.Icy;
import icy.math.Scaler;
import icy.painter.Anchor2D;
import icy.painter.Anchor2D.Anchor2DListener;
import icy.painter.Painter;
import icy.painter.PainterEvent;
import icy.roi.ROI2D;
import icy.sequence.Sequence;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import plugins.fab.Ruler.Anchor2DTarget;
import plugins.fab.Ruler.ShapeDefinition;
/**
* @author Fabrice de Chaumont
*/
public class AnglePainter implements Painter, Anchor2DListener {
Anchor2DTarget a1 = new Anchor2DTarget( 0 , 0 );
Anchor2DTarget a2 = new Anchor2DTarget( 0 , 0 );
Anchor2DTarget a3 = new Anchor2DTarget( 0 , 0 );
ArrayList<ShapeDefinition> shapeDefinitionList = new ArrayList<ShapeDefinition>();
ArrayList<AffineTransform> affineTransformList = new ArrayList<AffineTransform>();
public AnglePainter(Sequence sequence) {
if ( sequence == null ) return;
a1.setPosition( sequence.getWidth() / 2 , sequence.getHeight() / 2 );
a2.setPosition( 3 * sequence.getWidth() / 4 , sequence.getHeight() / 2 );
a3.setPosition( 3 * sequence.getWidth() / 4 , sequence.getHeight() / 3 );
sequence.addPainter( this );
a1.addListener( this );
a2.addListener( this );
a3.addListener( this );
}
// Listener of Anchor
@Override
public void painterChanged(PainterEvent event) {
for ( Sequence sequence : Icy.getMainInterface().getSequencesContaining( this ) )
{
sequence.painterChanged( this );
}
}
@Override
public void positionChanged(Anchor2D source) {
}
void pushTransform( Graphics2D g )
{
affineTransformList.add( g.getTransform() );
}
void popTransform( Graphics2D g )
{
g.setTransform( affineTransformList.get( affineTransformList.size() -1 ) );
affineTransformList.remove( affineTransformList.size() -1 );
}
public double CleanAngle( double angle )
{
double a = Math.abs( angle );
a = Math.round(a*10)/10.;
return a;
}
// Painter Section:
@Override
public void paint(Graphics2D g, Sequence sequence, IcyCanvas canvas) {
if ( ! ( canvas instanceof IcyCanvas2D ) ) return;
g= (Graphics2D) g.create();
BasicStroke[] stroke = new BasicStroke[4];
stroke[0] = new BasicStroke((float) ROI2D.canvasToImageLogDeltaX(canvas, 2 ) );
stroke[1] = new BasicStroke((float) ROI2D.canvasToImageLogDeltaX(canvas, 3 ) );
stroke[2] = new BasicStroke((float) ROI2D.canvasToImageLogDeltaX(canvas, 4 ) );
stroke[3] = new BasicStroke((float) ROI2D.canvasToImageLogDeltaX(canvas, 5 ) );
// transform and display ticks
shapeDefinitionList.clear();
pushTransform( g );
double vx12 = ( a2.getX() - a1.getX() ) ;
double vy12 = ( a2.getY() - a1.getY() ) ;
double angle12 = Math.atan2( vy12 , vx12 ) * ( 180d / Math.PI ) ;
double vx13 = ( a3.getX() - a1.getX() ) ;
double vy13 = ( a3.getY() - a1.getY() ) ;
double angle13 = Math.atan2( vy13 , vx13 ) * ( 180d / Math.PI );
double angle1 = angle12-angle13;
if ( angle1 < 0 ) angle1+=360;
double angle2 = 360-angle1;
double dis1 = a1.getPosition().distance( a2.getPosition() );
double dis2 = a1.getPosition().distance( a3.getPosition() );
double minDistance = Math.min( dis1 , dis2 );
double distanceAngle1 = minDistance ;
double distanceAngle2 = minDistance / 2;
double distanceTextAngle1 = minDistance;
double distanceTextAngle2 = minDistance/2;
// Lines
shapeDefinitionList.add( new ShapeDefinition( 2 , new Line2D.Double( a1.getPosition() , a2.getPosition() ) ) );
shapeDefinitionList.add( new ShapeDefinition( 2 , new Line2D.Double( a1.getPosition() , a3.getPosition() ) ) );
// angle 1
{
double arcSize = distanceAngle1;
Arc2D arc = new Arc2D.Double(
a1.getX() - arcSize/2d,
a1.getY() - arcSize/2d,
arcSize,
arcSize,
-angle12 ,
angle1,//angle13,
Arc2D.OPEN
);
shapeDefinitionList.add( new ShapeDefinition( 2 , arc ) );
}
// angle 2
{
double arcSize = distanceAngle2;
Arc2D arc = new Arc2D.Double(
a1.getX() - arcSize/2d,
a1.getY() - arcSize/2d,
arcSize,
arcSize,
-angle13 ,
angle2,//angle13,
Arc2D.OPEN
);
shapeDefinitionList.add( new ShapeDefinition( 2 , arc ) );
}
// draw lines ( black background, then white )
float oldAlpha= -1;
g.setColor( Color.black );
for ( ShapeDefinition ld : shapeDefinitionList )
{
if (oldAlpha!=ld.alpha)
{
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ld.alpha ) );
oldAlpha = ld.alpha;
}
g.setStroke( stroke[ld.stroke] );
g.draw( ld.shape );
}
g.setColor( Color.white );
for ( ShapeDefinition ld : shapeDefinitionList )
{
if (oldAlpha!=ld.alpha)
{
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ld.alpha ) );
oldAlpha = ld.alpha;
}
g.setStroke( stroke[ld.stroke-1] );
g.draw( ld.shape );
}
// Display angle text
{
int fontSize = (int)convertScale(canvas, 15 );
Font font = new Font( "Arial" , Font.PLAIN , fontSize );
pushTransform( g );
String pixelString = " "+ (int)( Math.round( angle1 ) ) + "° ";
Rectangle2D pixelBounds = GuiUtil.getStringBounds( g , font, pixelString );
g.translate( a1.getX() , a1.getY() );
double angleText = Math.toRadians( angle12 - angle1 / 2d );
g.translate( Math.cos( angleText ) * distanceTextAngle1 /2 , Math.sin( angleText ) * distanceTextAngle1 /2 );
g.translate( -pixelBounds.getWidth() / 2 , 0 );
g.setFont( font );
g.setColor( Color.white );
g.fill( pixelBounds );
g.setColor( Color.black );
g.drawString( pixelString , 0, 0 );
popTransform( g );
}
{
int fontSize = (int)convertScale(canvas, 15 );
Font font = new Font( "Arial" , Font.PLAIN , fontSize );
pushTransform( g );
String pixelString = " "+ (int)(Math.round( angle2 ) ) + "� ";
Rectangle2D pixelBounds = GuiUtil.getStringBounds( g , font, pixelString );
g.translate( a1.getX() , a1.getY() );
double angleText = Math.toRadians( 180 + angle12 - angle1 / 2d );
g.translate( Math.cos( angleText ) * distanceTextAngle2 / 2d , Math.sin( angleText ) * distanceTextAngle2 / 2d );
g.translate( -pixelBounds.getWidth() / 2 , 0 );
float alpha = 1 ;
double distance = canvas.getScaleX() * distanceTextAngle2 / 2d ;
Scaler scaler = new Scaler( 0 , 10 , 0, 1 , false );
alpha = (float)scaler.scale( distance - pixelBounds.getWidth() / 10d );
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha ) );
g.setFont( font );
g.setColor( Color.white );
g.fill( pixelBounds );
g.setColor( Color.black );
g.drawString( pixelString , 0, 0 );
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1 ) );
popTransform( g );
}
// get back to original transform
popTransform( g );
// display anchors
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1 ) );
a1.paint( g, sequence, canvas);
a2.paint( g, sequence, canvas);
a3.paint( g, sequence, canvas);
}
double convertScale( IcyCanvas canvas , double value )
{
return ROI2D.canvasToImageLogDeltaX(canvas, value );
}
@Override
public void mousePressed(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
a1.mousePressed(e, imagePoint, canvas);
a2.mousePressed(e, imagePoint, canvas);
a3.mousePressed(e, imagePoint, canvas);
}
@Override
public void mouseReleased(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
a1.mouseReleased(e, imagePoint, canvas);
a2.mouseReleased(e, imagePoint, canvas);
a3.mouseReleased(e, imagePoint, canvas);
}
@Override
public void mouseClick(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
a1.mouseClick(e, imagePoint, canvas);
a2.mouseClick(e, imagePoint, canvas);
a3.mouseClick(e, imagePoint, canvas);
}
@Override
public void mouseMove(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
a1.mouseMove(e, imagePoint, canvas);
a2.mouseMove(e, imagePoint, canvas);
a3.mouseMove(e, imagePoint, canvas);
}
@Override
public void mouseDrag(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
a1.mouseDrag(e, imagePoint, canvas);
a2.mouseDrag(e, imagePoint, canvas);
a3.mouseDrag(e, imagePoint, canvas);
}
@Override
public void keyPressed(KeyEvent e, Point2D imagePoint, IcyCanvas canvas) {
if ( ( e.getKeyCode() == KeyEvent.VK_DELETE && a1.isSelected() ) || ( e.getKeyCode() == KeyEvent.VK_DELETE && a2.isSelected() ) )
{
for ( Sequence sequence : Icy.getMainInterface().getSequencesContaining( this ) )
{
sequence.removePainter( this );
}
}
a1.keyPressed(e, imagePoint, canvas);
a2.keyPressed(e, imagePoint, canvas);
a3.keyPressed(e, imagePoint, canvas);
}
@Override
public void keyReleased(KeyEvent e, Point2D imagePoint, IcyCanvas canvas) {
a1.keyReleased(e, imagePoint, canvas);
a2.keyReleased(e, imagePoint, canvas);
a3.keyReleased(e, imagePoint, canvas);
}
}