gpt4 book ai didi

Java:Graphics 2d,绘制速度不够快

转载 作者:行者123 更新时间:2023-12-01 17:16:05 24 4
gpt4 key购买 nike

我正在寻找一个相当简单的方法(我所说的简单是指不需要太多代码行)来解决以下问题:

我有一个绘画应用程序。该应用程序的代码在这里:https://github.com/Tigatok/JavaProjects/tree/master/Paint2.0

这是我的问题:

如何使方形线像铅笔线一样平滑?

最佳答案

对于细线,您当前正在调用

g2D.drawLine(oldX, oldY, currentX, currentY);

而对于粗线,您只是在调用

g2D.fillRect(currentX, currentY, getXSize(), getYSize());

这意味着当您快速移动鼠标时,之前的鼠标位置和新的鼠标位置之间将没有任何联系。

一个简单的解决方案已经可以实现接近您可能想要的效果,可能是将第二个调用更改为

g2D.setStroke(new BasicStroke(getXSize()));
g2D.drawLine(oldX, oldY, currentX, currentY);

但是,您当前的绘画代码有一些可能的改进。您应该考虑根据一组 boolean 标志来决定如何绘制。相反,您可以考虑类似 Pen 接口(interface),它允许您通过使用此接口(interface)的不同实现来在不同的笔之间切换。

前面已经提到,您可以将这些点组装成 Path2D 并绘制该路径。这是一个您绝对应该考虑的好建议:它提供了一些不错的可能性。例如,您可以定义一个Stroke并创建具有任意笔形状的“描边形状”。

但是,所有这些更改可能需要大量重构,因此,到目前为止,它们只是相当模糊的建议。

<小时/>

编辑:根据评论添加了一个示例

我可以想象你想要达到什么效果。但这可能相当困难。一个至少可能接近您想要的简单解决方案可能是这样的(使用 http://www.jhlabs.com/java/java2d/strokes/ 中的类的简化版本)

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.FlatteningPathIterator;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SharpiePaintTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}

private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new SharpiePaintTestPanel());
f.setSize(1100,600);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}

class SharpiePaintTestPanel extends JPanel
{
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
g.setColor(Color.BLACK);

Path2D path = new Path2D.Double();
path.moveTo(300,300);
path.curveTo(400, 400, 400, 300, 300, 200);

g.setStroke(new ShapeStroke(new Rectangle2D.Double(0,0,3,15), 3.0f));
g.draw(path);
}
}

// Based on http://www.jhlabs.com/java/java2d/strokes/ShapeStroke.java,
// only slightly simplified
class ShapeStroke implements Stroke {
private Shape shape;
private float advance;
private static final float FLATNESS = 1;

public ShapeStroke(Shape shape, float advance ) {
this.advance = advance;
Rectangle2D bounds = shape.getBounds2D();
this.shape = AffineTransform.getTranslateInstance(
-bounds.getCenterX(), -bounds.getCenterY()).createTransformedShape(shape);
}

@Override
public Shape createStrokedShape( Shape shape ) {
GeneralPath result = new GeneralPath();
PathIterator it = new FlatteningPathIterator( shape.getPathIterator( null ), FLATNESS );
float points[] = new float[6];
float moveX = 0, moveY = 0;
float lastX = 0, lastY = 0;
float thisX = 0, thisY = 0;
int type = 0;
float next = 0;
while (!it.isDone() ) {
type = it.currentSegment( points );
switch( type ){
case PathIterator.SEG_MOVETO:
moveX = lastX = points[0];
moveY = lastY = points[1];
result.moveTo( moveX, moveY );
next = 0;
break;

case PathIterator.SEG_CLOSE:
points[0] = moveX;
points[1] = moveY;
// Fall into....

case PathIterator.SEG_LINETO:
thisX = points[0];
thisY = points[1];
float dx = thisX-lastX;
float dy = thisY-lastY;
float distance = (float)Math.sqrt( dx*dx + dy*dy );
if ( distance >= next ) {
float r = 1.0f/distance;
while (distance >= next ) {
float x = lastX + next*dx*r;
float y = lastY + next*dy*r;
AffineTransform t = new AffineTransform();
t.setToTranslation( x, y );
result.append( t.createTransformedShape(this.shape), false );
next += advance;
}
}
next -= distance;
lastX = thisX;
lastY = thisY;
break;
}
it.next();
}

return result;
}

}

关于Java:Graphics 2d,绘制速度不够快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22060601/

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