递归标尺刻度小程序

时间:2014-11-12 15:58:29

标签: java recursion graphics applet

首先,这是作业,所以我不是要求答案,只是关于如何继续我正在做的事情的一些指示。

我必须制作一个递归的小程序,从一个标尺上绘制测量标记,如下图所示:

http://www.myonlineruler.com/ruler.png

到目前为止,我已经能够获得最高的线条,但两者之间的分数并没有缩小:

这是我的代码:

import java.applet.Applet;
import java.awt.*

public class RulerOfTheWorld extends Applet
{
  private Image display;
  private Graphics drawingArea;

  public void init()
  {
    setSize( 600, 400 );
    int height = getSize().height;
    int width = getSize().width;
    display = createImage( width, height );
    drawingArea = display.getGraphics();

    drawRuler( 0, height / 2, width, height / 2, drawingArea );
  }

  public void paint( Graphics g )
  {
    g.drawImage( display, 0, 0, null );
  }

  public static void drawRuler( int leftX,
                                int leftY,
                                int rightX,
                                int rightY,
                                Graphics drawingArea )
  {
    final int STOP = 40;
    int midX = ( leftX + rightX ) / 2;
    int midY = ( leftY + rightY ) / 2;

    if(( rightX - leftX ) <= STOP )
    {
      drawingArea.drawLine( midX, leftY, midX, midY / 2 );
      drawingArea.drawLine( leftX, leftY, rightX, rightY );
    }
    else
    {
      drawRuler( leftX, leftY, midX, midY, drawingArea );
      drawRuler( midX, midY, rightX, rightY, drawingArea );
    }
  }
}

我一直在寻找事情,看看事情是如何被绘制的,但我似乎无法想出任何有效的事情;我的线条偏斜了。当试图将递归调用中的“顶部”y坐标除以2:

if(( rightX - leftX ) <= STOP )
{
  drawingArea.drawLine( midX, leftY, midX, midY / 2 );
  drawingArea.drawLine( leftX, leftY, rightX, rightY );
}
else
{
  drawRuler( leftX, leftY, midX, midY/2, drawingArea );
  drawRuler( midX, midY, rightX, rightY/2, drawingArea );
}

我明白了:

如果我尝试将“初始”y坐标除以2

  drawRuler( leftX, leftY/2, midX, midY, drawingArea );
  drawRuler( midX, midY/2, rightX, rightY, drawingArea );

我明白了:

似乎有一些关于在applet中绘制图形的基本信息,我不理解。我们没有在课堂上报道任何类似的内容,然后将这项任务转交给我们。

就像我说的那样,我不是在寻找答案,只是对我正在尝试的建议或更正。感谢。


编辑1


我应该注意到,我的导师说我们应该能够通过查看关于制作“随机分形线”的书中的一个例子来完成这个。以下是本书的例子:

import java.applet.Applet;
import java.awt.*;


public class Fractal extends Applet
{
  private Image display;
  private Graphics drawingArea;

  public void init()
  {
    int height = getSize().height;
    int width = getSize().width;
    display = createImage( width, height );
    drawingArea = display.getGraphics();

    randomFractal( 0, height/2, width, height/2, drawingArea );
  }

  public void paint( Graphics g )
  {
    g.drawImage( display, 0, 0, null );
  }

  public static void randomFractal( int leftX,
                                    int leftY,
                                    int rightX,
                                    int rightY,
                                    Graphics drawingArea )
  {
    final int STOP = 4;
    int midX, midY;
    int delta;

    if(( rightX - leftX ) <= STOP )
    {
      drawingArea.drawLine( leftX, leftY, rightX, rightY );
    }
    else
    {
      midX = ( leftX + rightX ) / 2;
      midY = ( leftY + rightY ) / 2;

      delta = ( int ) (( Math.random() - 0.5 ) * ( rightX - leftX ) );
      midY += delta;

      randomFractal( leftX, leftY, midX, midY, drawingArea );
      randomFractal( midX, midY, rightX, rightY, drawingArea );
    }
  }
}

编辑2


@Mike Ounsworth,我尝试了类似的东西,但有一组线总是倾斜的:

我没有更改我的方法标题但是我以类似的方式组织了我的数据:

public static void drawRuler( int leftX,
                              int bottomY,
                              int rightX,
                              int topY,
                              Graphics drawingArea )
{
  final int STOP = 40;
  int midX = ( leftX + rightX ) / 2;

  if(( rightX - leftX ) <= STOP )
  {
    drawingArea.drawLine( leftX, bottomY, rightX, topY );
  }
  else
  {
    drawingArea.drawLine( midX, bottomY, midX, topY );

    drawRuler( leftX, bottomY, midX, topY / 2, drawingArea );
    drawRuler( midX, bottomY, rightX, topY / 2, drawingArea );
  }
}

编辑3


Oooooo我发现斜线来自哪里,我没有使用相同的y坐标作为基线。 Woops。这就是现在的样子:

if(( rightX - leftX ) <= STOP )
{
  drawingArea.drawLine( leftX, bottomY, rightX, bottomY );
}

1 个答案:

答案 0 :(得分:2)

让我们看看我们是否可以给你一些有用的东西来思考而不会给予太多:

递归的工作方式是,在每个步骤中,您执行与之前相同的操作,但是在(通常)较小版本的数据上执行。在您发布的代码中,您将绘图区域划分为一半,并在右半部分和左半部分递归,在那里绘制线条。好。递归函数有两个部分:1)递归步骤,即循环,做一些工作,然后将问题分成两半,2)基本情况,这是你停止递归的点,因为问题不能解决被拆分得更小。所以,您需要考虑的问题:

1)在递归步骤中,在进行递归调用之前,是否要绘制一条线?如果是这样,有多高?

2)在基本情况下,当你已经到了递归的底部并且问题不能再被拆分时,你想画一条线吗?如果是这样,有多高?

提示1 :您可能首先需要将x轴分解为8&#34; 1英寸&#34;块和每个块上的递归分开。

提示2 Graphics.drawLine()具有以下定义:

drawLine(int x1, int y1, int x2, int y2)
    Draws a line, using the current color, between the points (x1, y1) and (x2, y2) in this graphics context's coordinate system.

因此,如果你想要垂直线,请确保x1 == x2,如果你想要水平线,确保y1 == y2,其他任何东西都会给出斜线。

提示3 (这很有趣!):尝试将此作为递归步骤,看看会发生什么[您必须将方法标题调整为drawRuler(leftX,rightX, topY,bottomY)]

else
{
  drawingArea.drawLine( midX, bottomY, midX, topY );

  drawRuler( leftX, midX, topY/2, bottomY, drawingArea );
  drawRuler( midX, rightX, topY/2, bottomY, drawingArea );
}