All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.org.retep.util.graphics.Join Maven / Gradle / Ivy

The newest version!
/*
 * 

Copyright (c) 1998-2010, Peter T Mount
* All rights reserved.

* *

Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met:

* *
    *
  • Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer.
  • * *
  • Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution.
  • * *
  • Neither the name of the retep.org.uk nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission.
  • * *
* *

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/ package uk.org.retep.util.graphics; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.GeneralPath; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import uk.org.retep.swing.model.EnumModel; import uk.org.retep.util.string.StringUtils; /** * An enum defining how two entities are joined. * * @author peter */ public enum Join implements EnumModel.Renderable { CUBIC( 0 ), QUAD( 0 ), STRAIGHT( 0 ), DIRECT( 0 ), CUBIC_DASHED( 1 ), QUAD_DASHED( 1 ), STRAIGHT_DASHED( 1 ), DIRECT_DASHED( 1 ), CUBIC_DOTTED( 2 ), QUAD_DOTTED( 2 ), STRAIGHT_DOTTED( 2 ), DIRECT_DOTTED( 2 ); private int mode; private boolean fillable; Join( int mode ) { this.mode = mode; fillable = mode == 0; } /** * Draw the join between two Shapes * *

If bottom = false, [From] --> [To]

*

If bottom = true,

     *    [From]
* |
* V
* [To]

* * @param g Graphics * @param orientation Orientation of the graph * @param bottom true for NORMAL to draw from bottom of from, false for right of from * @param fromShape * @param toShape * @param fromJoin JoinEnd on start * @param toJoin JoinEnd on end */ public final void draw( Graphics g, Orientation orientation, boolean bottom, Shape fromShape, JoinEnd fromJoin, Shape toShape, JoinEnd toJoin ) { // Bounds Rectangle from = fromShape.getBounds(); Rectangle to = toShape.getBounds(); // Centres Point2D fc = GeomUtils.getCentre( fromShape ); Point2D tc = GeomUtils.getCentre( toShape ); double x1; double y1; double x2; double y2; double x3; double y3; double x4; double y4; if( bottom ) { // Join bottom to top switch( orientation ) { case FLIP_VERTICAL: case INVERTED: y1 = from.getY(); y4 = to.getY() + to.getHeight(); y2 = y3 = y4 + ((y1 - y4) / 2.0); break; default: y1 = from.getY() + from.getHeight(); y4 = to.getY(); y2 = y3 = y1 + ((y4 - y1) / 2.0); break; } x1 = x2 = fc.getX(); x3 = x4 = tc.getX(); } else { // Join right to left edges switch( orientation ) { case FLIP_HORIZONTAL: case INVERTED: x1 = from.getX(); x4 = to.getX() + to.getWidth(); x2 = x3 = x4 + ((x1 - x4) / 2.0); break; default: x1 = from.getX() + from.getWidth(); x4 = to.getX(); x2 = x3 = x1 + ((x4 - x1) / 2.0); break; } y1 = y2 = fc.getY(); y3 = y4 = tc.getY(); } // Now correct the start/end points so they intersect the shape Point2D pt = new Point2D.Double( x1, y1 ); Line2D line = new Line2D.Double( pt, fc ); Point2D np = GeomUtils.findIntersection( line, fromShape ); if( np != null ) { x1 = (int) np.getX(); y1 = (int) np.getY(); } pt.setLocation( x4, y4 ); line = new Line2D.Double( pt, tc ); np = GeomUtils.findIntersection( line, toShape ); if( np != null ) { x4 = (int) np.getX(); y4 = (int) np.getY(); } draw( g, x1, y1, x2, y2, x3, y3, x4, y4, fromJoin, toJoin ); } /** * Draw the join between two points with an arrow at the end * * @param g Graphics * @param x1 Start x * @param y1 Start y * @param x2 first intermediary x * @param y2 first intermediary x * @param x3 second intermediary x * @param y3 second intermediary x * @param x4 end x * @param y4 end y * @param fromJoin JoinEnd on start * @param toJoin JoinEnd on end */ public final void draw( Graphics g, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, JoinEnd fromJoin, JoinEnd toJoin ) { draw( (Graphics2D) g, x1, y1, x2, y2, x3, y3, x4, y4, fromJoin, toJoin ); } /** * Draw the join between two points with an arrow at the end * * @param g Graphics2D * @param x1 Start x * @param y1 Start y * @param x2 first intermediary x * @param y2 first intermediary x * @param x3 second intermediary x * @param y3 second intermediary x * @param x4 end x * @param y4 end y * @param fromJoin JoinEnd on start * @param toJoin JoinEnd on end */ public final void draw( Graphics2D g, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, JoinEnd fromJoin, JoinEnd toJoin ) { draw( g, x1, y1, x2, y2, x3, y3, x4, y4, fromJoin, toJoin, null, null ); } /** * Draw the join between two points with an arrow at the end * * @param g Graphics2D * @param x1 Start x * @param y1 Start y * @param x2 first intermediary x * @param y2 first intermediary x * @param x3 second intermediary x * @param y3 second intermediary x * @param x4 end x * @param y4 end y * @param fromJoin JoinEnd on start * @param toJoin JoinEnd on end * @param color colour of the Join */ public final void draw( Graphics2D g, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, JoinEnd fromJoin, JoinEnd toJoin, Color color ) { draw( g, x1, y1, x2, y2, x3, y3, x4, y4, fromJoin, toJoin, color, color ); } /** * Draw the join between two points with an arrow at the end * * @param g Graphics2D * @param x1 Start x * @param y1 Start y * @param x2 first intermediary x * @param y2 first intermediary x * @param x3 second intermediary x * @param y3 second intermediary x * @param x4 end x * @param y4 end y * @param fromJoin JoinEnd on start * @param toJoin JoinEnd on end * @param borderColor colour of the Join border * @param fillColor colour of the Join fill */ public final void draw( Graphics2D g, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, JoinEnd fromJoin, JoinEnd toJoin, Color borderColor, Color fillColor ) { Graphics2D g2 = (Graphics2D) g.create(); try { GeneralPath p = new GeneralPath(); if( fillable ) { appendPath( p, (float) x1, (float) y1, (float) x2, (float) y2, (float) x3, (float) y3, (float) x4, (float) y4, fromJoin, toJoin, true ); if( fillColor != null ) { g2.setColor( fillColor ); } else if( borderColor != null ) { g2.setColor( borderColor ); } g2.fill( p ); p.reset(); } appendPath( p, (float) x1, (float) y1, (float) x2, (float) y2, (float) x3, (float) y3, (float) x4, (float) y4, fromJoin, toJoin, false ); if( borderColor != null ) { g2.setColor( borderColor ); } switch( mode ) { case 0: break; case 1: GeomUtils.setDashStroke( g2, 8.0f, 4.0f ); break; case 2: GeomUtils.setDashStroke( g2, 4.0f, 4.0f ); break; } g2.draw( p ); } finally { g2.dispose(); } } /** * Append the join to an existing GeneralPath * * @param p GeneralPath * @param x1 Start x * @param y1 Start y * @param x2 first intermediary x * @param y2 first intermediary x * @param x3 second intermediary x * @param y3 second intermediary x * @param x4 end x * @param y4 end y * @param fromJoin JoinEnd on start * @param toJoin JoinEnd on end * @param forFill * @return GeneralPath p */ public final GeneralPath appendPath( GeneralPath p, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, JoinEnd fromJoin, JoinEnd toJoin, boolean forFill ) { if( p == null ) { p = new GeneralPath(); } // x1a, y1a is the start control point Point2D pt = fromJoin.getJoinPoint( x1, y1, x2, y2 ); float x1a = (float) pt.getX(); float y1a = (float) pt.getY(); // x4a, y4a is the end control point pt = toJoin.getJoinPoint( x4, y4, x3, y3 ); float x4a = (float) pt.getX(); float y4a = (float) pt.getY(); // Now append the fromJoin JoinEnd p = fromJoin.appendPath( p, x1, y1, x1a, y1a, false, forFill ); switch( this ) { case STRAIGHT: case STRAIGHT_DASHED: case STRAIGHT_DOTTED: default: p.lineTo( x2, y2 ); p.lineTo( x3, y3 ); p.lineTo( x4a, y4a ); break; case DIRECT: case DIRECT_DASHED: case DIRECT_DOTTED: p.lineTo( x4a, y4a ); break; case CUBIC: case CUBIC_DASHED: case CUBIC_DOTTED: p.curveTo( x2, y2, x3, y3, x4a, y4a ); break; case QUAD: case QUAD_DASHED: case QUAD_DOTTED: p.quadTo( x2, y2, x2 + ((x3 - x2) / 2.0f), y2 + ((y3 - y2) / 2.0f) ); p.quadTo( x3, y3, x4a, y4a ); break; } p = toJoin.appendPath( p, x4, y4, x4a, y4a, true, forFill ); if( forFill ) { // Back over the join (for filling) switch( this ) { case STRAIGHT: case STRAIGHT_DASHED: case STRAIGHT_DOTTED: default: p.lineTo( x3, y3 ); p.lineTo( x2, y2 ); p.lineTo( x1a, y1a ); break; case DIRECT: case DIRECT_DASHED: case DIRECT_DOTTED: p.lineTo( x1a, y1a ); break; case CUBIC: case CUBIC_DASHED: case CUBIC_DOTTED: p.curveTo( x3, y3, x2, y2, x1a, y1a ); break; case QUAD: case QUAD_DASHED: case QUAD_DOTTED: p.quadTo( x3, y3, x2 + ((x3 - x2) / 2.0f), y2 + ((y3 - y2) / 2.0f) ); p.quadTo( x2, y2, x1a, y1a ); break; } // Move to the end (contract that the path will end at the end of // the Join //p.moveTo( x4, y4 ); } return p; } public String getDescription() { return StringUtils.capitaliseEnum( toString() ); } public void render( Graphics2D g, int w, int h ) { double x1 = ((double) w - 8.0) / 3.0; double x2 = x1 + x1; double x3 = x2 + x1; double y1 = (double) h / 3.0; double y2 = y1 + y1; draw( g, x1, y1, x2, y1, x2, y2, x3, y2, JoinEnd.NONE, JoinEnd.NONE ); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy