Example usage for java.awt.geom AffineTransform rotate

List of usage examples for java.awt.geom AffineTransform rotate

Introduction

In this page you can find the example usage for java.awt.geom AffineTransform rotate.

Prototype

public void rotate(double theta) 

Source Link

Document

Concatenates this transform with a rotation transformation.

Usage

From source file:statechum.analysis.learning.Visualiser.java

protected static PluggableRenderer constructRenderer(Graph g, final LayoutOptions options) {
    final LayoutOptions graphLayoutOptions = options != null ? options : new LayoutOptions();

    PluggableRenderer r = new PluggableRenderer() {
        /**//from   w w  w.j av a2 s . com
         * Draws the edge <code>e</code>, whose endpoints are at <code>(x1,y1)</code>
         * and <code>(x2,y2)</code>, on the graphics context <code>g</code>.
         * The <code>Shape</code> provided by the <code>EdgeShapeFunction</code> instance
         * is scaled in the x-direction so that its width is equal to the distance between
         * <code>(x1,y1)</code> and <code>(x2,y2)</code>.
         */
        @Override
        protected void drawSimpleEdge(Graphics2D g2d, Edge e, int x1, int y1, int x2, int y2) {
            final Vertex v1 = (Vertex) e.getEndpoints().getFirst();
            final Vertex v2 = (Vertex) e.getEndpoints().getSecond();
            boolean isLoop = v1.equals(v2);
            final Shape s2 = vertexShapeFunction.getShape(v2);
            Shape edgeShape = edgeShapeFunction.getShape(e);
            final double dx = x2 - x1;
            final double dy = y2 - y1;

            boolean edgeHit = true;
            boolean arrowHit = true;
            Rectangle deviceRectangle = null;
            if (screenDevice != null) {
                Dimension d = screenDevice.getSize();
                if (d.width <= 0 || d.height <= 0) {
                    d = screenDevice.getPreferredSize();
                }
                deviceRectangle = new Rectangle(0, 0, d.width, d.height);
            }

            String label = edgeStringer.getLabel(e);
            assert (label != null);
            Component labelComponent = prepareRenderer(graphLabelRenderer, label, isPicked(e), e);
            Dimension d = labelComponent.getPreferredSize();
            Rectangle2D EdgeShapeBoundaries = edgeShape.getBounds2D();
            AffineTransform xform = AffineTransform.getTranslateInstance(x1, y1);
            double yMin = 0, yMax = 0;
            double thetaRadians = 0;
            if (isLoop) {
                // this is a self-loop. scale it is larger than the vertex
                // it decorates and translate it so that its nadir is
                // at the center of the vertex.
                int edgeIndex = ParallelEdgeIndexSingleton.getInstance().getIndex(e);
                Rectangle2D s2Bounds = s2.getBounds2D();
                double scaleBy = 1 + (graphLayoutOptions.scaleLines - 1) * 1. / 3.;
                double translation = s2Bounds.getHeight() * (1. / 4. + edgeIndex / 4.);

                xform.translate(0, -scaleBy * translation);
                xform.scale(scaleBy * s2Bounds.getWidth(), scaleBy * s2Bounds.getHeight());
                yMin = scaleBy * (EdgeShapeBoundaries.getMinY() * s2Bounds.getHeight()) - translation;
                yMax = scaleBy * (EdgeShapeBoundaries.getMaxY() * s2Bounds.getHeight()) - translation;

            } else {
                // this is a normal edge. Rotate it to the angle between
                // vertex endpoints, then scale it to the distance between
                // the vertices
                thetaRadians = Math.atan2(dy, dx);
                double dist = Math.sqrt(dx * dx + dy * dy);
                xform.rotate(thetaRadians);
                xform.scale(dist, 1.0);
                yMin = EdgeShapeBoundaries.getMinY();
                yMax = EdgeShapeBoundaries.getMaxY();
            }

            edgeShape = xform.createTransformedShape(edgeShape);
            // Debug code
            /*
            if (!isLoop)
            {
            g2d.setPaint(new Color( 250, 250, 0));
               AffineTransform rect = AffineTransform.getTranslateInstance(x1, y1+yMin);
               rect.rotate(thetaRadians);
               g2d.fill(rect.createTransformedShape(
              new Rectangle(0,0,(int)Math.sqrt(dx*dx + dy*dy),(int)(yMax-yMin))));
            }
            else
            {
            g2d.setPaint(new Color( 100, 250, 0));
            AffineTransform rect = AffineTransform.getTranslateInstance(x1-s2.getBounds2D().getWidth()/2, y1+yMin);
               rect.rotate(thetaRadians);
               g2d.fill(rect.createTransformedShape(
              new Rectangle(0,0,(int)s2.getBounds2D().getWidth(),(int)(yMax-yMin))));
            }*/

            edgeHit = viewTransformer.transform(edgeShape).intersects(deviceRectangle);

            if (edgeHit == true) {
                Paint oldPaint = g2d.getPaint();

                // get Paints for filling and drawing
                // (filling is done first so that drawing and label use same Paint)
                Paint fill_paint = edgePaintFunction.getFillPaint(e);
                if (fill_paint != null) {
                    g2d.setPaint(fill_paint);
                    g2d.fill(edgeShape);
                }
                Paint draw_paint = edgePaintFunction.getDrawPaint(e);
                if (draw_paint != null) {
                    g2d.setPaint(draw_paint);
                    g2d.draw(edgeShape);
                }

                double scalex = g2d.getTransform().getScaleX();
                double scaley = g2d.getTransform().getScaleY();
                // see if arrows are too small to bother drawing
                if (scalex < .3 || scaley < .3)
                    return;

                if (edgeArrowPredicate.evaluate(e)) {

                    Shape destVertexShape = vertexShapeFunction.getShape((Vertex) e.getEndpoints().getSecond());
                    AffineTransform xf = AffineTransform.getTranslateInstance(x2, y2);
                    destVertexShape = xf.createTransformedShape(destVertexShape);

                    arrowHit = viewTransformer.transform(destVertexShape).intersects(deviceRectangle);
                    if (arrowHit) {

                        AffineTransform at;
                        if (edgeShape instanceof GeneralPath)
                            at = getArrowTransform((GeneralPath) edgeShape, destVertexShape);
                        else
                            at = getArrowTransform(new GeneralPath(edgeShape), destVertexShape);
                        if (at == null)
                            return;
                        Shape arrow = edgeArrowFunction.getArrow(e);
                        arrow = at.createTransformedShape(arrow);
                        // note that arrows implicitly use the edge's draw paint
                        g2d.fill(arrow);
                    }
                    assert !(e instanceof UndirectedEdge);
                }

                // For difference visualisation only
                boolean labelBelow = false;
                if (graphLayoutOptions.showDIFF && (draw_paint == null
                        || draw_paint instanceof Color && ((Color) draw_paint).equals(Color.BLACK)))
                    labelBelow = true;

                // Now draw the label.
                double xLabel = 0, yLabel = 0, xa = 0, ya = 0, rotation = thetaRadians;
                if (isLoop) {
                    double displacementY = labelBelow ? -yMin + d.height : -yMin + d.height,
                            displacementX = d.width / 2;
                    xa = x1 + dx / 2 + displacementY * Math.sin(thetaRadians);
                    ya = y1 + dy / 2 - displacementY * Math.cos(thetaRadians);
                    xLabel = xa - displacementX * Math.cos(thetaRadians);
                    yLabel = ya - displacementX * Math.sin(thetaRadians);
                } else if (dx < 0) {
                    double displacementY = labelBelow ? yMax - d.height : (-yMax - d.height),
                            displacementX = d.width / 2;
                    xa = x1 + dx / 2 + displacementY * Math.sin(thetaRadians);
                    ya = y1 + dy / 2 - displacementY * Math.cos(thetaRadians);
                    xLabel = xa + displacementX * Math.cos(thetaRadians);
                    yLabel = ya + displacementX * Math.sin(thetaRadians);
                    rotation = thetaRadians + Math.PI;
                } else {
                    double displacementY = labelBelow ? yMax : -yMax, displacementX = d.width / 2;
                    xa = x1 + dx / 2 + displacementY * Math.sin(thetaRadians);
                    ya = y1 + dy / 2 - displacementY * Math.cos(thetaRadians);
                    xLabel = xa - displacementX * Math.cos(thetaRadians);
                    yLabel = ya - displacementX * Math.sin(thetaRadians);
                }

                AffineTransform old = g2d.getTransform();
                AffineTransform labelTransform = new AffineTransform();
                // Debug code: 
                //g2d.drawLine((int)(x1+dx/2), (int)(y1+dy/2), (int)(xa), (int)(ya));g2d.drawLine((int)(xa), (int)(ya), (int)(xLabel), (int)(yLabel));
                labelTransform.translate(xLabel, yLabel);
                labelTransform.rotate(rotation);
                g2d.setTransform(labelTransform);
                rendererPane.paintComponent(g2d, labelComponent, screenDevice, 0, 0, d.width, d.height, true);
                g2d.setTransform(old);

                // restore old paint
                g2d.setPaint(oldPaint);
            } // if edgeHit == true
        }
    };
    r = labelEdges(g, r, graphLayoutOptions);
    r = labelVertices(r, g, graphLayoutOptions);
    r.setVertexIncludePredicate(new Predicate() {
        @Override
        public boolean evaluate(Object object) {
            if (!graphLayoutOptions.showIgnored && graphLayoutOptions.ignoredStates != null
                    && graphLayoutOptions.ignoredStates.contains(object.toString()))
                return false;

            if (graphLayoutOptions.showNegatives)
                return true;
            else
                return DeterministicDirectedSparseGraph.isAccept((Vertex) object);
        }
    });
    return r;
}