Java Swing BasicStroke“;“第;不适用于零度角

Java Swing BasicStroke“;“第;不适用于零度角,java,swing,graphics2d,stroke,Java,Swing,Graphics2d,Stroke,这个问题是我不久前提出的一个问题的后续问题: 经过实验,我发现了一些行为,可能是有意的,也可能是一个bug,但这两种方式都不是我想要的。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 j

这个问题是我不久前提出的一个问题的后续问题:

经过实验,我发现了一些行为,可能是有意的,也可能是一个bug,但这两种方式都不是我想要的。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);
    }
}
通过使用line
path.lineTo(100,50)

基本上,我正在绘制一个
GeneralPath
,每个图像中的角度略微减小。最终(在下图中)角度达到零。在这种情况下,将不再绘制圆形“连接”。这有点道理,但有点不通。我不确定这是不是有意的。有趣的是,如果将角度更改为略大于0的(即,将上面引用的线更改为
path.lineTo(100,99.999);
将再次绘制圆角


在我的应用程序中,路径可能会自身重复(即创建零度角),在这种情况下,在这种情况下绘制连接循环在美学上更具吸引力。我有没有办法破解Java源代码来实现这一点?

我不知道如何破解源代码,但您可以通过只绘制一行代码来定制代码来解释这种行为:

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);
我画的路径非常长,有500多个点,检查每个“子路径”会给我的绘制方法增加很多开销

不要在paint方法中构建GeneralPath。您可以使用一个包装类,该类将在添加每个点时对其进行过滤。这里的代码将在每次添加点时比较线的坡度。当坡度相同时,将为添加
线到
之前的最后一个点生成
移动到
。这将使圆冲程生成:

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();
        }
    }
}
import java.awt.*;
导入java.awt.Color;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.RenderingHints;
导入java.awt.geom.*;
导入java.util.List;
导入java.util.ArrayList;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公开课考试{
私有JFrame;
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
公开募捐{
试一试{
CornerTest窗口=新的CornerTest();
window.frame.setVisible(true);
}捕获(例外e){
e、 printStackTrace();
}
}
});
}
公共交通测试(){
初始化();
}
私有void初始化(){
frame=新的JFrame();
框架.立根(100100450450);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
最终GeneralPath gp=新的GeneralPath();
MyGeneralPath路径=新的MyGeneralPath(gp);
路径移动到(100100);
线路图(200100);
线路图(100,50);
//线路图(50100);
path.flush();
JPanel面板=新的JPanel(){
受保护组件(图形g){
Graphics2D g2d=(Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_抗锯齿,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.调整行程(新的基本行程(15.5f,基本行程.盖轮,基本行程.连接轮));
g2d.setColor(Color.BLACK);
g2d.绘图(gp);
}
};
框架。背景(颜色。青色);
框架。添加(面板);
}
静态类MyGeneralPath
{
专用通用路径;
私有列表点=新的ArrayList();
公共MyGeneralPath(GeneralPath路径)
{
this.path=path;
}
公共无效移动到(双x,双y)
{
冲洗();
添加(新的Point2D.Double(x,y));
}
公用空心线条(双x,双y)
{
Point2D.Double point=新的Point2D.Double(x,y);
检查坡度(点);
点。添加(点);
}
专用空心检查坡度(点2D.Double p3)
{
int size=points.size();
如果(尺寸<2)
返回;
Point2D.Double p2=points.get(大小-1);
Point2D.Double p1=points.get(大小-2);
双斜率1=(p2.getY()-p1.getY())/(p2.getX()-p1.getX());
双斜率2=(p3.getY()-p2.getY())/(p3.getX()-p2.getX());
如果(slope1==slope2)
moveTo(p2.getX(),p2.getY());
}
公共图书馆
{
int size=points.size();
如果(大小==0)
返回;
Point2D.Double point=points.get(0);
moveTo(point.getX(),point.getY());
对于(int i=1;i
是的,我也想过类似的事情,但在我的真实应用程序中,我绘制了500多个点的非常长的路径,检查每个“子路径”会给我的绘制方法增加很多开销看看它是否有一个切换。尽管它最终可能是最好的选择。感谢您的输入。感谢您的精心设计。我的路径变化非常频繁,只需在
paint
方法中不断计算它就可以了。无论如何,运行这些计算并不像我想象的那么痛苦。您gh你的斜率比较比我之前做的毕达哥拉斯曲线更容易计算。我在三次/二次曲线上遇到了一个类似的问题。我画了一些很小的曲线,它们几乎只有一个点,只是缺少了一个大写字母,看起来像一个大圆点