如何在不使用递归的情况下使正方形相互之间而不是彼此之上生成? [英] How do I make my squares generate behind each other rather than on top of eachother without using recursion?

查看:144
本文介绍了如何在不使用递归的情况下使正方形相互之间而不是彼此之上生成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的另一个问题中,我得到了一些帮助,以使我走到这一步,但是我想知道如何使我的方块彼此靠后而不是彼此靠前.下面的代码是到目前为止我得到的.

I've gotten some help in another one of my questions to get me this far but I'd like to know how to make my squares generate behind one another rather than on top of each other. The below code is what I've got so far.

这是将它们递归放置的代码:

This is the code that places them behind each other recursively:

import java.awt.image.*;
import java.awt.Color;
import java.io.*;
import javax.imageio.*;
import java.util.*;
public class FractalDriver {
    static final int SIDE = 1000; // image is SIDE X SIDE
    static BufferedImage image = new BufferedImage(SIDE, SIDE, BufferedImage.TYPE_INT_RGB);
    static final int WHITE = Color.WHITE.getRGB();
    static final int BLACK = Color.BLACK.getRGB();
    static Scanner kbd = new Scanner(System.in);

    public static void main(String[] args) throws IOException {
        String fileOut = "helloSquares.png";
        // make image black
        for (int i = 0; i < SIDE; i++) {
            for (int j = 0; j < SIDE; j++) {
                image.setRGB(i, j, BLACK);
            }
        }
        Square square = new Square(SIDE / 2, SIDE / 2, SIDE / 2, WHITE);
        drawSquare(square);

        // save image
        File outputfile = new File(fileOut);
        ImageIO.write(image, "jpg", outputfile);
    }

    public static void drawSquare(Square square) { // center of square is x,y length of side is s
        if (square.side <= 0) { // base case
            return;
        } else {
            // determine corners
            int left = square.center_x - (square.side / 2);
            int top = square.center_y - (square.side / 2);
            int right = square.center_x + (square.side / 2);
            int bottom = square.center_y + (square.side / 2);
            int newColor = square.color - 100000;
            Square newSquareA = new Square(left, top, square.side / 2, newColor);
            Square newSquareB = new Square(left, bottom, square.side / 2, newColor);
            Square newSquareC = new Square(right, top, square.side / 2, newColor);
            Square newSquareD = new Square(right, bottom, square.side / 2, newColor);

            // recursively paint squares at the corners
            drawSquare(newSquareA);
            drawSquare(newSquareB);
            drawSquare(newSquareC);
            drawSquare(newSquareD);
            //placing the for loop here starts at the end and moves toward     the beginning
            //it appears in the png that the squares are behind eachother
            for (int i = left; i < right; i++) {
                for (int j = top; j < bottom; j++) {
                    image.setRGB(i, j, square.color);
                }
            }
        }
    }
}

这是将它们打印在彼此之上的代码:

This is the code that prints them on top of eachother:

import java.awt.image.*;
import java.awt.Color;
import java.io.*;
import javax.imageio.*;
import java.util.*;

public class FractalDriver {
    static final int SIDE = 1000; // image is SIDE X SIDE
    static BufferedImage image = new BufferedImage(SIDE, SIDE, BufferedImage.TYPE_INT_RGB);
    static final int WHITE = Color.WHITE.getRGB();
    static final int BLACK = Color.BLACK.getRGB();
    static Scanner kbd = new Scanner(System.in);

    public static void main(String[] args) throws IOException {
        String fileOut = "helloSquares.png";
        // make image black
        for (int i = 0; i < SIDE; i++) {
            for (int j = 0; j < SIDE; j++) {
                image.setRGB(i, j, BLACK);
            }
        }
        Square square = new Square(SIDE / 2, SIDE / 2, SIDE / 2, WHITE);
        drawSquare(square);

        // save image
        File outputfile = new File(fileOut);
        ImageIO.write(image, "jpg", outputfile);
    }

