Search in sources :

Example 1 with CanvasSize

use of de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize in project elki by elki-project.

the class VoronoiDraw method drawVoronoi.

/**
 * Draw a Voronoi diagram
 *
 * @param proj Projection
 * @param delaunay Delaunay triangulation
 * @param means Cluster means
 * @return SVG path
 */
public static SVGPath drawVoronoi(Projection2D proj, List<SweepHullDelaunay2D.Triangle> delaunay, List<double[]> means) {
    final SVGPath path = new SVGPath();
    CanvasSize viewport = proj.estimateViewport();
    for (int i = 0; i < delaunay.size(); i++) {
        SweepHullDelaunay2D.Triangle del = delaunay.get(i);
        final double[] projcx = proj.fastProjectDataToRenderSpace(del.m);
        if (del.ab > i) {
            Triangle oth = delaunay.get(del.ab);
            double[] p1 = projcx.clone(), p2 = proj.fastProjectDataToRenderSpace(oth.m);
            if (viewport.clipToMargin(p1, p2)) {
                path.moveTo(p1);
                path.drawTo(p2);
            }
        } else if (del.ab < 0) {
            double[] dirv = VMath.minus(means.get(del.a), means.get(del.b));
            VMath.rotate90Equals(dirv);
            double[] dir = proj.fastProjectRelativeDataToRenderSpace(dirv);
            final double factor = viewport.continueToMargin(projcx, dir);
            if (factor > 0) {
                path.moveTo(projcx);
                path.relativeLineTo(factor * dir[0], factor * dir[1]);
            }
        }
        if (del.bc > i) {
            Triangle oth = delaunay.get(del.bc);
            double[] p1 = projcx.clone(), p2 = proj.fastProjectDataToRenderSpace(oth.m);
            if (viewport.clipToMargin(p1, p2)) {
                path.moveTo(p1);
                path.drawTo(p2);
            }
        } else if (del.bc < 0) {
            double[] dirv = VMath.minus(means.get(del.b), means.get(del.c));
            VMath.rotate90Equals(dirv);
            double[] dir = proj.fastProjectRelativeDataToRenderSpace(dirv);
            final double factor = viewport.continueToMargin(projcx, dir);
            if (factor > 0) {
                path.moveTo(projcx);
                path.relativeLineTo(factor * dir[0], factor * dir[1]);
            }
        }
        if (del.ca > i) {
            Triangle oth = delaunay.get(del.ca);
            // No need to clone projcx here.
            double[] projca = proj.fastProjectDataToRenderSpace(oth.m);
            if (viewport.clipToMargin(projcx, projca)) {
                path.moveTo(projcx);
                path.drawTo(projca);
            }
        } else if (del.ca < 0) {
            double[] dirv = VMath.minus(means.get(del.c), means.get(del.a));
            VMath.rotate90Equals(dirv);
            double[] dir = proj.fastProjectRelativeDataToRenderSpace(dirv);
            final double factor = viewport.continueToMargin(projcx, dir);
            if (factor > 0) {
                path.moveTo(projcx);
                path.relativeLineTo(factor * dir[0], factor * dir[1]);
            }
        }
    }
    return path;
}
Also used : CanvasSize(de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize) Triangle(de.lmu.ifi.dbs.elki.math.geometry.SweepHullDelaunay2D.Triangle) Triangle(de.lmu.ifi.dbs.elki.math.geometry.SweepHullDelaunay2D.Triangle) SweepHullDelaunay2D(de.lmu.ifi.dbs.elki.math.geometry.SweepHullDelaunay2D)

Example 2 with CanvasSize

use of de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize in project elki by elki-project.

the class DistanceFunctionVisualization method drawCosine.

/**
 * Visualizes Cosine and ArcCosine distance functions
 *
 * @param svgp SVG Plot
 * @param proj Visualization projection
 * @param mid mean vector
 * @param angle Opening angle in radians
 * @return path element
 */
