Package org.mt4j.components.clusters

Source Code of org.mt4j.components.clusters.Cluster

/***********************************************************************
* 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.clusters;


import java.util.ArrayList;

import org.mt4j.components.MTComponent;
import org.mt4j.components.TransformSpace;
import org.mt4j.components.bounds.BoundsArbitraryPlanarPolygon;
import org.mt4j.components.bounds.BoundsZPlaneRectangle;
import org.mt4j.components.visibleComponents.shapes.AbstractShape;
import org.mt4j.components.visibleComponents.shapes.MTPolygon;
import org.mt4j.util.math.ConvexQuickHull2D;
import org.mt4j.util.math.Matrix;
import org.mt4j.util.math.Vector3D;
import org.mt4j.util.math.Vertex;

import processing.core.PApplet;

/**
* The Class Cluster.
* @author Christopher Ruff
*/
public class Cluster extends MTComponent { //extends MTComponent/implements IMTComponent3D?
  /** The selection polygon. */
private MTPolygon selectionPolygon;
 
//FIXME THIS WHOLE CLASS SHOULD BE RE-WORKED!
//Disadvantages of the cluster:
//each of the children are transformed, not only the cluster parent -> performance..
//hardwired into mtcanvas -> should be removed..
//could be replaced with a composite component -> but then we have the problem of picking child components of the group
 
  /**
   * Instantiates a new cluster.
   *
   * @param pApplet the applet
   * @param selectionPolygon the selection polygon
   */
  public Cluster(PApplet pApplet,MTPolygon selectionPolygon) {
    this(pApplet, new MTComponent[]{}, selectionPolygon);
  }

  /**
   * Info: Cluster can only hold instances of MTBaseComponent!.
   *
   * @param pApplet the applet
   * @param components the components
   * @param selectionPolygon the selection polygon
   */
  public Cluster(PApplet pApplet, MTComponent[] components, MTPolygon selectionPolygon) {
    super(pApplet);
   
    this.selectionPolygon = selectionPolygon;
    if (selectionPolygon != null){
      this.addChild(selectionPolygon);
    }
   
    for (int i = 0; i < components.length; i++) {
      MTComponent component3D = components[i];
      this.addChild(component3D);
    }
   
    this.setName("unnamed Cluster");
  }
 
 

  /**
   * Gets the cluster polygon.
   *
   * @return the cluster polygon
   */
  public MTPolygon getClusterPolygon() {
    return selectionPolygon;
  }

  /**
   * Calculates the convex hull of all its children.
   * Then changes the cluster-polygon to represent that convex hull
   * and adds it as a child.
   */
  public void packClusterPolygon(){
    ArrayList<Vector3D> allClusteredVerts = new ArrayList<Vector3D>();
    int shapes = 0;
   
    //Remove the old clusterpoly
    MTPolygon clusterPoly = getClusterPolygon();
    this.removeChild(clusterPoly);
   
    MTComponent[] children = this.getChildren();
    for (int i = 0; i < children.length; i++) {
      MTComponent component = children[i];
     
      //Get vertices for convex hull of all selected components
      if (component instanceof AbstractShape){
        shapes++;
        AbstractShape shape = (AbstractShape)component;
//        Vertex[] verts = shape.getVerticesPickingWorld();
        Vector3D[] verts = null;
       
//        if (shape.isBoundingShapeSet()){
//           verts = shape.getBoundingShape().getVectorsGlobal();
//        }else{
//           verts = shape.getVerticesGlobal();
//        }
       
        if (shape.hasBounds()){
          if (shape.getBounds() instanceof BoundsZPlaneRectangle || shape.getBounds() instanceof BoundsArbitraryPlanarPolygon){
            verts = shape.getBounds().getVectorsGlobal();
          }else{
            BoundsZPlaneRectangle b = new BoundsZPlaneRectangle(shape);
            verts = b.getVectorsGlobal();
          }
        }else{
          BoundsZPlaneRectangle b = new BoundsZPlaneRectangle(shape);
          verts = b.getVectorsGlobal();
//           verts = shape.getVerticesGlobal();
        }
       
        for (Vector3D v : verts){
          allClusteredVerts.add(v);
        }
      }
    }
   
    if (shapes != 0 && shapes == children.length){ //If all children are of type abstractShape
     
      ArrayList<Vector3D> hull = ConvexQuickHull2D.getConvexHull2D(allClusteredVerts);
      if (hull.size() > 0){
        //Correctly close polygon with 1.st vertex again
        hull.add(hull.get(0).getCopy());
       
        Vertex[] newVerts = new Vertex[hull.size()];
        for (int i = 0; i < hull.size(); i++) {
          Vector3D vec = hull.get(i);
          newVerts[i] = new Vertex(vec);
        }
       
//        Vertex[] newVerts = (Vertex[])hull.toArray(new Vertex[hull.size()]);
//        System.out.println("Hull vertices: ");
        for (Vertex v : newVerts){
          v.setRGBA(100,150,250, 50);
        }
       
        clusterPoly.setVertices(newVerts);
       
        clusterPoly.setBoundsBehaviour(AbstractShape.BOUNDS_DONT_USE);
//        clusterPoly.setBoundingShape(new BoundsArbitraryPlanarPolygon(clusterPoly, clusterPoly.getVerticesLocal()));
       
        //Reset matrix of the clusterpoly because the new vertices are set at the global location
        clusterPoly.setLocalMatrix(new Matrix());
       
        //FIXME center are is negative if verts are in counterclockwise order?
//        Vector3D clusterCenter = clusterPoly.getCenterPointGlobal();
//        clusterPoly.scaleGlobal(1.1f, 1.1f, 1, new Vector3D(-1* clusterCenter.x, -1 * clusterCenter.y, clusterCenter.z));
        clusterPoly.scale(1.1f, 1.1f, 1, clusterPoly.getCenterPointLocal(), TransformSpace.LOCAL);
        this.addChild(clusterPoly);
      }else{
        System.err.println("Couldnt pack polygon.");
      }
    }
  }

