view java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/ArrowHead.java @ 0:78b7fc5391a2

first import, outcome of NIME 2014 hackaton
author Fiore Martin <f.martin@qmul.ac.uk>
date Tue, 08 Jul 2014 16:28:59 +0100
parents
children
line wrap: on
line source
/*  
 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
	  
 Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com)
 Copyright (C) 2011  Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package uk.ac.qmul.eecs.ccmi.simpletemplate;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.io.IOException;

/**
   This class defines arrowheads of diverse shapes.
*/
public enum ArrowHead {
	TAIL("Tail"),
	TRIANGLE("Triangle"),
    BLACK_TRIANGLE("Black Triangle"),
    V("V"),
	HALF_V("Half V"),
	DIAMOND("Diamond"),
	BLACK_DIAMOND("Black Diamond");
	
   private ArrowHead(String name) {
	   this.lowerCaseName = name;
   }
   
   public static ArrowHead getArrowHeadFromString(String arrowHeadName) throws IOException{
	   ArrowHead h;
	   String name = arrowHeadName.toUpperCase().replace(" ", "_");
	   try {
		   h = ArrowHead.valueOf(name);
	   }catch (IllegalArgumentException e){
		   throw new IOException(e);
	   }
	   return h;
   }
   
   @Override
   public String toString(){
	   return lowerCaseName;
   }
   
   /**
      Draws the arrowhead.
      @param g2 the graphics context
      @param p a point on the axis of the arrow head
      @param q the end point of the arrow head
   */
   public void draw(Graphics2D g2, Point2D p, Point2D q){
      GeneralPath path = getPath(p, q);
      Color oldColor = g2.getColor();
      if (this == BLACK_DIAMOND || this == BLACK_TRIANGLE)
         g2.setColor(Color.BLACK);
      else
         g2.setColor(Color.WHITE);
      g2.fill(path);
      g2.setColor(oldColor);
      Stroke oldStroke = g2.getStroke();
      g2.setStroke(new BasicStroke());
      g2.draw(path);
      g2.setStroke(oldStroke);
   }

   /**
      Gets the path of the arrowhead
      @param p a point on the axis of the arrow head
      @param q the end point of the arrow head
      @return the path
   */
   public GeneralPath getPath(Point2D p, Point2D q){
      GeneralPath path = new GeneralPath();
      final double ARROW_ANGLE = Math.PI / 6;
      final double ARROW_LENGTH = 10;

      double dx = q.getX() - p.getX();
      double dy = q.getY() - p.getY();
      double angle = Math.atan2(dy, dx);
      double x1 = q.getX() 
         - ARROW_LENGTH * Math.cos(angle + ARROW_ANGLE);
      double y1 = q.getY() 
         - ARROW_LENGTH * Math.sin(angle + ARROW_ANGLE);
      double x2 = q.getX() 
         - ARROW_LENGTH * Math.cos(angle - ARROW_ANGLE);
      double y2 = q.getY() 
         - ARROW_LENGTH * Math.sin(angle - ARROW_ANGLE);

      path.moveTo((float)q.getX(), (float)q.getY());
      path.lineTo((float)x1, (float)y1);
      if (this == V)
      {
         path.moveTo((float)x2, (float)y2);
         path.lineTo((float)q.getX(), (float)q.getY());
      }
      else if (this == TRIANGLE || this == BLACK_TRIANGLE)
      {
         path.lineTo((float)x2, (float)y2);
         path.closePath();                  
      }
      else if (this == DIAMOND || this == BLACK_DIAMOND)
      {
         double x3 = x2 - ARROW_LENGTH * Math.cos(angle + ARROW_ANGLE);
         double y3 = y2 - ARROW_LENGTH * Math.sin(angle + ARROW_ANGLE);
         path.lineTo((float)x3, (float)y3);
         path.lineTo((float)x2, (float)y2);
         path.closePath();         
      }      
      return path;
   }
   
   private String lowerCaseName;
}