    public static void drawSquare(Square square) { // center of square is x,y length of side is s
        if (square.side <= 0) { // base case
            return;
        } else {
            // determine corners
            int left = square.center_x - (square.side / 2);
            int top = square.center_y - (square.side / 2);
            int right = square.center_x + (square.side / 2);
            int bottom = square.center_y + (square.side / 2);
            int newColor = square.color - 100000;
            Square newSquareA = new Square(left, top, square.side / 2, newColor);
            Square newSquareB = new Square(left, bottom, square.side / 2, newColor);
            Square newSquareC = new Square(right, top, square.side / 2, newColor);
            Square newSquareD = new Square(right, bottom, square.side / 2, newColor);
            for (int i = left; i < right; i++) {
                for (int j = top; j < bottom; j++) {
                    image.setRGB(i, j, square.color);
                }
            }
            // recursively paint squares at the corners
            drawSquare(newSquareA);
            drawSquare(newSquareB);
            drawSquare(newSquareC);
            drawSquare(newSquareD);
            //placing the for loop here starts at the end and moves toward the beginning
            //it appears in the png that the squares are behind eachother

        }
    }
}

这里唯一的区别是for循环的位置(一个在递归调用之前,一个在递归调用之后)

The only difference here is the placement of the for loop (one before recursive calls, one after recursive calls)

这里是相同的程序,但没有递归:

Here is the same program but without the recursion:

import java.awt.image.*;
import java.awt.Color;
import java.io.*;
import javax.imageio.*;
import java.util.*;
public class TSquare {

    static final int SIDE = 1000; // image is SIDE X SIDE
    static final int WHITE = Color.WHITE.getRGB();
    static final int BLACK = Color.BLACK.getRGB();
    static Scanner kbd = new Scanner(System.in);

    public static void main(String[] args) throws IOException{
        BufferedImage image = new BufferedImage(SIDE, SIDE, BufferedImage.TYPE_INT_RGB);

        drawImage(SIDE, image);
        saveImage(image);
    }
    //#########################################################################
    protected static void drawImage(final int SIDE, BufferedImage image) {
        final int HALF = SIDE / 2;

        //Draw background
        new Square(HALF, HALF, SIDE, BLACK).draw(image);

        //Draw foreground starting with centered half sized square
        Square square = new Square(HALF, HALF, HALF, WHITE);
        drawSquare(square, image);
    }
    //#########################################################################
    protected static void drawSquare(Square square,BufferedImage image) {
        LinkedStack<Square> stack = new LinkedStack<>();
        stack.push(square);
        square.draw(image);
        while (!stack.isEmpty()) {
            square = stack.top();
            stack.pop();
            int half = square.half();
            if (half > 1) {

                int left = square.left();
                int top = square.top();
                int right = square.right();
                int bottom = square.bottom();
                int newColor = square.color - 100000;                

                stack.push(new Square(left, top, half, newColor,square));
                stack.push(new Square(left, bottom, half, newColor,square));
                stack.push(new Square(right, top, half, newColor,square));
                stack.push(new Square(right, bottom, half, newColor,square));
            }
                square.draw(image);  
        }
    }
    //#########################################################################
    public static void saveImage(BufferedImage image) throws IOException {
        String fileOut = "helloSquares.png";        
        File outputfile = new File(fileOut);
        ImageIO.write(image, "jpg", outputfile);
    }

}

广场课:

import java.awt.Color;
import java.awt.image.BufferedImage;
public class Square {
{
    final int BLACK = Color.BLACK.getRGB();
    final int WHITE = Color.WHITE.getRGB();
    protected int center_x;
    protected int center_y;
    protected int side;
    protected int color;
    protected Square parentSquare;

    public Square() {
        this.center_x = 0;
        this.center_y = 0;
        this.side = 0;
        this.color = WHITE;
        this.parentSquare = null;
    }

    public Square(int center_x, int center_y, int side, int color) {
        this.center_x = center_x;
        this.center_y = center_y;
        this.side = side;
        this.color = color;
        this.parentSquare = null;
    }

    public Square(int center_x, int center_y, int side, int color, Square parentSquare) {
        this.center_x = center_x;
        this.center_y = center_y;
        this.side = side;
        this.color = color;
        this.parentSquare = parentSquare;
    }

