gpt4 book ai didi

java - Path2D 绘制错误?

转载 作者:行者123 更新时间:2023-11-30 07:17:41 25 4
gpt4 key购买 nike

我一直在使用 Path2D.Double现在大约一天左右,in this post 我寻求有关设置控制点以允许路径通过指定点的帮助。我将一些代码混合在一起作为一个快速测试平台,随机生成点,然后根据上述帖子中提到的信息弯曲到这些点的路径。

这是可运行的代码,抱歉,它是整体式的,我希望它是可发布的,这样您就可以继续:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;

public class Curver {
public static ArrayList<Point2D> points = new ArrayList<Point2D>();
/**
* @param args
*/
public static void main(String[] args) {

final JFrame window = new JFrame();
window.setPreferredSize(new Dimension(500,500));
window.setLocationRelativeTo(null);

window.addMouseListener(new MouseListener() {

@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub

}

@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub

}

@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub

}

@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub

}

@Override
public void mouseClicked(MouseEvent e) {
new Thread(new Runnable(){
@Override
public void run() {

Random random = new Random();

while(true){

points.add(new Point2D.Double(random.nextInt(window.getWidth()-1)+1,random.nextInt(window.getHeight()-1)+1));
System.out.println(points.size());

try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}

}).start();
}
});


window.pack();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);

int div = 7;
int d = 4;

Path2D.Double path = new Path2D.Double();
Point2D currentPoint;
double startX, startY;
double interiorX_In, interiorY_In;
double interiorX_Out, interiorY_Out;
double endX, endY;

Graphics2D g;


