Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:使用绘图面板绘制星形和连接点_Java_Loops_Drawing_Polygon - Fatal编程技术网

Java:使用绘图面板绘制星形和连接点

Java:使用绘图面板绘制星形和连接点,java,loops,drawing,polygon,Java,Loops,Drawing,Polygon,我在搞清楚三件事上有困难。(使用图形面板创建:) 问题#1:绘制多边形,使其居中且不弯曲。画了更多的点,这是不明显的 问题2:将恒星的所有点连接在一起,形成一个巨大的圆(点)。我不明白为什么会这样,除非这个方法不是最好的 问题#3:当用少量的点绘制时,我注意到它不能正确绘制点,并且看起来像一个正方形 我真的很感激你的帮助 import java.awt.*; public class StarSampler { public static void main(String[]

我在搞清楚三件事上有困难。(使用图形面板创建:)

问题#1:绘制多边形,使其居中且不弯曲。画了更多的点,这是不明显的

问题2:将恒星的所有点连接在一起,形成一个巨大的圆(点)。我不明白为什么会这样,除非这个方法不是最好的

问题#3:当用少量的点绘制时,我注意到它不能正确绘制点,并且看起来像一个正方形

我真的很感激你的帮助

import java.awt.*;

public class StarSampler {

       public static void main(String[] args)
       {
           DrawingPanel panel = new DrawingPanel(500, 500);
           Graphics2D g = panel.getGraphics();
           g.setColor(Color.BLUE);

           fillStar(g, 250, 250, 150, 5, 1);
       }