    public void setX(int center_x) {
        this.center_x = center_x;
    }

    public int getX() {
        return center_x;
    }

    public void setY(int center_y) {
        this.center_x = center_y;
    }

    public int getY() {
        return center_y;
    }

    public void setSide(int side) {
        this.side = side;
    }

    public int getSide() {
        return side;
    }

    public void setColor(int color) {
        this.color = color;
    }

    public int getColor() {
        return color;
    }

    public void setParent(Square parentSquare) {
        this.parentSquare = parentSquare;
    }

    public Square getParent() {
        return parentSquare;
    }

    public int half() {
        return side / 2;
    }

    public int left() {
        return center_x - half();
    }

    public int top() {
        return center_y - half();
    }

    public int right() {
        return center_x + half();
    }

    public int bottom() {
        return center_y + half();
    }

    public void draw(BufferedImage image) {

        int left = left();
        int top = top();
        int right = right();
        int bottom = bottom();

        for (int i = left; i < right; i++) {
            for (int j = top; j < bottom; j++) {
                image.setRGB(i, j, color);
            }
        }
    }

    public boolean contains(int x, int y) {
        int s = this.side;
        // If at least one of the dimensions is negative
        if (s < 0) {
            return false;
        }
        //if coordiante is top left and outside of square
        if (x < (this.center_x / 2) && (y < (this.center_y / 2))) {
            return false;
        }
        //if coordinate is bottom left and outside of square
        if ((x < (this.center_x / 2)) && (y > (this.center_y + (this.center_y / 2)))) {
            return false;
        } //checks up and down from x bounds
        else if (((x > (this.center_x / 2)) && (x < this.center_x + (this.center_x / 2)))
                && (y < (this.center_y / 2)) || y > this.center_y + (this.center_y / 2)) {
            return false;
        }
        //if coordiante is top right and outside of square
        if ((x > (this.center_x + (this.center_x / 2))) && (y < (this.center_y / 2))) {
            return false;
        }
        //if coordinate is bottom right and outside of square
        if ((x > (this.center_x + (this.center_x / 2))) && (y > (this.center_y + (this.center_y / 2)))) {
            return false;
        } //checks left and right from y bounds
        else if (((y > (this.center_y / 2)) && (y < this.center_y + (this.center_y / 2)))
                && (x < (this.center_x / 2)) || x > this.center_x + (this.center_x / 2)) {
            return false;
        }
        return true;
    }
}

链接的堆栈类:

public class LinkedStack<T> implements StackInterface<T>
{
  protected LLNode<T> top;   // reference to the top of this stack

  public LinkedStack()
  {
    top = null;
  }

  public void push(T element)
  // Places element at the top of this stack.
  { 
    LLNode<T> newNode = new LLNode<T>(element);
    newNode.setLink(top);
    top = newNode;
  }     

  public void pop()
  // Throws StackUnderflowException if this stack is empty,
  // otherwise removes top element from this stack.
  {                  
    if (isEmpty())
      throw new StackUnderflowException("Pop attempted on an empty stack.");
    else
      top = top.getLink();
  }

  public T top()
  // Throws StackUnderflowException if this stack is empty,
  // otherwise returns top element of this stack.
  {                 
    if (isEmpty())
      throw new StackUnderflowException("Top attempted on an empty stack.");
    else
      return top.getInfo();
  }

  public boolean isEmpty()
  // Returns true if this stack is empty, otherwise returns false.
  {              
    return (top == null); 
  }

  public boolean isFull()
  // Returns false - a linked stack is never full
  {              
      return false;
  }

}

堆栈溢出类别:

public class StackOverflowException extends RuntimeException
{
  public StackOverflowException()
  {
    super();
  }

  public StackOverflowException(String message)
  {
    super(message);
  }
}

堆栈下溢类:

public class StackUnderflowException extends RuntimeException
{
  public StackUnderflowException()
  {
    super();
  }

  public StackUnderflowException(String message)
  {
    super(message);
  }
}

堆栈界面:

public interface StackInterface<T>
{
  void push(T element) throws StackOverflowException;
  // Throws StackOverflowException if this stack is full,
  // otherwise places element at the top of this stack.

