Search in sources :

Example 1 with Node

use of de.lmu.ifi.dbs.elki.visualization.parallel3d.layout.Layout.Node in project elki by elki-project.

the class Parallel3DRenderer method renderLabels.

private void renderLabels(GL2 gl, IntIntPair[] edgesort) {
    shared.textrenderer.begin3DRendering();
    // UNDO the camera rotation. This will mess up text orientation!
    gl.glRotatef((float) MathUtil.rad2deg(shared.camera.getRotationZ()), 0.f, 0.f, 1.f);
    // Rotate to have the text face the camera direction, which looks +Y
    // While the text will be visible from +Z and +Y is baseline.
    gl.glRotatef(90.f, 1.f, 0.f, 0.f);
    // HalfPI: 180 degree extra rotation, for text orientation.
    double cos = FastMath.cos(shared.camera.getRotationZ()), sin = FastMath.sin(shared.camera.getRotationZ());
    shared.textrenderer.setColor(0.0f, 0.0f, 0.0f, 1.0f);
    float defaultscale = .01f / (float) FastMath.sqrt(shared.dim);
    // TODO: div depth?
    final float targetwidth = .2f;
    // Assume all text is at least this width
    final float minratio = 8.f;
    for (int i = 0; i < shared.dim; i++) {
        if (shared.labels[i] != null) {
            Rectangle2D b = shared.textrenderer.getBounds(shared.labels[i]);
            float scale = defaultscale;
            if (Math.max(b.getWidth(), b.getHeight() * minratio) * scale > targetwidth) {
                scale = targetwidth / (float) Math.max(b.getWidth(), b.getHeight() * minratio);
            }
            float w = (float) b.getWidth() * scale;
            // Rotate manually, in x-z plane
            float x = (float) (cos * shared.layout.getNode(i).getX() + sin * shared.layout.getNode(i).getY());
            float y = (float) (-sin * shared.layout.getNode(i).getX() + cos * shared.layout.getNode(i).getY());
            shared.textrenderer.draw3D(shared.labels[i], (x - w * .5f), 1.01f, -y, scale);
        }
    }
    // Show depth indexes on debug:
    if (OpenGL3DParallelCoordinates.Instance.DEBUG) {
        shared.textrenderer.setColor(1f, 0f, 0f, 1f);
        for (IntIntPair pair : edgesort) {
            Layout.Edge edge = shared.layout.edges.get(pair.second);
            final Node node1 = shared.layout.getNode(edge.dim1);
            final Node node2 = shared.layout.getNode(edge.dim2);
            final double mx = 0.5 * (node1.getX() + node2.getX());
            final double my = 0.5 * (node1.getY() + node2.getY());
            // Rotate manually, in x-z plane
            float x = (float) (cos * mx + sin * my);
            float y = (float) (-sin * mx + cos * my);
            shared.textrenderer.draw3D(Integer.toString(pair.first), (x - defaultscale * .5f), 1.01f, -y, .5f * defaultscale);
        }
    }
    shared.textrenderer.end3DRendering();
}
Also used : Layout(de.lmu.ifi.dbs.elki.visualization.parallel3d.layout.Layout) Node(de.lmu.ifi.dbs.elki.visualization.parallel3d.layout.Layout.Node) Rectangle2D(java.awt.geom.Rectangle2D) IntIntPair(de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair)

Example 2 with Node

use of de.lmu.ifi.dbs.elki.visualization.parallel3d.layout.Layout.Node in project elki by elki-project.

the class Parallel3DRenderer method drawParallelPlot.

