0

I am learning about 2d images. We were given a template to use and told do various things. Everything seems to be working fine, except the image is already being drawn rotated. I do not understand why. This is the image.

     public static int[][] letterN = {
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 1, 1, 1, 1, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0},
    {0, 1, 1, 0, 0, 0, 0, 1, 1, 0}};

This is the code from the program: I dont understand why the image is popping up rotated. All of the other letters are being rotated as well.

   package cmsc325animate;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;


public class CMSC325Animate extends JPanel {

// A counter that increases by one in each frame.
private int frameNumber;
// The time, in milliseconds, since the animation started.
private long elapsedTimeMillis;
// This is the measure of a pixel in the coordinate system
// set up by calling the applyLimits method.  It can be used
// for setting line widths, for example.
private float pixelSize;

static int translateX = 0;
static int translateY = 0;
static double rotation = 0.0;
static double scaleX = 1.0;
static double scaleY = 1.0;
ImageTemplate myImages = new ImageTemplate();
BufferedImage tImage = myImages.getImage(ImageTemplate.letterT);
BufferedImage nImage = myImages.getImageN(ImageTemplate.letterN);
BufferedImage oImage = myImages.getImageO(ImageTemplate.letterO);
BufferedImage aImage = myImages.getImageA(ImageTemplate.letterA);
BufferedImage hImage = myImages.getImageH(ImageTemplate.letterH);
BufferedImage heartImage = myImages.getImageHeart(ImageTemplate.heart);

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here
    JFrame window;
    window = new JFrame("Java Animation");  // The parameter shows in the window title bar.
    final CMSC325Animate panel = new CMSC325Animate(); // The drawing area.
    window.setContentPane(panel); // Show the panel in the window.
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // End program when window closes.
    window.pack();  // Set window size based on the preferred sizes of its contents.
    window.setResizable(false); // Don't let user resize window.
    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    window.setLocation( // Center window on screen.
            (screen.width - window.getWidth()) / 2,
            (screen.height - window.getHeight()) / 2);
    Timer animationTimer;  // A Timer that will emit events to drive the animation.
    final long startTime = System.currentTimeMillis();
    // Taken from AnimationStarter
    // Modified to change timing and allow for recycling
    animationTimer = new Timer(1600, new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            if (panel.frameNumber > 4) {
                panel.frameNumber = 0;
            } else {
                panel.frameNumber++;
            }
            panel.elapsedTimeMillis = System.currentTimeMillis() - startTime;
            panel.repaint();
        }
    });
    window.setVisible(true); // Open the window, making it visible on the screen.
    animationTimer.start();  // Start the animation running.

}

public CMSC325Animate() {
    // Size of Frame
    setPreferredSize(new Dimension(800, 600));
}