  void pop() throws StackUnderflowException;
  // Throws StackUnderflowException if this stack is empty,
  // otherwise removes top element from this stack.

  T top() throws StackUnderflowException;
  // Throws StackUnderflowException if this stack is empty,
  // otherwise returns top element of this stack.

  boolean isEmpty();
  // Returns true if this stack is empty, otherwise returns false.

  boolean isFull();
  // Returns true if this stack is full, otherwise returns false.
}

LLNODE类:

public class LLNode<T> {
{
    protected LLNode<T> link;
    protected T info;

    public LLNode(T info) {
        this.info = info;
        link = null;
    }

    public void setInfo(T info) {
        this.info = info;
    }

    public T getInfo() {
        return info;
    }

    public void setLink(LLNode<T> link) {
        this.link = link;
    }

    public LLNode<T> getLink() {
        return link;
    }

    /**
     *Adds a link to a Node
     * 
     * @param newLink       The Link to be added
     */
    public void addLink(LLNode<T> newLink){
        if (link == null){
            this.link = newLink;
        }else{
            LLNode<T> temp = link;
            LLNode<T> pre = null;
            while (temp != null){
                pre = temp;
                temp = temp.link;
            }
        }
    }
}

基本上,我想要实现的是我想修改我的上述代码(无递归代码),以便在彼此之后而不是在彼此之上绘制正方形,这与我发布的第一个FractalDriver类的方式类似(非常递归)一)画他们

Basically what I'm trying to achieve is I want to modify my above code (code without recursion) to paint the squares behind eachother rather than on top of eachother similarly to how the very first FractalDriver class I posted (very top recursive one) paints them

推荐答案

这是一个比递归慢但像素完美的迭代解决方案.

Here's an iterative solution that is slower than recursion but is pixel perfect.

我想提高速度,但现在没有时间了.

I'd like to work on making it faster but I'm outta time right now.

希望有帮助.

package com.stackoverflow.candied_orange;
import java.awt.image.*;
import java.awt.Color;
import java.io.*;
import javax.imageio.*;
import java.util.*;
public class InFrontInterative {

    public static void main(String[] args) throws IOException{

        final int SIDE = 1000; // image is SIDE X SIDE        
        BufferedImage image = new BufferedImage(SIDE,SIDE,BufferedImage.TYPE_INT_RGB);

        drawImage(SIDE, image);
        saveImage(image, "helloSquares.png");
    }

    //Removed IO to enable unit testing
    protected static void drawImage(final int SIDE, BufferedImage image) {
        final int BLACK = Color.BLACK.getRGB();
        final int WHITE = Color.WHITE.getRGB();
        final int HALF = SIDE / 2;

        //Draw background on whole image
        new Square(HALF, HALF, SIDE, BLACK).draw(image);

        //Draw foreground starting with centered half sized square
        Square square = new Square(HALF, HALF, HALF, WHITE);
        drawFractal(square, image);
    }

    private static void drawFractal(Square square, BufferedImage image){

        Stack<Square> squares = new Stack<>();
        Queue<Square> breeders = new LinkedList<>();
        breeders.add(square);

        //Produce
        while (breeders.size() > 0) {
            square = breeders.remove();

            int half = square.half();

            if (half > 0) {
                System.out.println(half);//TODO remove debugging code 

                int left = square.left();
                int top = square.top();
                int right = square.right();
                int bottom = square.bottom();
                int newColor = square.color - 100000;                

                breeders.add(new Square(left, top, half, newColor));
                breeders.add(new Square(left, bottom, half, newColor));
                breeders.add(new Square(right, top, half, newColor));
                breeders.add(new Square(right, bottom, half, newColor));
                squares.push(square);   
            }            
        }

        //Consume
        while (squares.size() > 0) {
            square = squares.pop();
            square.draw(image);
        }
    }

    protected static void saveImage(BufferedImage image, String fileOut)
    throws IOException {
        File outputfile = new File(fileOut);
        ImageIO.write(image, "jpg", outputfile);
    }    
}

这篇关于如何在不使用递归的情况下使正方形相互之间而不是彼此之上生成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