       public static void fillStar(Graphics2D g, int ctrX, int ctrY, int radius, int nPoints, double spikiness)
       {
           double xDouble[] = new double[2*nPoints];
           double yDouble[] = new double[2*nPoints];
           int xPoint[] = new int[100]; 
           int yPoint[] = new int[100];

           for (int i = 0; i < 2*nPoints; i++)
           {
             double iRadius = (i % 2 == 0) ? radius : (radius * spikiness);
             double angle = (i * 720.0) / (2*nPoints);

             xDouble[i] = ctrX + iRadius * Math.cos(Math.toRadians(angle));
             yDouble[i] = ctrY + iRadius * Math.sin(Math.toRadians(angle));

           for (int j = 0; j < nPoints; j++) // Casts for ints and doubles
           {
               xPoint[j] = (int) xDouble[j];
               yPoint[j] = (int) yDouble[j];
           }
           }

           g.fillPolygon(xPoint, yPoint, nPoints); // Creates polygon
           // Polygon gets drawn crookedly
           g.drawPolyline(xPoint, yPoint, nPoints); // Draws lines to connect points
           // Two lines go straight to (0,0) when nPonts*2 and nothing without *2?
       }
}
import java.awt.*;
公共级星体采样器{
公共静态void main(字符串[]args)
{
DrawingPanel=新的DrawingPanel(500500);
Graphics2D g=panel.getGraphics();
g、 setColor(Color.BLUE);
fillStar(g,250,250,150,5,1);
}
公共静态空白填充星(图形2D g、整数ctrX、整数ctrY、整数半径、整数nPoints、双尖形)
{
双xDouble[]=新的双[2*n点];
double yDouble[]=新的双精度[2*n点];
int xPoint[]=新的int[100];
int yPoint[]=新int[100];
对于(int i=0;i<2*nPoints;i++)
{
双iRadius=(i%2==0)?半径:(半径*尖刺);
双角度=(i*720.0)/(2*n点);
xDouble[i]=ctrX+iRadius*Math.cos(Math.toRadians(angle));
yDouble[i]=ctrY+iRadius*Math.sin(Math.toRadians(angle));
for(int j=0;j
我的输出:

我的目标输出(不带标记点,例如双星):


您的代码存在逻辑性问题,或者是由于编码风格不严谨造成的:

for (int j = 0; j < nPoints; j++) // Casts for ints and doubles
       {
           xPoint[j] = (int) xDouble[j];
           yPoint[j] = (int) yDouble[j];
       }
将改变创建的点之间的角度。这意味着您要么只生成一半的尖峰(如果数量为偶数),要么生成大量交叉线(看起来也不错,但我猜不是您想要的)

单位圆(与三角测量零件相关)的定义方式应确保(1,0)是与中心成0°角的点。这也是你的第一个扣球将被创建的地方。只需减去90°的角度,即可将圆逆时针旋转90°

以下是基于您的代码的工作解决方案。main方法仅保存用于管理简单测试UI的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

public class StarSampler
{
    private static final int WIDTH = 500,
                                HEIGHT = 500,
                                RADIUS = 200;

    private static final double SPIKINESS = 0.5;

    public static void main(String[] args)
    {
        BufferedImage bi = new BufferedImage(500, 500, BufferedImage.TYPE_4BYTE_ABGR);
        updateImage(5, bi);

        JFrame frame = new JFrame("Some Test");
        frame.setLayout(new BorderLayout());

        frame.add(new JLabel(new ImageIcon(bi)), BorderLayout.CENTER);

        //menu to update number of spikes
        JPanel sub = new JPanel();
        sub.setLayout(new BoxLayout(sub, BoxLayout.X_AXIS));
        sub.add(new JLabel("Spikes: "));
        JSpinner spikeSpinner = new JSpinner(new SpinnerNumberModel(5, 1, 500, 1));
        spikeSpinner.addChangeListener(e -> {
            updateImage((Integer) spikeSpinner.getModel().getValue(), bi);
            SwingUtilities.invokeLater(()->frame.repaint());
        });
        sub.add(spikeSpinner);
        frame.add(sub, BorderLayout.SOUTH);

        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static void updateImage(int nSpikes, BufferedImage bi)
    {
        int ctrX = WIDTH / 2, ctrY = HEIGHT / 2;

        int nPoints = nSpikes * 2 + 1;

        int xPoint[] = new int[nPoints];
        int yPoint[] = new int[nPoints];

        //generate star
        for (int i = 0; i < nPoints; i++)
        {
            double iRadius = (i % 2 == 0) ? RADIUS : (RADIUS * SPIKINESS);
            double angle = (i * 360.0) / (2*nSpikes);

            xPoint[i] = (int) (ctrX + iRadius * Math.cos(Math.toRadians(angle - 90)));
            yPoint[i] = (int) (ctrY + iRadius * Math.sin(Math.toRadians(angle - 90)));
        }

        //paint the star
        Graphics2D g2 = (Graphics2D) bi.getGraphics();
        g2.setColor(Color.blue);
        g2.fillRect(0, 0, WIDTH, HEIGHT);
        g2.setStroke(new BasicStroke(4.f));
        g2.setColor(Color.yellow);
        g2.drawPolyline(xPoint, yPoint, nPoints);

        //insert control lines
        g2.setStroke(new BasicStroke(1.f));
        g2.setColor(Color.black);
        for(int i = 0; i < nSpikes * 2; i++)
            g2.drawLine(ctrX, ctrY, xPoint[i], yPoint[i]);

        int w1 = RADIUS,
                w2 = (int) (RADIUS * SPIKINESS);
        g2.drawOval(ctrX - w1, ctrY - w1, w1 * 2, w1 * 2);
        g2.drawOval(ctrX - w2, ctrY - w2, w2 * 2, w2 * 2);
    }
}
import javax.swing.*;
导入java.awt.*;
导入java.awt.image.buffereImage;
公共级星体采样器
{
专用静态最终整数宽度=500,
高度=500,
半径=200;
专用静态最终双尖峰=0.5;
公共静态void main(字符串[]args)
{
BuffereImage bi=新的BuffereImage(500500,BuffereImage.TYPE_4BYTE_ABGR);
更新图像(5,bi);
JFrame=新JFrame(“某些测试”);
frame.setLayout(新的BorderLayout());
frame.add(新的JLabel(新的ImageIcon(bi)),BorderLayout.CENTER);
//更新尖峰数的菜单
JPanel sub=新的JPanel();
sub.setLayout(新的BoxLayout(sub,BoxLayout.X_轴));
子条款添加(新JLabel(“尖峰:”);
JSpinner Spinner=新JSpinner(新SpinnerNumberModel(5,1500,1));
spikeSpinner.addChangeListener(e->{
updateImage((整数)spikeSpinner.getModel().getValue(),bi);
SwingUtilities.invokeLater(()->frame.repaint());
});
sub.add(spikeSpinner);
框架。添加(子,边界布局。南部);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
私有静态void updateImage(int nSpikes、buffereImage bi)
{
int ctrX=宽度/2,ctrY=高度/2;
int nPoints=nSpikes*2+1;
int xPoint[]=新的int[nPoints];
int yPoint[]=新的int[nPoints];
//生星
对于(int i=0;i
这是我的错,我使用的是绘图面板()而不是JPanel。但我真的很欣赏这些代码,我正在努力理解您实现的逻辑。@Aramza UI组件并不重要。
updateImage
-方法包含绘制星形的所有逻辑,而
main
-方法仅处理UI及其创建。
updateImage
-方法的
buffereImage
-参数可以很容易地用
替换
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

public class StarSampler
{
    private static final int WIDTH = 500,
                                HEIGHT = 500,
                                RADIUS = 200;

    private static final double SPIKINESS = 0.5;

    public static void main(String[] args)
    {
        BufferedImage bi = new BufferedImage(500, 500, BufferedImage.TYPE_4BYTE_ABGR);
        updateImage(5, bi);

        JFrame frame = new JFrame("Some Test");
        frame.setLayout(new BorderLayout());

        frame.add(new JLabel(new ImageIcon(bi)), BorderLayout.CENTER);

        //menu to update number of spikes
        JPanel sub = new JPanel();
        sub.setLayout(new BoxLayout(sub, BoxLayout.X_AXIS));
        sub.add(new JLabel("Spikes: "));
        JSpinner spikeSpinner = new JSpinner(new SpinnerNumberModel(5, 1, 500, 1));
        spikeSpinner.addChangeListener(e -> {
            updateImage((Integer) spikeSpinner.getModel().getValue(), bi);
            SwingUtilities.invokeLater(()->frame.repaint());
        });
        sub.add(spikeSpinner);
        frame.add(sub, BorderLayout.SOUTH);

        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static void updateImage(int nSpikes, BufferedImage bi)
    {
        int ctrX = WIDTH / 2, ctrY = HEIGHT / 2;

        int nPoints = nSpikes * 2 + 1;

        int xPoint[] = new int[nPoints];
        int yPoint[] = new int[nPoints];

        //generate star
        for (int i = 0; i < nPoints; i++)
        {
            double iRadius = (i % 2 == 0) ? RADIUS : (RADIUS * SPIKINESS);
            double angle = (i * 360.0) / (2*nSpikes);

            xPoint[i] = (int) (ctrX + iRadius * Math.cos(Math.toRadians(angle - 90)));
            yPoint[i] = (int) (ctrY + iRadius * Math.sin(Math.toRadians(angle - 90)));
        }

        //paint the star
        Graphics2D g2 = (Graphics2D) bi.getGraphics();
        g2.setColor(Color.blue);
        g2.fillRect(0, 0, WIDTH, HEIGHT);
        g2.setStroke(new BasicStroke(4.f));
        g2.setColor(Color.yellow);
        g2.drawPolyline(xPoint, yPoint, nPoints);

        //insert control lines
        g2.setStroke(new BasicStroke(1.f));
        g2.setColor(Color.black);
        for(int i = 0; i < nSpikes * 2; i++)
            g2.drawLine(ctrX, ctrY, xPoint[i], yPoint[i]);

        int w1 = RADIUS,
                w2 = (int) (RADIUS * SPIKINESS);
        g2.drawOval(ctrX - w1, ctrY - w1, w1 * 2, w1 * 2);
        g2.drawOval(ctrX - w2, ctrY - w2, w2 * 2, w2 * 2);
    }
}