在Java中结合区域时舍入不准确? [英] Rounding Inaccuracies When Combining Areas in Java?
问题描述
我正在Java中使用 Areas
。
我的测试程序绘制三个随机三角形并将它们结合以形成一个或多个多边形。在 有时候, 我认为问题是由四舍五入在Java的 任何解决方案? 示例代码和图片: 成功案例: 失败的案例: 这里: 实际上你在第一个循环中添加了 这是您的不准确之处。试试看看你的问题是否仍然存在。 请注意每个循环后重置的路径。 编辑:解释更多错误来自这里的三条路径,您尝试合并。这使得它明显可能出现错误。 I'm working with My test program draws three random triangles and combines them to form one or more polygons. After the Sometimes, however, the I think the problem is caused by rounding inaccuracies in Java's Any solutions? Example code and images: A successful case: A failing case: Here: you are adding in fact
1 triangle in the first loop
2 triangles in the second loop
3 triangles in the third loop This is where your inaccuracies come from. Try this and see if your problem still persists. Note the path reset after each loop. EDIT: to explain more where the inaccuracies come from here the three paths you try to combine. Which makes it obvious where errors might arise. 这篇关于在Java中结合区域时舍入不准确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! Areas
是 .add()
编辑在一起后,我使用 PathIterator $ c
Area
对象不会像他们应该那样组合。 ..正如你在我发布的最后一张图片中看到的那样,额外的边缘将被绘制出来。
Area
类中有错误(当我调试测试程序时, Area
显示 PathIterator
),但我不认为Java提供任何其他方式来组合形状。
import java .awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
public class AreaTest extends JFrame {
private static final long serialVersionUID = -2221432546854106311L;
面积= new Area();
ArrayList< Line2D.Double> areaSegments = new ArrayList< Line2D.Double>();
AreaTest(){
Path2D.Double triangle = new Path2D.Double();
Random random = new Random();
//绘制三个随机三角形
(int i = 0; i <3; i ++){
triangle.moveTo(random.nextInt(400)+ 50, random.nextInt(400)+ 50);
triangle.lineTo(random.nextInt(400)+ 50,random.nextInt(400)+ 50);
triangle.lineTo(random.nextInt(400)+ 50,random.nextInt(400)+ 50);
triangle.closePath();
area.add(新区域(三角形));
}
//注意:我们存储double []而不是Point2D.Double
ArrayList< double []> areaPoints = new ArrayList< double []>();
double [] coords = new double [6];
for(PathIterator pi = area.getPathIterator(null);!pi.isDone(); pi.next()){
//由于区域由直线
int type = pi.currentSegment(coords);
//我们记录一个{segment type,x coord,y coord}的双数组$ {
double [] pathIteratorCoords = {type,coords [0],coords [1]};
areaPoints.add(pathIteratorCoords);
}
double [] start = new double [3]; //记录每个多边形的起始位置
for(int i = 0; i< areaPoints.size(); i ++){
//如果我们不在最后一点,返回一行从这一点到下一个
double [] currentElement = areaPoints.get(i);
//我们需要一个默认值来防止我们到达ArrayList的末尾
double [] nextElement = {-1,-1,-1};
if(i< areaPoints.size() - 1){
nextElement = areaPoints.get(i + 1);
}
//使行
if(currentElement [0] == PathIterator.SEG_MOVETO){
start = currentElement; //记录多边形在哪里开始关闭它
}
if(nextElement [0] == PathIterator.SEG_LINETO){
areaSegments.add(
new Line2D.Double(
currentElement [1],currentElement [2],
nextElement [1],nextElement [2]
)
);
} else if(nextElement [0] == PathIterator.SEG_CLOSE){
areaSegments.add(
new Line2D.Double(
currentElement [1],currentElement [2],
start [1],start [2]
)
);
}
}
setSize(new Dimension(500,500));
setLocationRelativeTo(null); //将JFrame放在屏幕上
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
public void paint(Graphics g){
//填充区域
Graphics2D g2d =(Graphics2D)g;
g.setColor(Color.lightGray);
g2d.fill(area);
//逐行绘制边框
g.setColor(Color.black); (Line2D.Double line:areaSegments){
g2d.draw(line);
public static void main(String [] args){
new AreaTest();
$ / code>
for(int i = 0; i <3; i ++){
triangle.moveTo(random.nextInt(400)+50,random.nextInt(400)+50);
triangle.lineTo(random.nextInt(400)+ 50,random.nextInt(400)+ 50);
triangle.lineTo(random.nextInt(400)+ 50,random.nextInt(400)+ 50);
triangle.closePath();
area.add(新区域(三角形));
$ b $ p
$ b
1三角形
2个三角形在第二个循环中
3个三角形在第三个循环中
for(int i = 0; i <3; i ++){
triangle.moveTo(random.nextInt(400)+50,random.nextInt(400)+50);
triangle.lineTo(random.nextInt(400)+ 50,random.nextInt(400)+ 50);
triangle.lineTo(random.nextInt(400)+ 50,random.nextInt(400)+ 50);
triangle.closePath();
area.add(新区域(三角形));
triangle.reset();
}
Areas
in Java.Areas
are .add()
ed together, I use PathIterator
to trace the edges.Area
objects will not combine as they should... and as you can see in the last image I posted, extra edges will be drawn.Area
class (when I debug the test program, the Area
shows the gaps before the PathIterator
is used), but I don't think Java provides any other way to combine shapes.import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
public class AreaTest extends JFrame{
private static final long serialVersionUID = -2221432546854106311L;
Area area = new Area();
ArrayList<Line2D.Double> areaSegments = new ArrayList<Line2D.Double>();
AreaTest() {
Path2D.Double triangle = new Path2D.Double();
Random random = new Random();
// Draw three random triangles
for (int i = 0; i < 3; i++) {
triangle.moveTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
triangle.lineTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
triangle.lineTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
triangle.closePath();
area.add(new Area(triangle));
}
// Note: we're storing double[] and not Point2D.Double
ArrayList<double[]> areaPoints = new ArrayList<double[]>();
double[] coords = new double[6];
for (PathIterator pi = area.getPathIterator(null); !pi.isDone(); pi.next()) {
// Because the Area is composed of straight lines
int type = pi.currentSegment(coords);
// We record a double array of {segment type, x coord, y coord}
double[] pathIteratorCoords = {type, coords[0], coords[1]};
areaPoints.add(pathIteratorCoords);
}
double[] start = new double[3]; // To record where each polygon starts
for (int i = 0; i < areaPoints.size(); i++) {
// If we're not on the last point, return a line from this point to the next
double[] currentElement = areaPoints.get(i);
// We need a default value in case we've reached the end of the ArrayList
double[] nextElement = {-1, -1, -1};
if (i < areaPoints.size() - 1) {
nextElement = areaPoints.get(i + 1);
}
// Make the lines
if (currentElement[0] == PathIterator.SEG_MOVETO) {
start = currentElement; // Record where the polygon started to close it later
}
if (nextElement[0] == PathIterator.SEG_LINETO) {
areaSegments.add(
new Line2D.Double(
currentElement[1], currentElement[2],
nextElement[1], nextElement[2]
)
);
} else if (nextElement[0] == PathIterator.SEG_CLOSE) {
areaSegments.add(
new Line2D.Double(
currentElement[1], currentElement[2],
start[1], start[2]
)
);
}
}
setSize(new Dimension(500, 500));
setLocationRelativeTo(null); // To center the JFrame on screen
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
}
public void paint(Graphics g) {
// Fill the area
Graphics2D g2d = (Graphics2D) g;
g.setColor(Color.lightGray);
g2d.fill(area);
// Draw the border line by line
g.setColor(Color.black);
for (Line2D.Double line : areaSegments) {
g2d.draw(line);
}
}
public static void main(String[] args) {
new AreaTest();
}
}
for (int i = 0; i < 3; i++) {
triangle.moveTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
triangle.lineTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
triangle.lineTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
triangle.closePath();
area.add(new Area(triangle));
}
for (int i = 0; i < 3; i++) {
triangle.moveTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
triangle.lineTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
triangle.lineTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
triangle.closePath();
area.add(new Area(triangle));
triangle.reset();
}