2

我是一年级程序员。我正在尝试创建一个松鼠。(带圆角的正方形)。

到目前为止,我已经设法得到。我得到了 a、b 和 r 的常数。如果有人可以提供帮助,我将非常感激。我对此完全是个菜鸟。所以要友善:)

package squircle;

import java.awt.*;
import javax.swing.*;
import java.lang.Math;

public class Main extends javax.swing.JApplet {

  public void paint(Graphics g){

   // (x-a)^4  +  (y-b)^4  = r^4

   //    y =   quadroot( r^4 - (x-a)^4  + b)     
   // x values must fall within   a-r < x < a+r

    int[] xPoints = new int[200];
    int[] yPoints = new int[200];
    int[] mypoints = new int[200];

    for(int c = 0; c <200; c++){

       int a = 100;
       int r = 100;
       int b = 100;
       double x = c ;


       double temp = (r*r*r*r);
       double temp2 = x-a;
       double temp3 = ((temp2)*(temp2)*(temp2)*(temp2));
       double temp6 = Math.sqrt(temp-temp3);
       double y = (Math.sqrt(temp6) + b );
       double z = (y*-1)+300;

       mypoints[c]=(int)z;

    // if (c>100){
    //     y = y*1;
    // }
    // else if(c<100){
    //     y = y*1;
    // }

       xPoints[c]=(int)x;
       yPoints[c]=(int)y;


    // change the equation to find x co-ordinates 
    // change it to find y co-ordinates. 

    // r is the minor radius     
    // (a,b) is the location of the centre

    // a = 100
    // b = 100
    // r = 100
    // x value must fall within  0 or 200

    }

    g.drawPolygon(xPoints, yPoints, xPoints.length);
    g.drawPolygon(xPoints, (mypoints), xPoints.length);
  }
}
4

5 回答 5

4

如果您将此作为家庭作业提交,那么一些风格元素可能会对您有所帮助。200、100、300的作用是什么?这些是应该避免的“神奇常数”。它们是相关的还是仅仅是它们具有这些值的机会?建议您使用以下符号:

int NPOINTS = 200;

或者

double radius = 100.0

这将揭示 300 是否真的是您想要的值。我没有检查。

个人不会写

y*-1

-y

因为前者太容易打错了。

我还会将 200 个点打印为浮点数,看看您是否可以通过肉眼判断错误在哪里。伪线很可能是在计算的开始或结束时绘制的 - 在恰好省略一个点或计算两次的情况下,很容易产生“最终影响”错误。

实验也很便宜。尝试从 0 到 100 或 0 到 10、或 0 到 198 或 1 到 200 迭代 c。你的虚假线/三角形是否总是出现?

更新这是我认为是错误的以及如何解决它。您犯了一个非常自然的图形错误和一个围栏错误(http://en.wikipedia.org/wiki/Off-by-one_error)并且很难检测出什么是错误的,因为您的变量名称选择不当。

是什么mypoints?我相信这是松鼠的下半部分——如果你叫它,bottomHalf那么那些回复的人会更快地发现问题:-)。

您的图形问题是您正在绘制两个半松鼠。您正在绘制闭合曲线 - 当您到达最后一点 (c==199) 时,多边形通过拉回 c==0 来闭合。这样就形成了 D 形。你有两个 D 形,一个凸起向上,一个向下。每个都有一条关闭多边形的水平线。

您的栅栏错误是您正在从 0 到 199 绘制点。对于要从 0 到 200 绘制的半松鼠。那是 201 点!失去一个点意味着你有一条非常轻微的倾斜线。底线从顶部向相反方向倾斜。这给了你一个非常楔形的形状,你称之为三角形。我猜你的三角形实际上并没有闭合,而是像馅饼的一片,但非常/锋利。

(下面的代码可能更漂亮、更紧凑。但是,将对称问题分解为象限或八分圆通常很有用。使用角度扫出多边形也很有趣)。

你实际上想要一个多边形。代码应该是这样的:

int NQUADRANT = 100;
int NPOINTS = 4*NQUADRANT ; // closed polygon
double[] xpoints = new double[NPOINTS];
double[] ypoints = new double[NPOINTS];

你的松鼠是 100,半径为 100 的 100。我在这里选择了不同的值来强调它们不相关。通过使用符号名称,您可以轻松地改变它们。

double xcenter = 500.0;
double ycentre = 200.0;
double radius = 100.;

double deltax = radius/(double) NQUADRANT;
// let's assume squircle is centered on 0,0 and add offsets later
// this code is NOT complete or correct but should show the way
// I might have time later
for (int i = 0; i < NPOINTS; i++) {

if (i < NQUADRANT) {
    double x0 = -radius + i* deltax;
    double y0 = fourthRoot(radius, x0);
    x[i] = x0+xcenter;
    y[i] = y0+ycenter;

}else if (i < 2*NQUADRANT) {
    double x0 = (i-NQUADRANT)* deltax;
    double y0 = fourthRoot(radius, x0);
    x[i] = x0+xcenter;
    y[i] = y0+ycenter;
}else if (i < 3*NQUADRANT) {
    double x0 = (i-2*NQUADRANT)* deltax;
    double y0 = -fourthRoot(radius, x0);
    x[i] = x0+xcenter;
    y[i] = y0+ycenter;
}else {
    double x0 = -radius + (i-3*NQUADRANT)* deltax;
    double y0 = -fourthRoot(radius, x0);
    x[i] = x0+xcenter;
    y[i] = y0+ycenter;
}

}
// draw single polygon

private double fourthRoot(double radius, double x) {
    return Math.sqrt(Math.sqrt(radius*radius*radius*radius - x*x*x*x));
}
于 2009-12-08T00:55:09.637 回答
4

是作业还是您不使用的其他原因Graphics#drawRoundRect()

于 2009-12-08T00:06:15.760 回答
0

这里有一个 javascript 版本。您可以查看源代码并“比较笔记”以潜在地了解您做错了什么。

于 2009-12-08T01:27:32.833 回答
0

好的,经过进一步调查,这就是为什么您会得到“与它相交的三角形”。当您 drawPolygon 绘制点并且最后一个点连接第一个点,关闭这些点并制作多边形。由于您绘制了一半,因此它被绘制(然后连接到自身),然后另一侧也会发生同样的情况。

作为对此的测试,将最后几行更改为:

  for( int i = 0; i < yPoints.length; i++ ) {
   g.drawString( "*", xPoints[ i ], yPoints[ i ] );
  }

  for( int i = 0; i < mypoints.length; i++ ) {
   g.drawString( "*", xPoints[ i ], mypoints[ i ] );
  }

//  g.drawPolygon( xPoints, yPoints, xPoints.length );
//  g.drawPolygon( xPoints, ( mypoints ), xPoints.length );

这有点粗略,但我想你会明白的。有很多解决方案,我个人会尝试使用 Point 类的数组,然后在完成后对其进行排序,但我不知道你能做什么和不能做什么的细节。

于 2009-12-08T08:58:08.013 回答
0

哇,你们是不是想多了,还是什么!为什么不使用 drawLine() 四次绘制矩形的直线部分,然后使用 drawArc() 绘制圆角?

于 2009-12-08T09:32:13.090 回答