public static Element drawCosine(SVGPlot svgp, Projection2D proj, NumberVector mid, double angle) {
    // Project origin
    double[] pointOfOrigin = proj.fastProjectDataToRenderSpace(new double[proj.getInputDimensionality()]);
    // direction of the selected Point
    double[] selPoint = proj.fastProjectDataToRenderSpace(mid);
    double[] range1, range2;
    {
        // Rotation plane:
        double[] p1 = proj.fastProjectRenderToDataSpace(selPoint[0] + 10, selPoint[1]);
        double[] p2 = proj.fastProjectRenderToDataSpace(selPoint[0], selPoint[1] + 10);
        double[] pm = mid.toArray();
        // Compute relative vectors
        minusEquals(p1, pm);
        minusEquals(p2, pm);
        // Scale p1 and p2 to unit length:
        timesEquals(p1, 1. / euclideanLength(p1));
        timesEquals(p2, 1. / euclideanLength(p2));
        {
            double test = scalarProduct(p1, p2);
            if (Math.abs(test) > 1E-10) {
                LoggingUtil.warning("Projection does not seem to be orthogonal?");
            }
        }
        // Project onto p1, p2:
        double l1 = scalarProduct(pm, p1), l2 = scalarProduct(pm, p2);
        // Rotate projection by + and - angle
        // Using sin(-x) = -sin(x) and cos(-x)=cos(x)
        // To return cosine
        final DoubleWrapper tmp = new DoubleWrapper();
        final double sangle = FastMath.sinAndCos(angle, tmp), cangle = tmp.value;
        double r11 = +cangle * l1 - sangle * l2, r12 = +sangle * l1 + cangle * l2;
        double r21 = +cangle * l1 + sangle * l2, r22 = -sangle * l1 + cangle * l2;
        // Build rotated vectors - remove projected component, add rotated
        // component:
        double[] r1 = copy(pm), r2 = copy(pm);
        plusTimesEquals(r1, p1, -l1 + r11);
        plusTimesEquals(r1, p2, -l2 + r12);
        plusTimesEquals(r2, p1, -l1 + r21);
        plusTimesEquals(r2, p2, -l2 + r22);
        // Project to render space:
        range1 = proj.fastProjectDataToRenderSpace(r1);
        range2 = proj.fastProjectDataToRenderSpace(r2);
    }
    // Continue lines to viewport.
    {
        CanvasSize viewport = proj.estimateViewport();
        minusEquals(range1, pointOfOrigin);
        minusEquals(range2, pointOfOrigin);
        timesEquals(range1, viewport.continueToMargin(pointOfOrigin, range1));
        timesEquals(range2, viewport.continueToMargin(pointOfOrigin, range2));
        plusEquals(range1, pointOfOrigin);
        plusEquals(range2, pointOfOrigin);
        // Go backwards into the other direction - the origin might not be in the
        // viewport!
        double[] start1 = minus(pointOfOrigin, range1);
        double[] start2 = minus(pointOfOrigin, range2);
        timesEquals(start1, viewport.continueToMargin(range1, start1));
        timesEquals(start2, viewport.continueToMargin(range2, start2));
        plusEquals(start1, range1);
        plusEquals(start2, range2);
        // TODO: add filled variant?
        SVGPath path = new SVGPath();
        path.moveTo(start1);
        path.lineTo(range1);
        path.moveTo(start2);
        path.lineTo(range2);
        return path.makeElement(svgp);
    }
}
Also used : CanvasSize(de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize) DoubleWrapper(net.jafama.DoubleWrapper) SVGPath(de.lmu.ifi.dbs.elki.visualization.svg.SVGPath)

Example 3 with CanvasSize

use of de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize in project elki by elki-project.

the class AbstractScatterplotVisualization method setupCanvas.

/**
 * Utility function to setup a canvas element for the visualization.
 *
 * @param svgp Plot element
 * @param proj Projection to use
 * @param margin Margin to use
 * @param width Width
 * @param height Height
 * @return wrapper element with appropriate view box.
 */
public static Element setupCanvas(SVGPlot svgp, Projection2D proj, double margin, double width, double height) {
    final CanvasSize canvas = proj.estimateViewport();
    final double sizex = canvas.getDiffX();
    final double sizey = canvas.getDiffY();
    String transform = SVGUtil.makeMarginTransform(width, height, sizex, sizey, margin) + " translate(" + SVGUtil.fmt(sizex * .5) + " " + SVGUtil.fmt(sizey * .5) + ")";
    final Element layer = SVGUtil.svgElement(svgp.getDocument(), SVGConstants.SVG_G_TAG);
    SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform);
    return layer;
}
Also used : CanvasSize(de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize) Element(org.w3c.dom.Element)

Example 4 with CanvasSize

use of de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize in project elki by elki-project.

the class VoronoiDraw method drawFakeVoronoi.

/**
 * Fake Voronoi diagram. For two means only
 *
 * @param proj Projection
 * @param means Mean vectors
 * @return SVG path
 */
public static SVGPath drawFakeVoronoi(Projection2D proj, List<double[]> means) {
    CanvasSize viewport = proj.estimateViewport();
    final SVGPath path = new SVGPath();
    // Difference
    final double[] dirv = VMath.minus(means.get(1), means.get(0));
    VMath.rotate90Equals(dirv);
    double[] dir = proj.fastProjectRelativeDataToRenderSpace(dirv);
    // Mean
    final double[] mean = VMath.plus(means.get(0), means.get(1));
    VMath.timesEquals(mean, 0.5);
    double[] projmean = proj.fastProjectDataToRenderSpace(mean);
    double factor = viewport.continueToMargin(projmean, dir);
    path.moveTo(projmean[0] + factor * dir[0], projmean[1] + factor * dir[1]);
    // Inverse direction:
    dir[0] *= -1;
    dir[1] *= -1;
    factor = viewport.continueToMargin(projmean, dir);
    path.drawTo(projmean[0] + factor * dir[0], projmean[1] + factor * dir[1]);
    return path;
}
Also used : CanvasSize(de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize)

Aggregations

CanvasSize (de.lmu.ifi.dbs.elki.visualization.projections.CanvasSize)4 SweepHullDelaunay2D (de.lmu.ifi.dbs.elki.math.geometry.SweepHullDelaunay2D)1 Triangle (de.lmu.ifi.dbs.elki.math.geometry.SweepHullDelaunay2D.Triangle)1 SVGPath (de.lmu.ifi.dbs.elki.visualization.svg.SVGPath)1 DoubleWrapper (net.jafama.DoubleWrapper)1 Element (org.w3c.dom.Element)1