  /**
   * overridden to only put the cluster polygon last
   * in its parent list.
   */
  @Override
  public void sendToFront() {
    if (this.getClusterPolygon() != null){
      this.getClusterPolygon().sendToFront();
    }
   
    for (int i = 0; i < this.getChildren().length; i++) {
      MTComponent childComp = this.getChildren()[i];
      if (!childComp.equals(this.getClusterPolygon()))
        childComp.sendToFront();
    }
  }

  @Override
  public void addChild(int i, MTComponent tangibleComp) {
    //Overridden, so the component keeps it original parent
    this.getChildList().add(i, tangibleComp);
  }

  @Override
  public void addChild(MTComponent tangibleComp) {
    this.getChildList().add(tangibleComp);
  }

  @Override
  public void addChildren(MTComponent[] tangibleComps) {
    for (int i = 0; i < tangibleComps.length; i++) {
      MTComponent object = tangibleComps[i];
     
      //Add direct objects
      this.getChildList().add(object);
    }
  }

  @Override
  public void removeAllChildren() {
    this.getChildList().clear();
  }

  @Override
  public void removeChild(int i) {
    this.getChildList().remove(i);
  }

  @Override
  public void removeChild(MTComponent comp) {
    this.getChildList().remove(comp);
  }
 
 
  //TODO GANZE CLUSTERING �BERARBEITEN
  //SO GIBTS PROBLEME WENN GECLUSTERTE OBJECTE IN VERSCHIEDENEN PARENTS SIND
  // => DANN WERDEN SIE VERSCHIEDEN TRANSFORMIERT
  //  aM BESTEN ALLE ALS KINDER DES CLUSTERPOLYS MACHEN UND DAS AUF COMPOSITE=TRUE MACHEN
  //  ABER WOHIN GEHEN SIE WENN SIE AUS DEM CLUSTER GEL�ST WERDEN? VIELLEICHT GIBTS DIE ALTE GRUPPE NICHT MEHR?
  //  DANN AUF DEN WORLD CANVAS SETZEN; => ABER AN GLEICHER STELLE!
 
 
  /**
   * Transforms the shapes local coordinate space by the given matrix.
   *
   * @param transformMatrix the transform matrix
   */
  public void transform(Matrix transformMatrix) {
    for (MTComponent c : this.getChildList()){
      c.transform(transformMatrix);
    }
  }

 
  public void translateGlobal(Vector3D dirVect) {
    for (MTComponent c : this.getChildList()){
      c.translateGlobal(dirVect);
    }
  }
 
  public void translate(Vector3D dirVect) {
    for (MTComponent c : this.getChildList()){
      c.translate(dirVect);
    }
  }
 
 
  public void rotateXGlobal(Vector3D rotationPoint, float degree) {
    for (MTComponent c : this.getChildList()){
      c.rotateXGlobal(rotationPoint, degree);
    }
  }
 
  public void rotateX(Vector3D rotationPoint, float degree) {
    for (MTComponent c : this.getChildList()){
      c.rotateX(rotationPoint, degree);
    }
  }
 
 
  public void rotateYGlobal(Vector3D rotationPoint, float degree) {
    for (MTComponent c : this.getChildList()){
      c.rotateYGlobal(rotationPoint, degree);
    }
  }
 
  public void rotateY(Vector3D rotationPoint, float degree) {
    for (MTComponent c : this.getChildList()){
      c.rotateY(rotationPoint, degree);
    }
  }
 
  public void rotateZGlobal(Vector3D rotationPoint, float degree) {
    for (MTComponent c : this.getChildList()){
      c.rotateZGlobal(rotationPoint, degree);
    }
  }
 
 
  public void rotateZ(Vector3D rotationPoint, float degree) {
    for (MTComponent c : this.getChildList()){
      c.rotateZ(rotationPoint, degree);
    }
  }

  public void scaleGlobal(float factor, Vector3D scaleReferencePoint) {
    this.scaleGlobal(factor, factor, factor, scaleReferencePoint);
  }
 
  /**
   * scales the polygon around the scalingPoint, currently dosent support scaling around the Z axis.
   *
   * @param X the x
   * @param Y the y
   * @param Z the z
   * @param scalingPoint the scaling point
   */
  public void scaleGlobal(float X, float Y, float Z, Vector3D scalingPoint) {
    for (MTComponent c : this.getChildList()){
      c.scaleGlobal(X,  Y,  Z, scalingPoint);
    }
  }
 
 
  public void scale(float factor, Vector3D scaleReferencePoint) {
    this.scale(factor, factor, factor, scaleReferencePoint);
  }
 
  /**
   * scales the polygon around the scalingPoint, currently dosent support scaling around the Z axis.
   *
   * @param X the x
   * @param Y the y
   * @param Z the z
   * @param scalingPoint the scaling point
   */
  public void scale(float X, float Y, float Z, Vector3D scalingPoint) {
    for (MTComponent c : this.getChildList()){
      c.scale(X,  Y,  Z, scalingPoint);
    }
  }
}
TOP

Related Classes of org.mt4j.components.clusters.Cluster

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.