我正在制作一个基本的Java程序,我想使用基本的swing Graphics.drawLine绘制一条线.
有没有办法根据双打来制作两个点,这样我可以使输出更准确,或者更好的另一种方式?
我之前从未使用过Java绘图方法,所以我决定潜入并创建一个模拟时钟作为PoC.除了手之外,我画了一个钟面,包括刻度标记,分钟/小时.我使用简单的sin/cos计算来确定圆周线的位置.
但是,我注意到由于分钟刻度非常短,因此线条的角度看起来不对.我确定这是因为两者Graphics2D.drawLine()和Line2D.double()方法都无法以亚像素精度绘制.
我知道我可以画出来自中心的线条并用圆圈遮住它(以创建更长,更准确的线条),但这似乎是一种不那么优雅和昂贵的解决方案.我已经做过一些关于如何做到这一点的研究,但我遇到的最好的答案是使用一个AffineTransform.我假设我只能使用AffineTransformwith旋转,而不是必须执行超级采样.
这是以亚像素精度绘制的唯一/最佳方法吗?或者是否有更快的解决方案?
编辑:我已经设置RenderingHint的Graphics2D对象.
根据要求,这里有一些代码(没有完全优化,因为这只是一个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) …Run Code Online (Sandbox Code Playgroud) 我需要一种比Bresenham线绘制算法慢一点的算法,但必须更精确.使用'exact'我的意思是:应该打印每个触摸的像素.不多也不少!这意味着使用更粗的线或类似物不是一种选择,因为将涉及太多的像素.此外,我并不需要一个图形框架或类似就像是问 之前,我需要的算法!应用程序实际上不是"图形",它位于像素为"图块" 的地理区域.
对我来说主要的问题是我需要子像素精度,这意味着一条线可以从0.75/0.33开始,而不仅仅是0/0,就像整数值的情况一样.我尝试在过去几个小时内创建一个可行的解决方案,但无法使其正常工作 - 边缘情况太多了.
首先,我认为抗锯齿的版本就像从算法吴应,但它打印像素过多(尤其是起点和终点),并在某些情况下,还惦记着,例如在非常短的线条一些像素.
然后我试着让Bresenham在我用'else if'取代第二个'if'的地方工作,这里指出了它,但它更接近但仍然不存在.然后我尝试将Bresenham从整数移动到浮点精度,这导致无限循环(因为x,y值跳过完成条件if (y1 == y2 && x1 == x2)).
我可以使用天真的线条绘图解决方案,但delta我应该使用哪个?例如,如果我使用0.1,我仍然会错过一些像素并使用较小的值,它可能会花费太长时间(仍然会错过像素).
C/Java/...中的工作解决方案将不胜感激.至少它应该适用于八分之一,但一个完整的解决方案会更好.
更新:我提出了以下想法:使用朴素行光栅化,您可以为每个点计算4个像素候选.然后检查这4个像素,如果该线真正穿过它们.但我不确定线/盒交叉点是否足够快.