2015-06-24 2 views
1

Действительно возникают проблемы, пытаясь нарисовать четыре розы лист: Это упражнение:Drawing Four Leaf Rose в Java

Нарисуйте картину «fourleaved розы», уравнение которой в полярных координатах г = соз (2θ). Пусть θ переходит от 0 до 2 * pi за 100 шагов. Каждый раз, вычислить г, а затем вычислить (х, у) координаты от полярных координатах, используя формулу х = г ⋅ Cos (q), Y = г ⋅ sin (q)

Мой код:

public Rose(double awidth, double aheight) 
{ 
    width = awidth; 
    height = aheight; 
    theta = 0; 
} 


public void drawRose(Graphics2D g2) 
{ 
     Ellipse2D.Double test ; 
    double r = 0; 
    for(int i = 0; i <= 100; i++) 
    { 
      r = Math.cos(Math.toRadians(2*theta) ); 
     x = r *( Math.cos( Math.toRadians(theta)) * width) + 300; 
      y = r * ( Math.sin( Math.toRadians(theta)) * height) + 300 ; 
    test = new Ellipse2D.Double(x, y, width, height); 
    theta += 3.6; 
    g2.draw(test); 
    }   
} 

}

Любая помощь будет значительно appreciately.

+0

А что, собственно, не так с вашей реализацией? – MarsAtomic

+0

Я сам не создавал объекты Ellipse2D, а создавал 'List ', используя формулы, а затем рисовал линии между точками в списке. –

+0

Я еще не узнал о Списке . –

ответ

0

Вашей самая большая ошибка здесь:

test = new Ellipse2D.Double(x, y, width, height); 

Вы создаете 100 эллипсов с точками, которые находятся на розе, но с высотой и шириной желаемой розы. Вы действительно не хотите 100 эллипсов, а скорее хотите соединить линии между созданными вами точками x и y, которые соединяют текущие x, y с предыдущими созданными (если есть предыдущие x и у).

Один из способов с помощью этих предложений, но есть и другие способы сделать это:

  • Используйте Path2D объект, конкретная реализация будет Path2D.Double, чтобы держать ваши точки данных. Создайте это, прежде чем создавать точки данных.
  • Используйте цикл, который идет от 0 до 100, и сделать это в конструкторе класса
  • установить двойную тету в петле
  • установить свой двойной r переменными в цикле
  • Рассчитайте й и у double points
  • Увеличьте свои точки x и y, умножив их на коэффициент масштабирования, чтобы рисунок имел некоторый размер. Я использовал 150,0
  • Переведите ваши значения x и y, добавив константу перевода. Я использовал 200, и он отлично работал в 400 x 400 JPanel. Иначе центр розы будет равен 0, 0, и только четвертая часть будет видна.
  • В первой итерации moveTo(...) метода для вызова контура в Path2D, чтобы добавить отправную точку
  • Во всех других итерациях вызов метода lineTo(...). Это приведет линию между соседними точками.
  • После цикла for закройте путь, вызвав на нем closePath().
  • Нарисуйте путь в методе paintComponent в JPanel, отбросив параметр Graphics в объект Graphics2D (на самом деле вам это не нужно, поскольку ваш метод draw получает объект Grahpics2D) и вызывает draw(path) с объектом Graphics2D, передавая ваш Path2D объект.

Например, это создано:

enter image description here с этим кодом:

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Stroke; 
import java.awt.geom.Path2D; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

@SuppressWarnings("serial") 
public class RosePanel extends JPanel { 
    private static final int PREF_W = 400; 
    private static final int PREF_H = PREF_W; 
    private static final int MAX = 100; 
    private static final double SCALE = 150.0; 
    private static final double DELTA_X = 200; 
    private static final double DELTA_Y = DELTA_X; 
    private static final Color ROSE_COLOR = Color.red; 
    private static final Stroke ROSE_STROKE = new BasicStroke(8f); 
    private Path2D path = new Path2D.Double(); 

    public RosePanel() { 

     for (int i = 0; i < MAX; i++) { 
     double theta = i * 2 * Math.PI/MAX; 
     double r = Math.cos(2 * theta); 
     double dX = SCALE * r * Math.cos(theta) + DELTA_X; 
     double dY = SCALE * r * Math.sin(theta) + DELTA_Y; 
     if (i == 0) { 
      path.moveTo(dX, dY); 
     } else { 
      path.lineTo(dX, dY); 
     } 
     } 
     path.closePath(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setColor(ROSE_COLOR); 
     g2.setStroke(ROSE_STROKE); 
     g2.draw(path); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
     return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private static void createAndShowGui() { 
     RosePanel mainPanel = new RosePanel(); 

     JFrame frame = new JFrame("RosePanel"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

Следует отметить, что основное различие между моим кодом и вашим, кроме перевода и масштабирование - это то, что я соединяю линию между созданными точками.

+0

Ваше предложение выглядит хорошо и все. Тем не менее, я все еще нахожусь в Greenhorn на Java. То, что я знаю, это основы, такие как циклы, как создавать классы ... Я просто выбрал книгу, и из нее я изучаю Java и пытаюсь решить все проблемы в конце каждой главы. –

+0

@UstazMohammed: см. Edit to answer , Самая большая ошибка заключается в том, что вы пытаетесь создать 100 эллипсов, когда вам не нужны и не нужны эллипсы. Вы хотите подключить точки. –

+0

Я понимаю, но книга, которую я использую, не упоминает о классе Path2D. Черт, я не могу найти его в своих Java-библиотеках. Без класса Path существует другой способ. Должен ли я использовать строки вместо эллипса? Спасибо за ваше время и терпение. –