// This is where all of the action takes place
// Code taken from AnimationStarter.java but modified to add the specific Images
// Also added looping structure for Different transformations
protected void paintComponent(Graphics g) {

    /* First, create a Graphics2D drawing context for drawing on the panel.
     * (g.create() makes a copy of g, which will draw to the same place as g,
     * but changes to the returned copy will not affect the original.)
     */
    Graphics2D g2 = (Graphics2D) g.create();

    /* Turn on antialiasing in this graphics context, for better drawing.
     */
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    /* Fill in the entire drawing area with white.
     */
    g2.setPaint(Color.WHITE);
    g2.fillRect(0, 0, getWidth(), getHeight()); // From the old graphics API!

    /* Here, I set up a new coordinate system on the drawing area, by calling
     * the applyLimits() method that is defined below.  Without this call, I
     * would be using regular pixel coordinates.  This function sets the value
     * of the global variable pixelSize, which I need for stroke widths in the
     * transformed coordinate system.
     */
    // Controls your zoom and area you are looking at
    applyWindowToViewportTransformation(g2, -75, 75, -75, 75, true);

    AffineTransform savedTransform = g2.getTransform();

    System.out.println("Frame is " + frameNumber);
    switch (frameNumber) {
        case 1: // First frame is unmodified.
            translateX = 0;
            translateY = 0;
            scaleX = 1.0;
            scaleY = 1.0;
            rotation = 0;
            break;
        case 2: // Second frame translates each image by (-10, 12).
            translateX = -10;
            translateY = 12;
            break;
        case 3: // Third frame rotates each image by 55 degrees Counter
            translateX = -10;
            translateY = 12;
            rotation = 55 * Math.PI / 180.0;
            break;
        // Can add more cases as needed
        case 4: // 4th frame rotates each image by 75 degress Clockwise
            translateX = -10;
            translateY = 12;
            rotation = 55 * Math.PI / 180.0;
            rotation = 75 * Math.PI * 180;
            break;

        case 5: // Scales image 3.5 for x and 1.5 for y
            translateX = -10;
            translateY = 12;
            rotation = 55 * Math.PI / 180.0;
            rotation = 75 * Math.PI * 180;
            scaleX = scaleX * 3.5;
            scaleY = scaleY * 1.5;
            break;
        default:
            break;
    } // End switch

    g2.translate(translateX, translateY); // Move image.
    // To offset translate again
    g2.translate(-10,10);
    g2.rotate(rotation); // Rotate image.
    g2.scale(scaleX, scaleY); // Scale image.
    g2.drawImage(tImage, 100, 0, this); // Draw image.
    g2.setTransform(savedTransform);

    // draw nImage
    g2.translate(translateX, translateY); // Move image.
    // To offset translate again
    // This allows you to place your images across your graphic
    g2.translate(-30, 30);
    g2.rotate(rotation); // Rotate image.
    g2.scale(scaleX, scaleY); // Scale image.
    g2.drawImage(nImage, 0, 0, this); // Draw image.
    g2.setTransform(savedTransform);

// You can add more shapes/images as needed
// draw o Image
    g2.translate(translateX, translateY); //move image
    g2.translate(-10, 10);
    g2.rotate(rotation);
    g2.scale(scaleX, scaleY);
    g2.drawImage(oImage, 0, 0, this);
    g2.setTransform(savedTransform);

    g2.translate(translateX, translateY); //move image
    g2.translate(10, -10);
    g2.rotate(rotation);
    g2.scale(scaleX, scaleY);
    g2.drawImage(aImage, 0, 0, this);
    g2.setTransform(savedTransform);

    g2.translate(translateX, translateY); //move image
    g2.translate(30, -30);
    g2.rotate(rotation);
    g2.scale(scaleX, scaleY);
    g2.drawImage(hImage, 0, 0, this);
    g2.setTransform(savedTransform);

    g2.translate(translateX, translateY); //move image
    g2.translate(50, -50);
    g2.rotate(rotation);
    g2.scale(scaleX, scaleY);
    g2.drawImage(heartImage, 0, 0, this);
    g2.setTransform(savedTransform);

}

// Method taken directly from AnimationStarter.java Code
private void applyWindowToViewportTransformation(Graphics2D g2,
        double left, double right, double bottom, double top,
        boolean preserveAspect) {
    int width = getWidth();   // The width of this drawing area, in pixels.
    int height = getHeight(); // The height of this drawing area, in pixels.
    if (preserveAspect) {
        // Adjust the limits to match the aspect ratio of the drawing area.
        double displayAspect = Math.abs((double) height / width);
        double requestedAspect = Math.abs((bottom - top) / (right - left));
        if (displayAspect > requestedAspect) {
            // Expand the viewport vertically.
            double excess = (bottom - top) * (displayAspect / requestedAspect - 1);
            bottom += excess / 2;
            top -= excess / 2;
        } else if (displayAspect < requestedAspect) {
            // Expand the viewport vertically.
            double excess = (right - left) * (requestedAspect / displayAspect - 1);
            right += excess / 2;
            left -= excess / 2;
        }
    }
    g2.scale(width / (right - left), height / (bottom - top));
    g2.translate(-left, -top);
    double pixelWidth = Math.abs((right - left) / width);
    double pixelHeight = Math.abs((bottom - top) / height);
    pixelSize = (float) Math.max(pixelWidth, pixelHeight);
}
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • I would start by trying to debug this by putting lots of breakpoints throughout the execution. You can sorta do a "binary search" for when the image gets rotated, assuming that you know what the images should look like. Especially in your switch statement, where the rotation variable is being changed. – PhaseRush Nov 18 '18 at 21:30
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). **For example** there are 6 images declared. Presumably this can be reduced to one (any image that is rotated prior to expectation). Remove the cruft that is irrelevant to the immediate problem! 2) One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). E.G. [This answer](https://stackoverflow.com/a/10862262/418556) hot links to an image embedded in [this question](https://stackoverflow.com/q/10861852/418556). – Andrew Thompson Nov 19 '18 at 01:58
  • Basically I'm trying to make the letter n, but when i run the code it is making a c. how would i go about rotating it to make it a 'n'? It is also happening to all of the characters I have made and they are rotated the same was as the n. Which makes no sense to me, because at the beginning rotation should be set to 0. – John Summers Nov 19 '18 at 02:15
  • *"Basically I'm trying.."* Tip: Add @PhaseRush (or whoever, the `@` is important) to *notify* the person of a new comment. – Andrew Thompson Nov 19 '18 at 03:31
  • @AndrewThompson thank you for all of the tips. Basically, I changed the 1s and 0s in each image so that when I compiled, it looked the way I wanted it to look. – John Summers Nov 19 '18 at 14:21

0 Answers0