/***********************************************************************
* mt4j Copyright (c) 2008 - 2009 C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
*
* 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 org.mt4j.components.visibleComponents.shapes;
import java.util.ArrayList;
import java.util.List;
import org.mt4j.components.bounds.BoundsZPlaneRectangle;
import org.mt4j.components.bounds.IBoundingShape;
import org.mt4j.util.math.ToolsGeometry;
import org.mt4j.util.math.Vertex;
import processing.core.PApplet;
/**
* This class can be used to display a rounded rectangle shape.
*
* @author Christopher Ruff
*/
public class MTRoundRectangle extends MTPolygon {
//Draw first lines
private Vertex upperLineP1;
private Vertex upperLineP2;
private Vertex rLinep1;
private Vertex rLinep2;
//Draw the first arc
private Vertex lowerLinep1;
private Vertex lowerLinep2;
private Vertex lLinep1;
private Vertex lLinep2;
private float arcWidth;
private float arcHeight;
private int arcSegments;
private float x,y,z;
private float width;
private float height;
/**
* Instantiates a new mT round rectangle.
*
* @param x the x
* @param y the y
* @param z the z
* @param width the width
* @param height the height
* @param arcWidth the arc width
* @param arcHeight the arc height
* @param pApplet the applet
*/
public MTRoundRectangle(float x, float y, float z, float width, float height, float arcWidth, float arcHeight, PApplet pApplet) {
this(x, y, z, width, height, arcWidth, arcHeight, 50, pApplet);
}
/**
* Instantiates a new mT round rectangle.
*
* @param x the x
* @param y the y
* @param z the z
* @param width the width
* @param height the height
* @param arcWidth the arc width
* @param arcHeight the arc height
* @param segments the segments
* @param pApplet the applet
*/
public MTRoundRectangle(float x, float y, float z, float width, float height, float arcWidth, float arcHeight, int segments, PApplet pApplet) {
super(new Vertex[]{}, pApplet);
this.x = x;
this.y = y;
this.z = z;
this.arcWidth = arcWidth;
this.arcHeight = arcHeight;
this.width = width;
this.height = height;
//defines the resolution and thereby the vertex count of the arcs
this.arcSegments = segments;
//Arc Width may not be greater than the rectangles width
//and Arc height may not be greater than rectangles height!
this.setVertices(this.getRoundRectVerts(x, y, z, width, height, arcWidth, arcHeight, segments, true));
this.setBoundsBehaviour(AbstractShape.BOUNDS_ONLY_CHECK);
}
/* (non-Javadoc)
* @see com.jMT.components.visibleComponents.shapes.MTPolygon#computeDefaultBounds()
*/
@Override
protected IBoundingShape computeDefaultBounds(){
return new BoundsZPlaneRectangle(this);
}
/**
* Gets the round rect verts.
*
* @param x the x
* @param y the y
* @param z the z
* @param width the width
* @param height the height
* @param arcWidth the arc width
* @param arcHeight the arc height
* @param segments the segments
*
* @return the round rect verts
*/
private Vertex[] getRoundRectVerts(float x, float y, float z, float width, float height, float arcWidth, float arcHeight, int segments, boolean createTexCoords){
//Draw first lines
Vertex upperLineP1 = new Vertex(x + arcWidth, y, 0);
Vertex upperLineP2 = new Vertex(x + width - arcWidth , y, 0);
// Vertex upperLineP2 = new Vertex(x + arcWidth + width - 2*arcWidth , y, 0);
Vertex rLinep1 = new Vertex(x + width, y + arcHeight , 0);
Vertex rLinep2 = new Vertex(x + width, y + height - arcHeight, 0);
//Draw the first arc
List<Vertex> upperRightCorner = ToolsGeometry.arcTo(upperLineP2.x,upperLineP2.y, arcWidth, arcHeight, 0, false,true, rLinep1.x,rLinep1.y, arcSegments);
Vertex lowerLinep1 = new Vertex(x + width - arcWidth , y + height, 0);
Vertex lowerLinep2 = new Vertex(x + arcWidth , y + height, 0);
List<Vertex> lowerRightCorner = ToolsGeometry.arcTo(rLinep2.x,rLinep2.y, arcWidth, arcHeight, 0, false,true, lowerLinep1.x,lowerLinep1.y, arcSegments);
Vertex lLinep1 = new Vertex(x , y + height - arcHeight, 0);
Vertex lLinep2 = new Vertex(x , y + arcHeight, 0);
List<Vertex> lowerLeftCorner = ToolsGeometry.arcTo(lowerLinep2.x,lowerLinep2.y, arcWidth, arcHeight, 0, false,true, lLinep1.x,lLinep1.y, arcSegments);
List<Vertex> upperLeftCorner = ToolsGeometry.arcTo(lLinep2.x,lLinep2.y, arcWidth, arcHeight, 0, false,true, upperLineP1.x,upperLineP1.y, arcSegments);
ArrayList<Vertex> verts = new ArrayList<Vertex>();
verts.add(upperLineP1);
// verts.add(upperLineP2);
verts.addAll(upperRightCorner);
verts.add(rLinep1);
// verts.add(rLinep2);
verts.addAll(lowerRightCorner);
verts.add(lowerLinep1);
// verts.add(lowerLinep2);
verts.addAll(lowerLeftCorner);
verts.add(lLinep1);
// verts.add(lLinep2);
verts.addAll(upperLeftCorner);
Vertex[] newVertices = verts.toArray(new Vertex[verts.size()]);
//Set texture coordinates
if (createTexCoords){
for (int i = 0; i < newVertices.length; i++) {
Vertex vertex = newVertices[i];
vertex.setTexCoordU((vertex.x-x)/width);
vertex.setTexCoordV((vertex.y-y)/height);
//System.out.println("TexU:" + vertex.getTexCoordU() + " TexV:" + vertex.getTexCoordV());
}
}
return newVertices;
}
public void setSizeLocal(float width, float height){
if (width > 0 && height > 0){
this.setVertices(this.getRoundRectVerts(x, y, z, width, height, arcWidth, arcHeight, arcSegments, true));
}
}
// /**
// * Sets the size of the rectangle.
// * Changes the vertices themself, not the transform, to allow for hassle-free non-uniform scaling.
// * <p>Overridden because shearing will occur if the component was rotated and then scaled non-uniformly!
// * <br>This method preserves the orientation
// *
// * @param width the width
// * @param height the height
// *
// * @return true, if sets the size xy relative to parent
// */
// @Override
// public boolean setSizeXYRelativeToParent(float width, float height){
//// /*
// if (width > 0 && height > 0){
// this.setVertices(this.getRoundRectVerts(x, y, z, width, height, arcWidth, arcHeight, arcSegments, true));
// return true;
// }else{
// return false;
// }
//
//// */
//
//
//// if (width > 0 && height > 0){
//// Vertex[] v = this.getVerticesObjSpace();
//// this.setVertices(new Vertex[]{
//// new Vertex(v[0].x, v[0].y, v[0].z, v[0].getTexCoordU(), v[0].getTexCoordV()),
//// new Vertex(v[0].x+width, v[1].y, v[1].z, v[1].getTexCoordU(), v[1].getTexCoordV()),
//// new Vertex(v[0].x+width, v[1].y+height, v[2].z, v[2].getTexCoordU(), v[2].getTexCoordV()),
//// new Vertex(v[3].x, v[0].y+height, v[3].z, v[3].getTexCoordU(), v[3].getTexCoordV()),
//// new Vertex(v[4].x, v[4].y, v[4].z, v[4].getTexCoordU(), v[4].getTexCoordV()),
//// });
//// return true;
//// }else
//// return false;
// }
// /* (non-Javadoc)
// * @see com.jMT.components.visibleComponents.shapes.MTPolygon#setHeightXYRelativeToParent(float)
// */
// @Override
// public boolean setHeightXYRelativeToParent(float height){
// if (height > 0){
// Vertex[] v = this.getVerticesLocal();
// this.setVertices(new Vertex[]{
// new Vertex(v[0].x, v[0].y, v[0].z, v[0].getTexCoordU(), v[0].getTexCoordV()),
// new Vertex(v[1].x, v[1].y, v[1].z, v[1].getTexCoordU(), v[1].getTexCoordV()),
// new Vertex(v[2].x, v[1].y+height, v[2].z, v[2].getTexCoordU(), v[2].getTexCoordV()),
// new Vertex(v[3].x, v[1].y+height, v[3].z, v[3].getTexCoordU(), v[3].getTexCoordV()),
// new Vertex(v[4].x, v[4].y, v[4].z, v[4].getTexCoordU(), v[4].getTexCoordV()),
// });
// return true;
// }else
// return false;
// }
// /**
// * Scales the shape to the given width.
// * Uses the bounding rectangle for calculation!
// * Aspect ratio is preserved!
// *
// * @param width the width
// *
// * @return true, if the width isnt negative
// */
// @Override
// public boolean setWidthXYRelativeToParent(float width){
// if (width > 0){
// Vertex[] v = this.getVerticesLocal();
// this.setVertices(new Vertex[]{
// new Vertex(v[0].x, v[0].y, v[0].z, v[0].getTexCoordU(), v[0].getTexCoordV()),
// new Vertex(v[0].x+width, v[1].y, v[1].z, v[1].getTexCoordU(), v[1].getTexCoordV()),
// new Vertex(v[0].x+width, v[2].y, v[2].z, v[2].getTexCoordU(), v[2].getTexCoordV()),
// new Vertex(v[3].x, v[3].y, v[3].z, v[3].getTexCoordU(), v[3].getTexCoordV()),
// new Vertex(v[4].x, v[4].y, v[4].z, v[4].getTexCoordU(), v[4].getTexCoordV()),
// });
// return true;
// }else
// return false;
// }
}