Posts Tagged ‘graphics’

Link: IKEA’s use of 3D rendering in its catalogs

September 2, 2014 Leave a comment

This blew my mind – almost all of the imagery in IKEA catalogs is computer generated.

The main rationale for switching from traditional photography to 3D rendering:

The IKEA team didn’t feel there was anything wrong with traditional photography, quality-wise. Like any company, they just wanted to make things easier for the team to work on – to make the process simpler, cheaper and faster. With traditional photography, you need to have prototype furniture being built in different parts of the world shipped over so it can be photographed. Everything needs to be there on time and it can be logistically difficult, expensive and not that environmental. Then if there are changes everything needs to be re-shot. With CG re-creations of pieces, it removes a lot of this difficulty. However to start with, Martin says, “There was no vision initially to create entire rooms in CG, like we do now. We just wanted to create the individual pieces – the ones you see on white backgrounds on the web.”

There are some great images in the article showing how the same kitchen is rendered for different countries. You’ll notice that the faucet switches sides, the oven handle changes, and in one of the renders the refrigerator is removed completely.

The article also describes the technology stack that they use to render all of the images.
Thanks to Hacker News for the link.

Categories: link Tags: , , ,

Simplifying Isosurfaces (Part 2)

August 26, 2012 Leave a comment

Very interesting article on techniques for simplifying 3d surfaces, including an interactive WebGL demo comparing the various techniques. Simplifying 3d surfaces is important for maintaining frame rate in interactive applications when objects are far away; it is a way of managing level of detail in an automated fashion.


To briefly recap, our goal is to render large volumetric environments.  For the sake of both efficiency and image quality, we want to introduce some form of level of detail simplification for distant geometry.  Last time, we discussed two general approaches to level of detail — surface and volumetric — focusing primarily on the former.  Though volumetric terrain is not exactly the same as height-map based terrain, we can draw an imperfect analogy between these two problems and the two most popular techniques for 2D terrain rendering: ROAM and geometry clipmaps.

ROAM vs. Clip Maps

ROAM, or Realtime Optimally Adapting Meshes, is in many ways the height-field equivalent of surface based simplification.  In fact, ROAM is secretly just the simplification envelopes algorithm applied to large regular grids!  For any viewing configuration and triangle budget, ROAM computes an optimally simplified mesh in this sense.  This…

View original post 3,675 more words

Quick hit – antialiasing in Java Graphics2D

February 9, 2010 7 comments

If you’re trying to use antialiasing in Java, chances are you’ll do some searching and come to the conclusion that you have to set the rendering hints for the Graphics object in order to eliminate your jaggies. Probably like so:

Graphics2D g2 = (Graphics2D) g;

And you’ll probably wonder why your graphics are still jagged. That’s because you haven’t instructed Java what type of interpolation to use for the antialiasing; by default you’ll get Nearest Neighbor, which is fast but won’t get you far in the image department. You can instead choose to use bilinear interpolation (slower) or bicubic interpolation (slowest).

Here’s how to enable the alternate interpolation modes:

Graphics2D g2 = (Graphics2D) g;



You make a trade off between speed and image quality; to my eyes bilinear looks fine. Compare for yourself:

Thanks to Chris Cambpell’s blog for showing me this.

How to make a solar system: Introduction to affine transformations and Java 2D

February 2, 2010 5 comments

At the heart of all computer graphics lies linear algebra, and specifically matrix multiplication. One can use matrices to perform all sorts of operations, such as transformations to move from one coordinate system to another, as well as a set known as affine transformations. Affine transformations are those that map lines to lines in the transformed coordinate space, and which preserve the relative distance between points. An affine transformation consists of one or more translation, rotation, scaling, and shearing transformations.

See the following external sites for translation and rotation examples, shearing, scaling.

Java has a class to represent these affine transformations, as well as shorthand methods to apply them to a Graphics2D context.

Rotate about origin
Rotate about a point
Scale x and y axis by given amount

If you do any work involving Graphics2D in Java (and if you work with Swing components, you implicitly do), knowing how to use affine transforms is extremely beneficial. With them you can express and code things more succintly, and clearly than is possible without them.

We’ll start with a simple example, once with standard Swing painting code, and once using affine transformations. Finally we will end with a more fully fleshed out example that really illustrates the power of affine transformations, rendering a simplified overhead view of the solar system. This example would be extremely difficult to replicate without affine transformations.

