teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5994: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.jfree; felix@3018: ingo@3765: import java.awt.Shape; ingo@3765: import java.awt.geom.Rectangle2D; ingo@3765: import java.util.Iterator; ingo@3765: import java.util.Random; ingo@3765: ingo@3765: import org.apache.log4j.Logger; ingo@3765: import org.jfree.chart.entity.ChartEntity; ingo@3765: import org.jfree.chart.entity.EntityCollection; ingo@3765: teichmann@5831: import org.dive4elements.river.artifacts.math.Function; teichmann@6905: import org.dive4elements.river.themes.ThemeDocument; sascha@3109: felix@3018: public class JFreeUtil { sascha@3772: ingo@3765: private static final Logger logger = Logger.getLogger(JFreeUtil.class); sascha@3076: felix@3018: /** Do not instantiate. */ felix@3018: private JFreeUtil() { felix@3018: } felix@3018: felix@3018: felix@3018: /** felix@3018: * True if \param hotspot collides with a Entity in \param entities. felix@3018: * @param hotspot Shape to compare against other shapes (bounds only). felix@3018: * @param entities entities against which to compare shape. felix@3023: * @param exclusiveEntityClass If not null, consider only entities of felix@3023: * given class. felix@3023: * @return true if a collision (non-zero intersection) exists between felix@3018: * shapes. felix@3018: */ felix@3023: public static boolean collides(Shape hotspot, EntityCollection entities, felix@3023: Class exclusiveEntityClass) { felix@3018: if (entities == null) return false; felix@3018: felix@3018: Rectangle2D hotspotBox = hotspot.getBounds2D(); sascha@3076: felix@3018: for (Iterator i = entities.iterator(); i.hasNext(); ) { felix@3018: Object next = i.next(); felix@3018: ChartEntity entity = (ChartEntity) next; felix@3023: if (exclusiveEntityClass == null felix@3023: || exclusiveEntityClass.isInstance(entity)) felix@3023: { felix@3023: if (entity.getArea().intersects(hotspotBox)) { felix@3023: // Found collision, early stop. felix@3023: return true; felix@3023: } felix@3018: } felix@3018: } felix@3018: felix@3018: return false; felix@3018: } sascha@3772: sascha@3772: ingo@3765: /** ingo@3765: * This function samples a randomized line that contains of x and y values ingo@3765: * between startX, endX, startY and endY. The ingo@3765: * number of points in the line is specified by num. sascha@3772: * ingo@3765: * @param num The number of points in the line. ingo@3765: * @param startX The min value of the x values. ingo@3765: * @param endX The max value of the x values. ingo@3765: * @param startY The min value of the y values. ingo@3765: * @param endY The max value of the y values. ingo@3765: * @return an array with [allX-values, allY-values]. ingo@3765: * @throws IllegalArgumentException ingo@3765: */ ingo@3765: public static double[][] randomizeLine( ingo@3765: int num, ingo@3765: double startX, ingo@3765: double endX, ingo@3765: double startY, ingo@3765: double endY ingo@3765: ) throws IllegalArgumentException ingo@3765: { ingo@3765: if (num <= 0) { ingo@3765: throw new IllegalArgumentException("Parameter 'num' has to be > 0"); ingo@3765: } sascha@3772: ingo@3765: Random random = new Random(); sascha@3772: ingo@3765: double[] x = new double[num]; ingo@3765: double[] y = new double[num]; sascha@3772: ingo@3765: for (int i = 0; i < num; i++) { ingo@3765: double xFac = random.nextDouble(); ingo@3765: double yFac = random.nextDouble(); sascha@3772: ingo@3765: x[i] = startX + xFac * (endX - startX); ingo@3765: y[i] = startY + yFac * (endY - startY); sascha@3772: ingo@3765: logger.debug("Created new point: " + x[i] + "|" + y[i]); ingo@3765: } sascha@3772: ingo@3765: return new double[][] { x, y }; ingo@3765: } ingo@3105: ingo@3105: ingo@3105: public static StyledXYSeries sampleFunction2D( sascha@3109: Function func, teichmann@6905: ThemeDocument theme, sascha@3109: String seriesKey, sascha@3109: int samples, sascha@3109: double start, sascha@3109: double end ingo@3105: ) { ingo@3105: StyledXYSeries series = new StyledXYSeries(seriesKey, theme); ingo@3105: ingo@3105: double step = (end - start) / (samples - 1); ingo@3105: ingo@3105: for (int i = 0; i < samples; i++) { ingo@3105: double x = start + (step * i); sascha@3109: series.add(x, func.value(x)); ingo@3105: } ingo@3105: ingo@3105: return series; ingo@3105: } teichmann@4564: teichmann@4564: public static StyledXYSeries sampleFunction2DPositive( teichmann@4564: Function func, teichmann@6905: ThemeDocument theme, teichmann@4564: String seriesKey, teichmann@4564: int samples, teichmann@4564: double start, teichmann@4564: double end teichmann@4564: ) { teichmann@4564: StyledXYSeries series = new StyledXYSeries(seriesKey, theme); teichmann@4564: teichmann@4564: double step = (end - start) / (samples - 1); teichmann@4564: teichmann@4564: for (int i = 0; i < samples; i++) { teichmann@4564: double x = start + (step * i); teichmann@4564: double v = func.value(x); teichmann@4564: if (x > 0d && v > 0d) { teichmann@4564: series.add(x, v); teichmann@4564: } teichmann@4564: } teichmann@4564: teichmann@4564: return series; teichmann@4564: } felix@3018: } sascha@3083: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :