Создание Белки - PullRequest
       42

Создание Белки

2 голосов
/ 08 декабря 2009

Я программист первого курса. Я пытаюсь создать белка. (квадрат с закругленными углами).

Пока мне удалось добраться. Мне дали константы 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);
  }
}

Ответы [ 5 ]

4 голосов
/ 08 декабря 2009

Если вы отправляете это как домашнее задание, вам могут помочь некоторые элементы стиля. Каковы роли 200, 100 и 300? Это «магические константы», которых следует избегать. Они связаны или это просто шанс, что они имеют эти ценности? Предлагаем вам использовать такие символы, как:

int NPOINTS = 200;

или

double radius = 100.0

Это покажет, действительно ли 300 было желаемым значением. Я не проверял.

Лично я бы не стал писать

y*-1

но

-y

так как слишком легко ошибиться с первым.

Я бы также распечатал 200 точек в виде числа с плавающей запятой и посмотрел, можно ли на глаз определить, где ошибка. Весьма вероятно, что паразитные линии начерчены либо в начале, либо в конце расчета - легко допустить ошибки «конечного эффекта», когда ровно одна точка пропускается или вычисляется дважды.

Также экспериментировать дешево. Попробуйте перебрать c от 0 до 100, или от 0 до 10, или от 0 до 198, или от 1 до 200. Всегда ли встречается ваша паразитная линия / треугольник?

ОБНОВЛЕНИЕ Вот что я считаю неправильным и как с этим бороться. Вы допустили очень естественную графическую ошибку и ошибку ограждения (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));
}
4 голосов
/ 08 декабря 2009

Это домашняя работа или есть какая-то другая причина, по которой вы не используете Graphics#drawRoundRect()?

0 голосов
/ 08 декабря 2009

Ого, вы, ребята, задумывались над этим, или как! Почему бы просто не использовать drawLine () четыре раза, чтобы нарисовать прямые части прямоугольника, а затем использовать drawArc (), чтобы нарисовать закругленные углы?

0 голосов
/ 08 декабря 2009

Хорошо, после дальнейшего изучения вот почему вы получаете «треугольник, пересекающий его». Когда вы рисуете Polygon, точки рисуются, и последняя точка соединяет первую точку, закрывая точки и создавая многоугольник. Так как вы рисуете одну половину, она рисуется (затем соединяется с собой), и то же самое происходит для другой стороны.

В качестве теста этого измените последние пару строк на:

  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, а затем отсортировал его, когда закончил, но я не знаю специфики того, что вы можете и не можете делать.

0 голосов
/ 08 декабря 2009

Существует версия JavaScript здесь . Вы можете просмотреть источник и «сравнить заметки», чтобы потенциально увидеть, что вы делаете неправильно.

...