For the simple example, let’s draw dots in a circle pattern. The easiest way to start drawing to the screen is simply to subclass the JComponent class and override the paintComponent(Graphics g) method. Here we go:

     * Draw a series of dots in a circular pattern
     * @param g
    public void paintComponent(Graphics g) {
        // Don't forget to call the super method

        int radius = getWidth() / 2;

        for (int i = 0; i < NUM_DOTS; i++) {
            double theta = 2 * Math.PI * ((double) i / NUM_DOTS);
            int x = (int) (radius * Math.cos(theta));
            int y = (int) (radius * Math.sin(theta));

            // these x and y are relative to center of circle; currently origin
            // is at upper left corner of window.  Add to x and y to
            // translate.
            x += getWidth() / 2;
            y += getHeight() / 2;

            g.drawOval(x, y, 1, 1);


Here’s a picture of the result.

(Full source)

Now, here’s that same code using the implicit affine transformation of the rotate() method of Graphics2D.

     * Draw a series of dots in a circular pattern
     * @param g
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        // Don't forget to call the super method

        int radius = getWidth()/2;

        // Translate the origin to the center of window
        g2.translate(getWidth() /2, getHeight() /2);
        for (int i = 0; i < NUM_DOTS; i++) {
            // We have rotated about the origin; draw a ray out along x axis
            // of new coordinate system
            g2.drawOval(radius, 0, 1, 1);


(Full Source)

As you can see from the screenshots, they come out functionally the same. In this case there’s not a huge advantage to using the rotation over the standard method. But what if we weren’t drawing dots along the radius of the circle, but instead were drawing rectangles that laid tangent to the circle? Here’s how simple that is to do using the rotations..

// Define the number of pixels wide each box is
private static final int BOX_SIZE = 5;

// Replace the call to drawOval with fillRect
g2.fillRect(radius, 0, BOX_SIZE, BOX_SIZE);

Here is the result

(Full source)

Think how complicated this would be to accomplish if you were not using affine transforms; you would need to manually calculate the coordinates of each corner of each box, create a polygon from those points, and then call fillShape on the polygon.

The other place where affine transformations shine is when you need to place objects relative to each other. For instance, you might draw a table with a bowl of fruit on it; if your table moves, you would like the bowl to move as well. I will show you how you can render a simplified version of the solar system where the earth revolves around the sun, while at the same time the moon orbits the earth. As you can imagine, implementing this without affine transformations would be absolutely infeasible.

First we separate our model from our view as per the model view controller pattern; the state of the solar system is kept in the model which the view uses to render itself. Since the state of the model will be observed by the view, we make it a subclass of the Java Observable class.

package solarsystem;

import java.util.Observable;

public class SolarSystemModel extends Observable {

    public static final int DAYS_PER_EARTH_REVOLUTION_AROUND_SUN = 365;
    public static final int HOURS_PER_EARTH_REVOLUTION_AROUND_AXIS = 24;

    // <a href=""></a>
    // "The orbit of the Moon around the Earth is completed in approximately 27.3 days"
    public static final float DAYS_PER_MOON_ORBIT_AROUND_EARTH = 27.3f;

    private int day;
    private int hour;

    public int getDay() {
        return day;

    public void setDay(int day) {
        int oldDay =; = clampDay(day);
        if (oldDay != {

    public int getHour() {
        return hour;

    public void setHour(int hour) {
        int oldHour = this.hour;
        this.hour = clampHour(hour);
        if (oldHour != this.hour) {

    private int clampDay(int day) {

    private int clampHour(int hour) {


(Note that we need to call setChanged() before notifyObservers() or our Observers registered with the model will not be updated.)

Now that we have our model defined, we need to make a view to actually render the solar system. Just as in our previous examples, I make the view extend JComponent for ease of display in a JFrame.

public class SolarSystemView extends JComponent implements Observer

The Observer interface allows classes to be notified when an Observable object changes; since we want to keep our view in sync with the model, this is just what we will do.

Here is the meat of the class:

        public void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;


            // Set the origin to be in the center of the screen
            g2.translate(getWidth()/2, getHeight()/2);

            // Order matters, since the earth placement is dependent upon the sun
            // placement, and the moon placement is dependent upon the earth placement



The graphics context is passed into each drawing method, which may or may not modify the context. The drawSpaceBackdrop method merely draws a few random stars on a black background; see the following screenshot:

The code for that is fairly straightforward:

         * Draws a black backdrop with star field
         * @param g2
        private void drawSpaceBackdrop(Graphics2D g2) {
            // Draw background as black
            g2.fillRect(0, 0, getWidth(), getHeight());

            for (int i = 0; i &lt; NUM_STARS; i++) {
                g2.fillOval(starX[i], starY[i], starRadius[i], starRadius[i]);


starX, starY, starRadius are parallel int arrays that are initialized earlier in the program by a random int generator.

     * Creates and populates our arrays of star x values, star y values, and
     * star radii
     * @param width     what is max x value we should consider for star
     * @param height    what is max y value we should consider for star
    private void createStarField(int width, int height, int maxRadius) {
        // Create the arrays
        starX = new int[NUM_STARS];
        starY = new int[NUM_STARS];
        starRadius = new int[NUM_STARS];
        // Fill them in with random values
        for (int i = 0; i &lt; NUM_STARS; i++) {
            starX[i] = random.nextInt(width);
            starY[i] = random.nextInt(height);
            starRadius[i] = random.nextInt(maxRadius);

After initializing the arrays and drawing the stars, we then draw the sun. Note that we translate the origin from the upper left corner to the center of the screen; this allows each of the drawing methods to consider its own local coordinate system and not have to remember to translate from upper left corner of screen. For instance, the center of the sun is at (0,0) in its coordinate system.

         * @param g2 graphics context with (0,0) in center of screen (where sun will
         * be centered)
        private void drawSun(Graphics2D g2) {
            int sunRadius = (int) (SUN_RADIUS_PROPORTION * getWidth());
            GradientPaint sunColor = new GradientPaint(0, 0, Color.YELLOW, 0, sunRadius, Color.RED);
            g2.fillOval(-sunRadius/2, -sunRadius/2, sunRadius, sunRadius);

We apply a gradient just to make it look slightly nicer than a monochrome sun.

After having drawn the sun, it’s time to draw the earth.

         * Draws the earth to the screen, whose position is dependent upon the
         * day of the year
         * @param g2 the graphics context with its origin in the center of the sun
        private void drawEarth(Graphics2D g2) {
            // Draw the earth
            // Calculate what portion along its orbit the earth is, and thus how
            // far to rotate about our centerpoint
            double earthTheta = map(model.getDay(), 0, SolarSystemModel.DAYS_PER_EARTH_REVOLUTION_AROUND_SUN, 0, TWO_PI);

            // Rotate our coordinate system by that much
            // Translate the earth
            int distanceFromEarthToSun = (int) (EARTH_DISTANCE_PROPORTION_SCREEN * getWidth());
            g2.translate(distanceFromEarthToSun, 0);

            int earthRadius = (int) (EARTH_RADIUS_PROPORTION * getWidth());
            GradientPaint earthColor = new GradientPaint(0, 0, Color.BLUE, 0, earthRadius, Color.GREEN.darker(), true);

            g2.fillOval(-earthRadius/2, -earthRadius/2, earthRadius, earthRadius);

If you’ve read my earlier blog post on the map function, you know that it maps a value from one range of numbers to another. We must calculate the number of radians to rotate so that we can position our earth correctly along its orbit.

Note that we first rotate and then translate; if we did it in the opposite direction we would see the earth spin about its axis but it would not revolve around the earth.

The drawMoon method is much the same; the main difference is that we calculate its position along its orbit based on its much smaller time to orbit the earth.

         * Draw the moon to the screen, whose position is dependent upon that of
         * the earth and the day of the year, which dictates its position along
         * its orbit around earth
         * @param g2 the graphics context with its origin in the center of the earth
        private void drawMoon(Graphics2D g2) {
            double moonTheta = map(model.getDay(), 0, SolarSystemModel.DAYS_PER_MOON_ORBIT_AROUND_EARTH, 0, TWO_PI);

            int moonRadius = (int) (MOON_RADIUS_PROPORTION * getWidth());
            int distanceFromEarthToMoon = (int) (MOON_DISTANCE_PROPORTION_SCREEN * getWidth());
            // Translate the earth
            g2.translate(distanceFromEarthToMoon, 0);
            g2.fillOval(-moonRadius/2, -moonRadius/2, moonRadius, moonRadius);

Finally all we have to do is create an instance of the model and view, hook them together, and display them in a JFrame.

        public static void main(String[] args) {
            JFrame frame = new JFrame("Solar System");

            final SolarSystemModel model = new SolarSystemModel();
            final SolarSystemView view = new SolarSystemView(model);

            JPanel panel = new JPanel();


If we run it as is, we see the planets aligned, since the model starts off at day zero. It’s a lot more fun to be able to interact with the model. To do that, we add a JSlider that modifies the model.

            final JSlider daySlider = new JSlider(0,SolarSystemModel.DAYS_PER_EARTH_REVOLUTION_AROUND_SUN);
            daySlider.addChangeListener(new ChangeListener() {
                public void stateChanged(ChangeEvent e) {

With that addition, we can move the slider and watch the planets move.

That’s it for this time. Can you figure out how to use the hour field of the model with another slider to make the earth rotate about its axis as it revolves around the sun?

Full model source
Full view source

Categories: Java, programming, regular Tags: , , ,