gpt4 book ai didi

Java - 亚像素线精度是否需要 AffineTransform?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:19:07 24 4
gpt4 key购买 nike

我以前从未使用过 Java 绘图方法,所以我决定深入研究并创建一个模拟时钟作为 PoC。除了指针之外,我还绘制了一个钟面,其中包含分钟/小时的刻度线。我使用简单的 sin/cos 计算来确定圆周线的位置。

但是,我注意到由于分钟刻度线非常短,所以线条的角度看起来不对。我敢肯定这是因为 Graphics2D.drawLine()Line2D.double() 方法都无法以亚像素精度进行绘制。

我知道我可以从中心画线并用圆圈遮盖它(以创建更长、更准确的线),但这似乎是一种不优雅且成本高昂的解决方案。我已经对如何执行此操作进行了一些研究,但我遇到的最佳答案是使用 AffineTransform。我假设我可以使用仅具有旋转功能的 AffineTransform,而不是必须执行 super 采样。

这是唯一/最好的亚像素精度绘图方法吗?或者是否有可能更快的解决方案?

编辑:我已经为 Graphics2D 对象设置了一个 RenderingHint

根据要求,这里有一些代码(没有完全优化,因为这只是一个 PoC):

diameter = Math.max(Math.min(pnlOuter.getSize().getWidth(),
pnlOuter.getSize().getHeight()) - 2, MIN_DIAMETER);

for (double radTick = 0d; radTick < 360d; radTick += 6d) {
g2d.draw(new Line2D.Double(
(diameter / 2) + (Math.cos(Math.toRadians(radTick))) * diameter / 2.1d,
(diameter / 2) + (Math.sin(Math.toRadians(radTick))) * diameter / 2.1d,
(diameter / 2) + (Math.cos(Math.toRadians(radTick))) * diameter / 2.05d,
(diameter / 2) + (Math.sin(Math.toRadians(radTick))) * diameter / 2.05d));
} // End for(radTick)

这是绘图的屏幕截图。可能有点难看,但是看59分钟的刻度线。它是完全垂直的。

Sample image

最佳答案

Line2D.double() methods cannot draw with subpixel accuracy.

错误,使用RenderingHints.VALUE_STROKE_PURE Graphics2D 对象可以绘制形状为 Line2D 的“亚像素”精度。


I assume I could use an AffineTransform with rotation only, as opposed to having to perform a supersampling. Is this the only/best method of drawing with sub-pixel accuracy? Or is there a potentially faster solution?

我认为您在这里遗漏了一些东西。 Graphics2D 对象已经拥有一个 AffineTransform 并将其用于所有 绘图操作及其廉价的性能。


但是为了让您了解您的代码中缺少的内容 - 这是缺少的:

g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);

下面是生成此图片的独立示例:

screenshot

public static void main(String[] args) throws Exception {

final JFrame frame = new JFrame("Test");

frame.add(new JComponent() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);

Graphics2D g2d = (Graphics2D) g;

System.out.println(g2d.getTransform());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);

double dia = Math.min(getWidth(), getHeight()) - 2;

for (int i = 0; i < 60 ; i++) {
double angle = 2 * Math.PI * i / 60;
g2d.draw(new Line2D.Double(
(dia / 2) + Math.cos(angle) * dia / 2.1d,
(dia / 2) + Math.sin(angle) * dia / 2.1d,
(dia / 2) + Math.cos(angle) * dia / 2.05d,
(dia / 2) + Math.sin(angle) * dia / 2.05d));
}

g2d.draw(new Ellipse2D.Double(1, 1, dia - 1, dia - 1));
}
});

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}

关于Java - 亚像素线精度是否需要 AffineTransform?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5018635/

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