@Override public void fullRedraw() { setupCanvas(); final StyleLibrary style = context.getStyleLibrary(); CSSClass css = new CSSClass(svgp, POLYS); // TODO: separate fill and line colors? css.setStatement( SVGConstants.CSS_STROKE_WIDTH_PROPERTY, style.getLineWidth(StyleLibrary.POLYGONS)); css.setStatement(SVGConstants.CSS_STROKE_PROPERTY, style.getColor(StyleLibrary.POLYGONS)); css.setStatement(SVGConstants.CSS_FILL_PROPERTY, SVGConstants.CSS_NONE_VALUE); svgp.addCSSClassOrLogError(css); svgp.updateStyleElement(); // draw data for (DBIDIter iditer = rep.iterDBIDs(); iditer.valid(); iditer.advance()) { try { PolygonsObject poly = rep.get(iditer); if (poly == null) { continue; } SVGPath path = new SVGPath(); for (Polygon ppoly : poly.getPolygons()) { Vector first = ppoly.get(0); double[] f = proj.fastProjectDataToRenderSpace(first.getArrayRef()); path.moveTo(f[0], f[1]); for (ArrayListIter<Vector> it = ppoly.iter(); it.valid(); it.advance()) { if (it.getOffset() == 0) { continue; } double[] p = proj.fastProjectDataToRenderSpace(it.get().getArrayRef()); path.drawTo(p[0], p[1]); } // close path. path.drawTo(f[0], f[1]); } Element e = path.makeElement(svgp); SVGUtil.addCSSClass(e, POLYS); layer.appendChild(e); } catch (ObjectNotFoundException e) { // ignore. } } }
/** * Constructor. * * @param points Polygon points */ public Polygon(List<Vector> points) { super(); this.points = points; // Compute the bounds. if (points.size() > 0) { final Iterator<Vector> iter = points.iterator(); final Vector first = iter.next(); final int dim = first.getDimensionality(); min = first.getArrayCopy(); max = first.getArrayCopy(); while (iter.hasNext()) { Vector next = iter.next(); for (int i = 0; i < dim; i++) { final double cur = next.get(i); min[i] = Math.min(min[i], cur); max[i] = Math.max(max[i], cur); } } } }
/** * Point in polygon test, based on * * <p>http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html * * <p>by W. Randolph Franklin * * @param v Point to test * @return True when contained. */ public boolean containsPoint2D(Vector v) { assert (v.getDimensionality() == 2); final double testx = v.get(0); final double testy = v.get(1); boolean c = false; Iterator<Vector> it = points.iterator(); Vector pre = points.get(points.size() - 1); while (it.hasNext()) { final Vector cur = it.next(); final double curx = cur.get(0); final double cury = cur.get(1); final double prex = pre.get(0); final double prey = pre.get(1); if (((cury > testy) != (prey > testy))) { if ((testx < (prex - curx) * (testy - cury) / (prey - cury) + curx)) { c = !c; } } pre = cur; } return c; }
/** * Write the resulting clusters to an output stream. * * @param outStream output stream * @param data Generated data * @throws IOException thrown on write errors */ public void writeClusters(OutputStreamWriter outStream, MultipleObjectsBundle data) throws IOException { int modelcol = -1; { // Find model column for (int i = 0; i < data.metaLength(); i++) { if (TypeUtil.MODEL.isAssignableFromType(data.meta(i))) { modelcol = i; break; } } } if (modelcol < 0) { throw new AbortException("No model column found in bundle."); } ArrayList<Model> models = new ArrayList<>(); Map<Model, TIntList> modelMap = new HashMap<>(); { // Build a map from model to the actual objects for (int i = 0; i < data.dataLength(); i++) { Model model = (Model) data.data(i, modelcol); TIntList modelids = modelMap.get(model); if (modelids == null) { models.add(model); modelids = new TIntArrayList(); modelMap.put(model, modelids); } modelids.add(i); } } // compute global discard values int totalsize = 0, totaldisc = 0; for (Entry<Model, TIntList> ent : modelMap.entrySet()) { totalsize += ent.getValue().size(); if (ent.getKey() instanceof GeneratorSingleCluster) { totaldisc += ((GeneratorSingleCluster) ent.getKey()).getDiscarded(); } } double globdens = (double) (totalsize + totaldisc) / totalsize; outStream .append("########################################################") .append(LINE_SEPARATOR); outStream.append("## Number of clusters: " + models.size()).append(LINE_SEPARATOR); for (Model model : models) { TIntList ids = modelMap.get(model); outStream .append("########################################################") .append(LINE_SEPARATOR); outStream.append("## Size: " + ids.size()).append(LINE_SEPARATOR); if (model instanceof GeneratorSingleCluster) { GeneratorSingleCluster cursclus = (GeneratorSingleCluster) model; outStream .append("########################################################") .append(LINE_SEPARATOR); outStream.append("## Cluster: ").append(cursclus.getName()).append(LINE_SEPARATOR); Vector cmin = cursclus.getClipmin(); Vector cmax = cursclus.getClipmax(); if (cmin != null && cmax != null) { outStream .append("## Clipping: ") .append(cmin.toString()) // .append(" - ") .append(cmax.toString()) .append(LINE_SEPARATOR); } outStream .append("## Density correction factor: " + cursclus.getDensityCorrection()) .append(LINE_SEPARATOR); outStream.append("## Generators:").append(LINE_SEPARATOR); for (int i = 0; i < cursclus.getDim(); i++) { Distribution gen = cursclus.getDistribution(i); outStream.append("## ").append(gen.toString()).append(LINE_SEPARATOR); } if (cursclus.getTransformation() != null && cursclus.getTransformation().getTransformation() != null) { outStream.append("## Affine transformation matrix:").append(LINE_SEPARATOR); outStream .append(FormatUtil.format(cursclus.getTransformation().getTransformation(), "## ")) .append(LINE_SEPARATOR); } outStream .append( "## Discards: " + cursclus.getDiscarded() + " Retries left: " + cursclus.getRetries()) .append(LINE_SEPARATOR); double corf = /* cursclus.overweight */ (double) (cursclus.getSize() + cursclus.getDiscarded()) / cursclus.getSize() / globdens; outStream.append("## Density correction factor estimation: " + corf).append(LINE_SEPARATOR); } outStream .append("########################################################") .append(LINE_SEPARATOR); for (TIntIterator iter = ids.iterator(); iter.hasNext(); ) { int num = iter.next(); for (int c = 0; c < data.metaLength(); c++) { if (c != modelcol) { if (c > 0) { outStream.append(' '); } outStream.append(data.data(num, c).toString()); } } outStream.append(LINE_SEPARATOR); } } }