/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* * Paul Klint - Paul.Klint@cwi.nl - CWI
* * Arnold Lankamp - Arnold.Lankamp@cwi.nl
*******************************************************************************/
package org.rascalmpl.eclipse.library.vis.figure.combine.containers;
import static org.rascalmpl.eclipse.library.vis.properties.TwoDProperties.ALIGN;
import static org.rascalmpl.eclipse.library.vis.properties.TwoDProperties.SIZE;
import static org.rascalmpl.eclipse.library.vis.util.vector.Dimension.HOR_VER;
import java.util.List;
import org.rascalmpl.eclipse.library.vis.figure.Figure;
import org.rascalmpl.eclipse.library.vis.graphics.GraphicsContext;
import org.rascalmpl.eclipse.library.vis.properties.PropertyManager;
import org.rascalmpl.eclipse.library.vis.swt.applet.IHasSWTElement;
import org.rascalmpl.eclipse.library.vis.util.FigureMath;
import org.rascalmpl.eclipse.library.vis.util.vector.Coordinate;
import org.rascalmpl.eclipse.library.vis.util.vector.Dimension;
import org.rascalmpl.eclipse.library.vis.util.vector.Rectangle;
import org.rascalmpl.eclipse.library.vis.util.vector.TransformMatrix;
/**
*
* Ellipse that can act as container
*
* @author paulk
*
*/
public class Ellipse extends Container {
final static boolean debug = false;
final static double SHRINK_EXTRA = Math.sqrt(0.5);
public Ellipse(Figure inner, PropertyManager properties) {
super(inner, properties);
}
@Override
public void drawElement(GraphicsContext gc, List<IHasSWTElement> visibleSWTElements){
gc.ellipse(globalLocation.getX() , globalLocation.getY() , size.getX() , size.getY() );
}
@Override
public void computeMinSize() {
super.computeMinSize();
if(innerFig == null) return;
for(Dimension d : HOR_VER){
minSize.set(d, minSize.get(d)/SHRINK_EXTRA);
}
}
@Override
public void resizeElement(Rectangle view) {
super.resizeElement(view);
if(innerFig == null) return;
for(Dimension d : HOR_VER){
innerFig.localLocation.add(d,innerFig.size.get(d)*(1.0-SHRINK_EXTRA) * innerFig.prop.get2DReal(d, ALIGN));
innerFig.size.set(d, innerFig.size.get(d)*SHRINK_EXTRA);
}
}
@Override
String containerName(){
return "ellipse" + super.toString();
}
@Override
public boolean mouseInside(Coordinate c){
double w2 = size.getX()/2;
double h2 = size.getY()/2;
double X = globalLocation.getX() + w2;
double Y = globalLocation.getY() + h2;
double ex = (c.getX() - X) / w2;
double ey = (c.getY() - Y) / h2;
return ex * ex + ey * ey <= 1;
}
/**
* Draw a connection from an external position (fromX, fromY) to the center (X,Y) of the current figure.
* At the intersection with the border of the current figure, place an arrow that is appropriately rotated.
* @param X X of center of current figure
* @param Y Y of center of current figure
* @param fromX X of center of figure from which connection is to be drawn
* @param fromY Y of center of figure from which connection is to be drawn
* @param toArrow the figure to be used as arrow
*/
@Override
public void connectArrowFrom(double X, double Y, double fromX, double fromY,
Figure toArrow, GraphicsContext gc, List<IHasSWTElement> visibleSWTElements ) {
for(Dimension d : HOR_VER){
toArrow.minSize.set(d,toArrow.prop.get2DReal(d, SIZE));
}
toArrow.size.set(toArrow.minSize);
toArrow.globalLocation.set(0,0);
toArrow.localLocation.set(0,0);
toArrow.resize(null, new TransformMatrix());
if(fromX == X)
fromX += 0.00001;
double theta = FigureMath.atan((fromY - Y) / (fromX - X));
if(theta < 0){
if(fromX < X )
theta += FigureMath.PI;
} else {
if(fromX < X )
theta += FigureMath.PI;
}
double sint = FigureMath.sin(theta);
double cost = FigureMath.cos(theta);
double r = minSize.getY() * minSize.getX() / (4 * FigureMath.sqrt((minSize.getY()*minSize.getY()*cost*cost + minSize.getX()*minSize.getX()*sint*sint)/4));
double IX = X + r * cost;
double IY = Y + r * sint;
double rotd = -90 + Math.toDegrees(theta);
gc.pushMatrix();
gc.translate(IX, IY);
gc.rotate(rotd);
gc.translate(-toArrow.size.getX()/2.0,0);
toArrow.applyProperties(gc);
toArrow.drawElement(gc,visibleSWTElements);
gc.popMatrix();
}
@Override
public String toString(){
return String.format("Ellipse %s %s", globalLocation,size);
}
}