这个问题是我前一段时间提出的问题的后续问题: Drawing a bordered path with sharp corners in Java
经过实验,我发现了一些可能有意或可能是错误的行为,但我不希望这两种方式。 SSCCE:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CornerTest {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CornerTest window = new CornerTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CornerTest() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel() {
protected void paintComponent(Graphics g) {
GeneralPath path;
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(15.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.setColor(Color.BLACK);
path = new GeneralPath();
path.moveTo(100, 100);
path.lineTo(200, 100);
path.lineTo(100, 50);
g2d.draw(path);
}
};
frame.setBackground(Color.CYAN);
frame.add(panel);
}
}
通过取path.lineTo(100, 50);
行并使用第二个参数,我们可以改变绘制路径的角度。有关各种示例,请参见下图。
基本上,我正在绘制GeneralPath
,每个图像的角度略微减小。最终(在底部图像中)角度达到零。在这种情况下,圆形的“连接”不再被绘制。这种方式有道理,但有点不然。我不确定它是否有意。有趣的是,如果您将角度更改为略微大于0(即通过将上面引用的行更改为path.lineTo(100, 99.999);
,则会再次绘制圆角。
在我的应用中,路径可以自身加倍(即创建零度角),并且在这种情况下,在这种情况下绘制连接轮在美学上更具吸引力。有什么方法可以破解Java源代码来实现这个目的吗?
答案 0 :(得分:2)
不知道攻击源代码,但您可以通过绘制一行来自定义代码以解决此问题:
path = new GeneralPath();
path.moveTo(100, 100);
path.lineTo(200, 100);
path.lineTo(50, 100);
Rectangle bounds = path.getBounds();
if (bounds.height == 0)
{
path = new GeneralPath();
path.moveTo(bounds.x, bounds.y);
path.lineTo(bounds.x + bounds.width, bounds.y);
}
if (bounds.width == 0)
{
path = new GeneralPath();
path.moveTo(bounds.x, bounds.y);
path.lineTo(bounds.x, bounds.y + bounds.height);
}
g2d.draw(path);
答案 1 :(得分:2)
我正在用500+点绘制很长的路径,这会给我的绘制方法增加很多开销,以检查每个“子路径”
不要在paint方法中构建GeneralPath。您可以使用一个包装类,它将在添加时过滤每个点。这里的代码将比较每次要添加一个点时线的斜率。当斜率相同时,在添加moveTo
之前的最后一个点生成lineTo
。这将导致生成圆形笔划:
import java.awt.*;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CornerTest {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CornerTest window = new CornerTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CornerTest() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 450);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final GeneralPath gp = new GeneralPath();
MyGeneralPath path = new MyGeneralPath(gp);
path.moveTo(100, 100);
path.lineTo(200, 100);
path.lineTo(100, 50);
// path.lineTo(50, 100);
path.flush();
JPanel panel = new JPanel() {
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(15.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.setColor(Color.BLACK);
g2d.draw(gp);
}
};
frame.setBackground(Color.CYAN);
frame.add(panel);
}
static class MyGeneralPath
{
private GeneralPath path;
private List<Point2D.Double> points = new ArrayList<Point2D.Double>();
public MyGeneralPath(GeneralPath path)
{
this.path = path;
}
public void moveTo(double x, double y)
{
flush();
points.add( new Point2D.Double(x, y) );
}
public void lineTo(double x, double y)
{
Point2D.Double point = new Point2D.Double(x, y);
checkSlope(point);
points.add( point );
}
private void checkSlope(Point2D.Double p3)
{
int size = points.size();
if (size < 2 )
return;
Point2D.Double p2 = points.get(size - 1);
Point2D.Double p1 = points.get(size - 2);
double slope1 = (p2.getY() - p1.getY()) / (p2.getX() - p1.getX());
double slope2 = (p3.getY() - p2.getY()) / (p3.getX() - p2.getX());
if (slope1 == slope2)
moveTo(p2.getX(), p2.getY());
}
public void flush()
{
int size = points.size();
if (size == 0)
return;
Point2D.Double point = points.get(0);
path.moveTo(point.getX(), point.getY());
for (int i = 1; i < size; i++)
{
point = points.get(i);
path.lineTo(point.getX(), point.getY());
}
points.clear();
}
}
}