java.awt.drawarc,Java: Draw a circular spiral using drawArc

问题

I'm working on a java programming exercise where we have to draw a circular spiral using the drawArc method so that the result looks similar to this:

fd8a95efaeddf697443185105afb0c29.png

I've been working on this for a while and this is what I have so far:

import java.awt.Graphics;

import javax.swing.JPanel;

import javax.swing.JFrame;

public class CircSpiral extends JPanel {

public void paintComponent(Graphics g) {

int x = 100;

int y = 120;

int width = 40;

int height = 60;

int startAngle = 20;

int arcAngle = 80;

for (int i = 0; i < 5; i++) {

g.drawArc(x, y, width, height, startAngle, arcAngle);

g.drawArc(x + 10, y + 10, width, height, startAngle + 10, arcAngle);

x = x + 5;

y = y + 5;

startAngle = startAngle - 10;

arcAngle = arcAngle + 10;

}

}

public static void main(String[] args) {

CircSpiral panel = new CircSpiral();

JFrame application = new JFrame();

application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

application.add(panel);

application.setSize(300, 300);

application.setVisible(true);

}

}

My code gives me this result:

34aaf0ab43892329018c98600e18b5c8.png

I know the problem lies in my arguments for the drawArc method because the numbers aren't right, but I don't know how to go about making the numbers go in a circular manner. Any help is appreciated. Thank you!

回答1:

Your idea is almost right. I did some modifications. You need to inverse the angle to draw the other side of the spiral and use fixed point to startAngle.

import java.awt.Graphics;

import javax.swing.JPanel;

import javax.swing.JFrame;

public class CircSpiral extends JPanel {

public void paintComponent(Graphics g) {

int x = getSize().width / 2 - 10;

int y = getSize().height/ 2 - 10;

int width = 20;

int height = 20;

int startAngle = 0;

int arcAngle = 180;

int depth = 10;

for (int i = 0; i < 10; i++) {

if (i % 2 == 0) {

// g.drawArc(x + 10, y + 10, width, height, startAngle + 10, -arcAngle);

// x = x - 5;

y = y - depth;

width = width + 2 * depth;

height = height + 2 * depth;

g.drawArc(x, y, width, height, startAngle, -arcAngle);

} else {

// g.drawArc(x + 10, y + 10, width, height, startAngle + 10, arcAngle);

x = x - 2 * depth;

y = y - depth;

width = width + 2 * depth;

height = height + 2 * depth;

g.drawArc(x, y, width, height, startAngle, arcAngle);

}

}

}

public static void main(String[] args) {

CircSpiral panel = new CircSpiral();

JFrame application = new JFrame();

application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

application.add(panel);

application.setSize(300, 300);

application.setVisible(true);

}

}

回答2:

If this were my project, yes I'd draw my arcs in a loop, but within the loop, I'd try to make the arc's bounding box bigger but still centered over the same location. To do this I'd decrement x and y by some small constant, say DELTA (which I'd set to == 1), and I'd increment width and height by 2 * DELTA. I'd also leave my arcAngle unchanged but rather would change my startAngle in the loop like so: startAngle = startAngle - arcAngle;.

For example, this:

import java.awt.Dimension;

import java.awt.Graphics;

import javax.swing.JPanel;

import javax.swing.JFrame;

@SuppressWarnings("serial")

public class CircSpiral extends JPanel {

private static final int DELTA = 1;

private static final int ARC_ANGLE = 20;

private static final int PREF_W = 300;

private static final int PREF_H = PREF_W;

private static final int LOOP_MAX = 400;

public void paintComponent(Graphics g) {

int x = PREF_W / 2;

int y = PREF_H / 2;

int width = 1;

int height = 1;

int startAngle = 0;

int arcAngle = ARC_ANGLE;

for (int i = 0; i < LOOP_MAX; i++) {

g.drawArc(x, y, width, height, startAngle, arcAngle);

x = x - DELTA;

y = y - DELTA;

width += 2 * DELTA;

height += 2 * DELTA;

startAngle = startAngle - arcAngle;

}

}

@Override

public Dimension getPreferredSize() {

if (isPreferredSizeSet()) {

return super.getPreferredSize();

}

return new Dimension(PREF_W, PREF_H);

}

public static void main(String[] args) {

CircSpiral panel = new CircSpiral();

JFrame application = new JFrame();

application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

application.add(panel);

application.pack();

application.setLocationRelativeTo(null);

application.setVisible(true);

}

}

Would result in this:

798e784d1a0d6d765334aabc86c2c9cd.png

回答3:

The following code will output this image:

ccff09ef388e4f04c4ba3e8076b3e068.png

import java.awt.Graphics;

import javax.swing.JPanel;

import javax.swing.JFrame;

public class CircSpiral extends JPanel {

public void paintComponent(Graphics g) {

int centerX = getWidth() / 2;

int centerY = getHeight() / 2;

int numIterations = 5;

int arcWidth = 10;

int arcGrowDelta = 30;

for (int i = 0; i < numIterations; i++) {

g.drawArc(centerX - arcWidth, centerY - arcWidth, 2 * arcWidth, 2 * arcWidth, 0, 180);

arcWidth += arcGrowDelta;

g.drawArc(centerX - arcWidth, centerY - arcWidth, 2 * arcWidth - arcGrowDelta, 2 * arcWidth, 180, 180);

}

}

public static void main(String[] args) {

CircSpiral panel = new CircSpiral();

JFrame application = new JFrame();

application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

application.add(panel);

application.setSize(300, 300);

application.setVisible(true);

}

}

The idea is very simple, just draw the upper half of a circle, like this:

408ab211d622abd68ab8b4250b0c8a8d.png

Then increment the arc size by a constant factor and draw the bottom half of the circle but making the end point of this circle and the upper circle match, for it, just substrate the arcGrowDelta from the bottom circle width:

3027a97326320e263a4ad06bcb7edabe.png

And repeat.

回答4:

This is my solution:

package mainpack;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import javax.swing.JPanel;

public class SpiralPanel extends JPanel {

private static final long serialVersionUID = 1L;

@Override

public void paintComponent(Graphics g) {

super.paintComponent(g);

Graphics2D g2d = (Graphics2D)g;

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2d.setRenderingHint(RenderingHints.KEY_RENDERING,

RenderingHints.VALUE_RENDER_QUALITY);

int width = 10;

int height = 10;

int startAngle = 0;

int arcAngle = 180;

int x = (getWidth() - width) / 2;

int y = (getHeight() - height) / 2;

int i = 0;

int t = 0;

while (i < 36) {

g2d.drawArc(x + t, y, width, height, startAngle, arcAngle);

if (i % 2 == 0) {

t -= 10;

}

y -= 5;

width += 10;

height += 10;

startAngle += 180;

i++;

}

}

}

回答5:

I am a beginner to java and finally managed how to create the spiral.

Here is my code:

int lineLength = 20; //starting line length

int x = getWidth() / 2; //start drawing from center of JPanel

int y = getHeight() / 2; //start drawing from center of JPanel

for( int counter = 0; counter < 10; counter++ )

{

g.drawArc( x, y, lineLength, lineLength, 0, 180 ); //draws top semicircle of equal width and height

lineLength += 20; //increases arc diameter

x -= 20; //moves x coordinate left

g.drawArc( x, y - 10, lineLength, lineLength, 0, -180 ); //draws bottom semicircle; 'y - 10' joins the 2 semicircles

lineLength += 20; //increases arc diameter

y -= 20; //moves y coordinate up

}

回答6:

If you're willing to let some good old trigonometry do the work, you could use this:

import java.awt. *;

import javax.swing. *;

import java.math.*;

public class Spiral extends JFrame {

public Spiral()

{

// Set Window

setTitle("Spirale");

setSize(1500, 1500);

setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

setVisible(true);

}

public void paint(Graphics g)

{

super.paint(g);

for(double i = 1; i < 50000; i++)

{

int locY = 600 - (int) (Math.cos((Math.PI*i)/1800)*i/50);

int locX = 600 - (int) (Math.sin((Math.PI*i)/1800)*i/50);

g.drawLine(locX, locY, locX, locY);

}

}

public static void main(String[] args) {

new Spiral();

}

}

来源:https://stackoverflow.com/questions/29638733/java-draw-a-circular-spiral-using-drawarc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值