org.caleydo.view.bicluster.util.TesselatedBiClusterPolygons.java Source code

Java tutorial

Introduction

Here is the source code for org.caleydo.view.bicluster.util.TesselatedBiClusterPolygons.java

Source

/*******************************************************************************
 * Caleydo - Visualization for Molecular Biology - http://caleydo.org
 * Copyright (c) The Caleydo Team. All rights reserved.
 * Licensed under the new BSD license, available at http://caleydo.org/license
 ******************************************************************************/
package org.caleydo.view.bicluster.util;

import gleem.linalg.Vec2f;
import gleem.linalg.Vec3f;

import java.util.Arrays;
import java.util.List;

import org.caleydo.core.view.opengl.layout2.GLElement;
import org.caleydo.core.view.opengl.layout2.GLGraphics;
import org.caleydo.core.view.opengl.layout2.GLSandBox;
import org.caleydo.core.view.opengl.layout2.renderer.IGLRenderer;
import org.caleydo.core.view.opengl.util.spline.Band;
import org.caleydo.core.view.opengl.util.vislink.Splines;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

/**
 * @author Samuel Gratzl
 *
 */
public final class TesselatedBiClusterPolygons {
    public final static int NUMBER_OF_SPLINE_POINTS = 30;

    public static Band band(List<Vec2f> anchorPoints, final float z, float radiusFirst, float radiusSecond,
            int numberOfSplinePoints) {
        Preconditions.checkArgument(anchorPoints.size() >= 2, "at least two points");

        List<Vec3f> curve = Splines.spline3(Lists.transform(anchorPoints, new Function<Vec2f, Vec3f>() {
            @Override
            public Vec3f apply(Vec2f in) {
                return new Vec3f(in.x(), in.y(), z);
            }
        }), numberOfSplinePoints);

        return toBand(curve, radiusFirst, radiusSecond);
    }

    private static Band toBand(List<Vec3f> curve, float radiusSecond, float radiusFirst) {
        final int last = curve.size() - 1;
        Vec3f[] c = curve.toArray(new Vec3f[0]);
        Vec3f[] normals = new Vec3f[curve.size()];

        normals[0] = normal(c[0], c[1]);
        for (int i = 1; i < last; ++i) {
            normals[i] = normal(c[i - 1], c[i]).plus(normal(c[i], c[i + 1]));
            normals[i].scale(0.5f);
            normals[i].normalize();
        }
        normals[last] = normal(c[last - 1], c[last]);

        Vec3f[] top = new Vec3f[curve.size()];
        Vec3f[] bottom = new Vec3f[curve.size()];
        float radius = radiusFirst;
        float diff = radiusFirst - radiusSecond;
        for (int i = 0; i <= last; ++i) {
            radius = radiusSecond + diff * i / last;
            top[i] = c[i].addScaled(radius, normals[i]);
            bottom[i] = c[i].addScaled(-radius, normals[i]);
        }

        return new Band(Arrays.asList(top), Arrays.asList(bottom));
    }

    private static Vec3f normal(Vec3f a, Vec3f b) {
        Vec3f d = b.minus(a);
        d.normalize();
        d.set(-d.y(), d.x(), d.z());
        return d;
    }

    public static void main(String[] args) {

        GLSandBox.main(args, new IGLRenderer() {
            @Override
            public void render(GLGraphics g, float w, float h, GLElement parent) {
                renderBandTwo(g, new Vec2f(0, 0), new Vec2f(2, -2), new Vec2f(4, -3), new Vec2f(6, -7));
                renderBandOne(g, new Vec2f(10, 0), new Vec2f(12, -2), new Vec2f(14, -4), new Vec2f(16, -6));

            }

            private void renderBandTwo(GLGraphics g, Vec2f... vecs) {
                final Band band = band(Arrays.asList(vecs), 0, 3, 4, 40);
                g.move(100, 100);
                g.save().gl.glScalef(10, 10, 10);
                g.color(1, 0, 0, 0.5f);
                g.fillPolygon(band);
                g.color(0, 1, 0, 0.5f);
                g.drawPath(band);
                g.restore();
            }

            private void renderBandOne(GLGraphics g, Vec2f... vecs) {
                final Band band = band(Arrays.asList(vecs), 0, 3, 6, 40);
                g.move(100, 100);
                g.save().gl.glScalef(10, 10, 10);
                g.color(1, 0, 0, 0.5f);
                g.fillPolygon(band);
                g.color(0, 1, 0, 0.5f);
                g.drawPath(band);
                g.restore();
            }

        });

    }
}