protected void drawParallelPlot(GLAutoDrawable drawable, GL2 gl) {
    // Sort axes by sq. distance from camera, front-to-back:
    sortAxes();
    // Sort edges by the maximum (foreground) index.
    IntIntPair[] edgesort = sortEdges(dindex);
    if (textures != null) {
        gl.glShadeModel(GL2.GL_FLAT);
        // Render spider web:
        // outside glBegin!
        gl.glLineWidth(shared.settings.linewidth);
        gl.glBegin(GL.GL_LINES);
        gl.glColor4f(0f, 0f, 0f, 1f);
        for (Layout.Edge edge : shared.layout.edges) {
            Node n1 = shared.layout.getNode(edge.dim1), n2 = shared.layout.getNode(edge.dim2);
            gl.glVertex3d(n1.getX(), n1.getY(), 0f);
            gl.glVertex3d(n2.getX(), n2.getY(), 0f);
        }
        gl.glEnd();
        // Draw axes and 3DPC:
        for (int i = 0; i < shared.dim; i++) {
            final int d = axes[i].second;
            final Node node1 = shared.layout.getNode(d);
            // Draw edge textures
            for (IntIntPair pair : edgesort) {
                // Not yet available?
                if (pair.second >= completedTextures) {
                    continue;
                }
                // Other axis must have a smaller index.
                if (pair.first >= i) {
                    continue;
                }
                Layout.Edge edge = shared.layout.edges.get(pair.second);
                // Must involve the current axis.
                if (edge.dim1 != d && edge.dim2 != d) {
                    continue;
                }
                int od = axes[pair.first].second;
                gl.glEnable(GL.GL_TEXTURE_2D);
                gl.glColor4f(1f, 1f, 1f, 1f);
                final Node node2 = shared.layout.getNode(od);
                gl.glBindTexture(GL.GL_TEXTURE_2D, textures[pair.second]);
                gl.glBegin(GL2.GL_QUADS);
                gl.glTexCoord2d((edge.dim1 == d) ? 0f : 1f, 0f);
                gl.glVertex3d(node1.getX(), node1.getY(), 0f);
                gl.glTexCoord2d((edge.dim1 == d) ? 0f : 1f, 1f);
                gl.glVertex3d(node1.getX(), node1.getY(), 1f);
                gl.glTexCoord2d((edge.dim1 != d) ? 0f : 1f, 1f);
                gl.glVertex3d(node2.getX(), node2.getY(), 1f);
                gl.glTexCoord2d((edge.dim1 != d) ? 0f : 1f, 0f);
                gl.glVertex3d(node2.getX(), node2.getY(), 0f);
                gl.glEnd();
                gl.glDisable(GL.GL_TEXTURE_2D);
            }
            // Draw axis
            // outside glBegin!
            gl.glLineWidth(shared.settings.linewidth);
            gl.glBegin(GL.GL_LINES);
            gl.glColor4f(0f, 0f, 0f, 1f);
            gl.glVertex3d(node1.getX(), node1.getY(), 0f);
            gl.glVertex3d(node1.getX(), node1.getY(), 1f);
            gl.glEnd();
            // Draw ticks.
            LinearScale scale = shared.proj.getAxisScale(d);
            gl.glPointSize(shared.settings.linewidth * 2f);
            gl.glBegin(GL.GL_POINTS);
            for (double tick = scale.getMin(); tick <= scale.getMax() + scale.getRes() / 10; tick += scale.getRes()) {
                gl.glVertex3d(node1.getX(), node1.getY(), scale.getScaled(tick));
            }
            gl.glEnd();
        }
    }
    // Render labels
    renderLabels(gl, edgesort);
}
Also used : LinearScale(de.lmu.ifi.dbs.elki.math.scales.LinearScale) Layout(de.lmu.ifi.dbs.elki.visualization.parallel3d.layout.Layout) Node(de.lmu.ifi.dbs.elki.visualization.parallel3d.layout.Layout.Node) IntIntPair(de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair)

Aggregations

IntIntPair (de.lmu.ifi.dbs.elki.utilities.pairs.IntIntPair)2 Layout (de.lmu.ifi.dbs.elki.visualization.parallel3d.layout.Layout)2 Node (de.lmu.ifi.dbs.elki.visualization.parallel3d.layout.Layout.Node)2 LinearScale (de.lmu.ifi.dbs.elki.math.scales.LinearScale)1 Rectangle2D (java.awt.geom.Rectangle2D)1