while(true){

g = (Graphics2D) window.getGraphics();
g.setColor(Color.blue);

for(int i = 0; i < points.size(); i++){

currentPoint = points.get(i);
g.fillRect((int)currentPoint.getX(), (int)currentPoint.getY(), d, d);

if (i == 0){
// Don't attempt any line drawing as we don't have enough points.
path.moveTo(currentPoint.getX(), currentPoint.getY());
} else if (i == 1 && points.size() > 2){
// draw first curve with knowledge of third point (third point is not end point)
startX = points.get(i-1).getX() + (currentPoint.getX() - points.get(i-1).getX()) / div; // from start
startY = points.get(i-1).getY() + (currentPoint.getY() - points.get(i-1).getY()) / div;

interiorX_In = currentPoint.getX() - (points.get(i+1).getX() - points.get(i-1).getX()) / div; // to interior
interiorY_In = currentPoint.getY() - (points.get(i+1).getY() - points.get(i-1).getY()) / div;

path.curveTo(startX, startY, interiorX_In, interiorY_In, currentPoint.getX(), currentPoint.getY());

} else if (i == 1){ // Only 2 points in list so use a straight line until more points are available.
g.drawLine((int) points.get(i-1).getX(), (int) points.get(i-1).getY(), (int)currentPoint.getX(), (int)currentPoint.getY());
} else if (i >= 1 && i < points.size()-1){ // interior to interior edge.

interiorX_Out = points.get(i-1).getX() + (currentPoint.getX() - points.get(i-2).getX()) / div; // from interior
interiorY_Out = points.get(i-1).getY() + (currentPoint.getY() - points.get(i-2).getY()) / div;

interiorX_In = currentPoint.getX() - (points.get(i+1).getX() - points.get(i-1).getX()) / div; // to interior
interiorY_In = currentPoint.getY() - (points.get(i+1).getY() - points.get(i-1).getY()) / div;

path.curveTo(interiorX_Out, interiorY_Out, interiorX_In, interiorY_In, currentPoint.getX(), currentPoint.getY());

} else { // from interior point to end point.

interiorX_Out = points.get(i-1).getX() + (currentPoint.getX() - points.get(i-2).getX()) / div; // from interior
interiorY_Out = points.get(i-1).getY() + (currentPoint.getY() - points.get(i-2).getY()) / div;

endX = currentPoint.getX() - (currentPoint.getX() - points.get(i-1).getX()) / div; // to end
endY = currentPoint.getY() - (currentPoint.getY() - points.get(i-1).getY()) / div;

path.curveTo(interiorX_Out, interiorY_Out, endX, endY, currentPoint.getX(), currentPoint.getY());

}

} // end for

g.clearRect(0, 0, window.getWidth(), window.getHeight());
g.draw(path);
path.reset();


try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
  • 只需单击 JFrame 即可开始绘制随机点 - 控制台将报告正在绘制的点数。

我遇到的问题是一旦我向上或 60-65 个随机点路径闪烁并且似乎在屏幕上缩小并且通常表现出奇怪的行为? 正如我所说,代码可能并不完美,所以任何人都可以给我一些关于如何减少错误的指示。

我假设奇怪的行为来自每次重绘 JFrame 时构建越来越长的路径?也许有一种方法可以将路径绘制为连续的线,因为我认为路径被解释为一系列段?或者也许使路径累积而不是为运行循环的每次迭代重建整个事物?

期待提供的任何建议 - 但请尝试解释,因为我对绘画和路径等比较陌生。

提前致谢。


感谢@camickr 的帖子。这是重新编写的代码,可以完美运行,有 3,500 多个随机点,没有一个故障:

> import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Curver extends JFrame implements ActionListener, MouseListener{

public Timer animationTicker = new Timer(50, this);
public ArrayList<Point2D> points = new ArrayList<Point2D>();
private Canvas canvas;

public Curver(){
this.setPreferredSize(new Dimension(500,500));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setLayout(new BorderLayout());
canvas = new Canvas(points);
this.add(canvas, BorderLayout.CENTER);
this.addMouseListener(this);
this.pack();
this.setVisible(true);
}

class Canvas extends JPanel{

int div = 7;
int d = 4;

Path2D.Double path = new Path2D.Double();
Point2D currentPoint;
double startX, startY;
double interiorX_In, interiorY_In;
double interiorX_Out, interiorY_Out;
double endX, endY;
Graphics2D g2;
ArrayList<Point2D> points;

public Canvas(ArrayList<Point2D> points){
this.setMinimumSize(new Dimension(100,100));
this.points = points;
}

@Override
public void paintComponent(Graphics g) {

g2 = (Graphics2D) g;
g.setColor(Color.blue);

synchronized(points){
for(int i = 0; i < points.size(); i++){

currentPoint = points.get(i);
g2.fillRect((int)currentPoint.getX(), (int)currentPoint.getY(), d, d);

if (i == 0){
// Don't attempt any line drawing as we don't have enough points.
path.moveTo(currentPoint.getX(), currentPoint.getY());
} else if (i == 1 && points.size() > 2){
// draw first curve with knowledge of third point (third point is not end point)
startX = points.get(i-1).getX() + (currentPoint.getX() - points.get(i-1).getX()) / div; // from start
startY = points.get(i-1).getY() + (currentPoint.getY() - points.get(i-1).getY()) / div;

interiorX_In = currentPoint.getX() - (points.get(i+1).getX() - points.get(i-1).getX()) / div; // to interior
interiorY_In = currentPoint.getY() - (points.get(i+1).getY() - points.get(i-1).getY()) / div;

path.curveTo(startX, startY, interiorX_In, interiorY_In, currentPoint.getX(), currentPoint.getY());

} else if (i == 1){ // Only 2 points in list so use a straight line until more points are available.
g2.drawLine((int) points.get(i-1).getX(), (int) points.get(i-1).getY(), (int)currentPoint.getX(), (int)currentPoint.getY());
} else if (i >= 1 && i < points.size()-1){ // interior to interior edge.

interiorX_Out = points.get(i-1).getX() + (currentPoint.getX() - points.get(i-2).getX()) / div; // from interior
interiorY_Out = points.get(i-1).getY() + (currentPoint.getY() - points.get(i-2).getY()) / div;

interiorX_In = currentPoint.getX() - (points.get(i+1).getX() - points.get(i-1).getX()) / div; // to interior
interiorY_In = currentPoint.getY() - (points.get(i+1).getY() - points.get(i-1).getY()) / div;

path.curveTo(interiorX_Out, interiorY_Out, interiorX_In, interiorY_In, currentPoint.getX(), currentPoint.getY());

} else { // from interior point to end point.

interiorX_Out = points.get(i-1).getX() + (currentPoint.getX() - points.get(i-2).getX()) / div; // from interior
interiorY_Out = points.get(i-1).getY() + (currentPoint.getY() - points.get(i-2).getY()) / div;

endX = currentPoint.getX() - (currentPoint.getX() - points.get(i-1).getX()) / div; // to end
endY = currentPoint.getY() - (currentPoint.getY() - points.get(i-1).getY()) / div;

path.curveTo(interiorX_Out, interiorY_Out, endX, endY, currentPoint.getX(), currentPoint.getY());

}

} // end for

g.clearRect(0, 0, this.getWidth(), this.getHeight());
g2.draw(path);
path.reset();
}
}
} // end of inner class

@Override
public void actionPerformed(ActionEvent e) {
this.canvas.repaint();
}

@Override
public void mouseClicked(MouseEvent e) {
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("Thread running");
Random random = new Random();

while(true){
synchronized(points){
points.add(new Point2D.Double(random.nextInt(getWidth()-1)+1,random.nextInt(getHeight()-1)+1));
System.out.println(points.size());
}
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}

}

}

}).start();
}

@Override
public void mousePressed(MouseEvent e) {}

@Override
public void mouseReleased(MouseEvent e) {}

@Override
public void mouseEntered(MouseEvent e) {}

@Override
public void mouseExited(MouseEvent e) {}


public static void main(String[] args) {
Curver curver = new Curver();
curver.animationTicker.start();
}
}

最佳答案

g = (Graphics2D) window.getGraphics();

我没有仔细查看您的代码,但论坛建议不要使用 getGraphics() 方法进行绘画。

自定义绘画是通过覆盖 JPanel(或 JComponent)的 paintComponent() 方法来完成的。然后将面板添加到框架中。阅读 Swing 教程,了解有关自定义绘画的更多信息。

此外,不要使用“while (true)”逻辑。 Swing 将根据需要重新绘制。如果您想要某种动画,请使用 Swing Timer。

关于java - Path2D 绘制错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15884223/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com