【问题标题】:Recursive ruler tick applet递归标尺刻度小程序
【发布时间】:2014-11-12 15:58:29
【问题描述】:

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

我必须制作一个递归小程序,从尺子上绘制测量刻度,就像下面的尺子一样:


(来源:myonlineruler.com

到目前为止,我已经能够获得最高的线条,但中间的标记并没有缩小:

这是我的代码:

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 );

我明白了:

似乎在我不理解的小程序中绘制图形有一些基本的东西。我们在课堂上没有涵盖任何此类内容,然后就把这个作业丢给了我们。

就像我说的,我不是在寻找答案,只是对我正在尝试的内容提出一些建议或更正。谢谢。


编辑 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


哦,我找到了斜线的来源,我没有使用相同的 y 坐标作为基线。哎呀。这是它现在的样子:

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

还有:

【问题讨论】:

    标签: java recursion graphics applet


    【解决方案1】:

    让我们看看我们是否可以在不付出太多的情况下为您提供一些有用的思考:

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

    1) 在递归步骤中,在进行递归调用之前,是否要画一条线?如果有,在哪里,多高?

    2) 在基本情况下,当您到达递归的底部并且问题无法再拆分时,您要画一条线吗?如果有,在哪里,多高?

    提示 1:您可能首先需要将 x 轴分成 8 个“1 英寸”块,然后分别对每个块进行递归。

    提示 2Graphics.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,底部Y)]

    else
    {
      drawingArea.drawLine( midX, bottomY, midX, topY );
    
      drawRuler( leftX, midX, topY/2, bottomY, drawingArea );
      drawRuler( midX, rightX, topY/2, bottomY, drawingArea );
    }
    

    【讨论】:

    • 谢谢!修修补补继续
    • 刚刚对您的建议进行了编辑。仍然有倾斜线的问题,虽然没有那么多也没有那么错误
    • 斜线来自基本情况 drawingArea.drawLine( leftX, bottomY, rightX, topY );,因为 x1 != x2 AND y1 != y2
    • 如果你只是暂时注释掉那行,我想你会看到一些有趣的东西。
    • 刚刚注意到并发布了另一个更新,但你打败了我 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 2019-07-10
    • 2020-01-27
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 2011-09-17
    相关资源
    最近更新 更多