数学计算:比较坐标以形成合理的形状

时间:2016-09-20 18:15:52

标签: java math

我有一个数学问题。我做了一个游戏,用户是一个12岁的孩子。孩子的目标是计算绘制形状的面积。在简单和中等模式下,形状给出并硬编码,因此它们不是硬核。在硬模式下,随机生成5个坐标,这就是问题所在。我需要制作一个面积可由12岁儿童计算的形状。随机坐标会出现各种难题,例如交叉点或连接其他2个点的线上的奇点等等。有没有办法计算和避免这些问题?

这是我的代码,它使随机点+在应用程序中的点网格上绘制:

private void gameHard ()
{
    //distance between points is 65 pixels, the numbers that are generated are 1-8
    x1=(genRandomInt())*65;
    x2=(genRandomInt())*65;
    x3=(genRandomInt())*65;
    x4=(genRandomInt())*65;
    x5=(genRandomInt())*65;
    y1=(genRandomInt())*65;
    y2=(genRandomInt())*65;
    y3=(genRandomInt())*65;
    y4=(genRandomInt())*65;
    y5=(genRandomInt())*65;

    compareRCoordinates ();

    areaImage = new JPanel ()
      {  
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(Color.WHITE);
            g2.fillRect(0,0,780,650);
            g2.setColor(Color.BLACK);
            int xnum = 65, ynum = 65;   
            for(ynum=65;ynum<650;ynum=ynum+65)
            {
                int x=0, y=0;
                for(xnum = 65;xnum<780;xnum=xnum+65)
                {
                x = xnum-9;
                y = ynum-9;     
                g2.fillOval(x,y,18,18);

            }
            xnum=xnum+65;
            }
            g2.setColor(Color.RED);
            g2.setStroke(new BasicStroke(6));
            g2.drawLine(x1,y1,x2,y2);
            g2.drawLine(x2,y2,x3,y3);
            g2.drawLine(x3,y3,x4,y4);
            g2.drawLine(x4,y4,x5,y5);
            g2.drawLine(x5,y5,x1,y1);
        }
    };

    areaImage.setBounds(20,20,780,650);
    areaImage.setBorder(BorderFactory.createLineBorder(Color.black));
    this.add(areaImage);
    roundsPlayed++;
}

3 个答案:

答案 0 :(得分:2)

这是一个相当简单的方法的概述。

  • 选择五个不同的随机点。
  • 计算五个点的质心(即平均X坐标和平均Y坐标)。
  • 计算从质心到五个原点中每个原点的角度。如果其中一个点恰好是质心,则选择任意数字(例如0)作为角度。
  • 按照计算的角度顺序排列点。关系可以随意打破。

好的,这些点现在按照你排列它们的顺序制作一个五边形(包括从最后一个点到第一个点的线段)。它不一定是凸的,但它不会有任何“交叉”。你可以在屏幕上画出来。

您可以将区域计算为

( x1 * y2 + x2 * y3 + x3 * y4 + x4 * y5 + x5 * y1 - y1 * x2 - y2 * x3 - y3 * x4  - y4 * x5 - y5 * x1 ) / 2  

答案 1 :(得分:0)

我的基本想法是将64(8乘8)个可能的点划分为5个不相交的矩形区域,并从每个区域中选择一个随机点。拾取区域,以便按顺序连接点将永远不会导致任何连接线交叉。这很简单 - 也许太简单了?

    x1 = genRandomInt(1, 3) * 65;
    y1 = genRandomInt(1, 4) * 65;
    x2 = genRandomInt(1, 3) * 65;
    y2 = genRandomInt(5, 8) * 65;
    x3 = genRandomInt(4, 8) * 65;
    y3 = genRandomInt(6, 8) * 65;
    x4 = genRandomInt(4, 8) * 65;
    y4 = genRandomInt(4, 5) * 65;
    x5 = genRandomInt(6, 8) * 65;
    y5 = genRandomInt(1, 3) * 65;

编写genRandomInt(int from, int to),使其在fromto之间的间隔内返回一个随机int。在上面的代码中,每个矩形区域中有10到15个可能的点。

答案 2 :(得分:0)

使用数组作为坐标便于使用。

可以使用到先前点的随机距离,因此点不在附近。我将数学懒惰,只需重复选择新的随机数,直到随机点不再接近。

最后,我欺骗并使用java.awt.Polygon检查新的候选点是否在多边形内部直到那个。

多边形可以绘制,甚至可以填充。

字段:

int[] xs = new int[5]; // xs[0] till xs[4]
int[] ys = new int[5];
Polygon pentagon;

挑选随机点:

final int NEAR = 20;
for (int i = 0; i < 5; ++i) {
    // Pull random numbers for this i'th point till okay.
    for (;;) {
        xs[i] = random ...
        ys[i] = random ...

        // Check that the point is not inside the polygon till now:
        if (i >= 3) {
            Polygon polygon = new Polygon(xs, ys, i);
            if (polygon.contains(xs[i], ys[i]) {
                continue; // Inside
            }
        }

        // Check that the point are apart:
        boolean near = false;
        for (int j = 0; j < i && !near; ++j) {
            near = Math.abs(xs[i] - xs[j]) < NEAR
                && Math.abs(ys[i] - ys[j]) < NEAR;
        }
        if (near) {
            continue; // Too near
        }

        break; // Found point i
    } 
}
pentagon = new Polygon(xs, ys, 5);

图:

        g2.setColor(Color.RED);
        g2.setStroke(new BasicStroke(6));
        g2.draw(pentagon);

        g2.setColor(Color.TEAL);
        g2.fill(pentagon);
        ... draw grid

正如您可能想象的那样,可能有足够的循环。当前四个点覆盖屏幕的最大部分时无尽。