我正在尝试做一些GIS工作。我需要能够渲染大量信息(例如,1.3M三角形,以及每个内部渲染的图形)。我在JavaFX下测试了保留模式图形,但它在这个规模上表现不佳,所以我尝试了画布。
下面的代码创建了一个平面二十面体(20边形图)并递归地将其细分为越来越小的三角形。
在递归0到4的级别(GIS.java的第36行),一切都很好。但是,一旦我去了5或者更多,我开始看到非常奇怪的画布渲染。该图呈现在y轴的右侧(对于最左边的三角形,x = 0),并且看起来在大部分中覆盖自身。
我将此代码音译为.Net并且它完美地运行(就像在递归0到4时在Java中一样)所以我不相信它是逻辑/算法问题。
提前为代码长度道歉。我剥夺了我能做的一切,但它仍然有相当数量的代码。
有两个文件 - 作为主窗体的GIS.java和HexGrid.java,它是创建网格并将其渲染到画布上的类。
另一个有趣的注意事项:HexGrid.java的第98到105行绘制红线以显示x轴和y轴。我试图看到画布认为轴的位置,因为渲染远远超出了预期的位置。如果你使用递归4或更高版本取消对第105行的gc.stroke()的注释,那么它也会炸毁画布并且渲染与预期的FAR不同。在递归3或更低时,一切都按预期执行。
我希望我做错了什么!我真的希望坚持使用JavaFX来完成这个项目。
提前致谢。
********** GIS.java *******************
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class GIS extends Application{
Pane drawPane;
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = new BorderPane();
Scene primaryScene = new Scene(root, 900, 800);
primaryStage.setScene(primaryScene);
primaryStage.setWidth(1000);
primaryStage.setHeight(700);
primaryStage.minWidthProperty().setValue(1000);
primaryStage.minHeightProperty().setValue(700);
drawPane = new Pane();
drawPane.setId("drawPane");
drawPane.setPrefSize(1000, 800);
drawPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
drawPane.setBackground(new Background(new BackgroundFill(Color.ALICEBLUE, CornerRadii.EMPTY, Insets.EMPTY)));
root.setCenter(drawPane);
HexGrid hexGrid = new HexGrid();
//LEVEL OF RECURSION
hexGrid.generate(5);
drawWorldCanvas(hexGrid);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private void drawWorldCanvas(HexGrid hexGrid) {
drawPane.getChildren().add(hexGrid.getCanvas());
}
}
***************** HexGrid.java *******************
import javafx.geometry.Point2D;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import java.io.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
public class HexGrid {
ArrayList<Point2D> _vertices = new ArrayList<>(1000);
int _index = 0;
FileWriter log;
int TRIANGLE_SIDE_LENGTH = 250;
private class TriangleFaceVertices {
public int v1; //these are indexes into the _vertices arrayList
public int v2;
public int v3;
private TriangleFaceVertices(int v1, int v2, int v3) {
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
}
}
ArrayList<TriangleFaceVertices> _faces = new ArrayList<>(1000);
public HexGrid() {
try {
log = new FileWriter("log1.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
public void generate(int recursionLevel) {
_vertices.clear();
_faces.clear();
addVertices();
addFaces();
divideTriangles(recursionLevel);
}
private void divideTriangles(int recursionLevel) {
// refine triangles
for (int i = 0; i < recursionLevel; i++)
{
ArrayList<TriangleFaceVertices> faces2 = new ArrayList<>(200000);
for (TriangleFaceVertices face: _faces)
{
// replace triangle by 4 triangles
int a = getMiddlePoint(face.v1, face.v2);
int b = getMiddlePoint(face.v2, face.v3);
int c = getMiddlePoint(face.v3, face.v1);
faces2.add(new TriangleFaceVertices(face.v1, a, c));
faces2.add(new TriangleFaceVertices(face.v2, b, a));
faces2.add(new TriangleFaceVertices(face.v3, c, b));
faces2.add(new TriangleFaceVertices(a, b, c));
}
_faces = faces2;
System.out.println(LocalDateTime.now() + " : Iteration: " + i + " - Triangle Count: " + faces2.size());
}
}
private int getMiddlePoint(int v1, int v2)
{
Point2D point1 = _vertices.get(v1);
Point2D point2 = _vertices.get(v2);
Point2D middle = new Point2D(
(point1.getX() + point2.getX()) / 2.0,
(point1.getY() + point2.getY()) / 2.0);
return addVertex(middle);
}
private int addVertex(Point2D p)
{
_vertices.add(p);
return _index++;
}
public Canvas getCanvas() {
Canvas canvas = new Canvas(5000,2000);
GraphicsContext gc = canvas.getGraphicsContext2D();
Color landColor = Color.BEIGE;
Color borderColor = Color.DARKKHAKI;
gc.setFill(landColor);
gc.setStroke(borderColor);
gc.beginPath();
gc.moveTo(0,0);
gc.lineTo(2000,0);
gc.closePath();
//gc.stroke();
for (TriangleFaceVertices face:_faces) {
gc.beginPath();
gc.moveTo(_vertices.get(face.v1).getX(), _vertices.get(face.v1).getY());
gc.lineTo(_vertices.get(face.v2).getX(), _vertices.get(face.v2).getY());
gc.lineTo(_vertices.get(face.v3).getX(), _vertices.get(face.v3).getY());
gc.lineTo(_vertices.get(face.v1).getX(), _vertices.get(face.v1).getY());
gc.closePath();
gc.stroke();
//gc.fill();
}
return canvas;
}
private void addFaces() {
_faces.add(new TriangleFaceVertices(0, 2, 1)); //creates a triangle from vertices[0], [1], and [2]
_faces.add(new TriangleFaceVertices(1, 2, 3));
_faces.add(new TriangleFaceVertices(1, 3, 4));
_faces.add(new TriangleFaceVertices(3, 5, 4));
_faces.add(new TriangleFaceVertices(1, 7, 6));
_faces.add(new TriangleFaceVertices(1, 4, 7));
_faces.add(new TriangleFaceVertices(7, 4, 8));
_faces.add(new TriangleFaceVertices(4, 9, 8));
_faces.add(new TriangleFaceVertices(10, 7, 11));
_faces.add(new TriangleFaceVertices(7, 8, 11));
_faces.add(new TriangleFaceVertices(11, 8, 12));
_faces.add(new TriangleFaceVertices(8, 13, 12));
_faces.add(new TriangleFaceVertices(14, 11, 15));
_faces.add(new TriangleFaceVertices(11, 12, 15));
_faces.add(new TriangleFaceVertices(15, 12, 16));
_faces.add(new TriangleFaceVertices(12, 17, 16));
_faces.add(new TriangleFaceVertices(18, 15, 19));
_faces.add(new TriangleFaceVertices(15, 16, 19));
_faces.add(new TriangleFaceVertices(19, 16, 20));
_faces.add(new TriangleFaceVertices(16, 21, 20));
}
private void addVertices(){
float height = (float)(Math.sqrt(3.0) / 2.0) * TRIANGLE_SIDE_LENGTH;
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH / 2.0, 0)); //0
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH, height)); //1
addVertex(new Point2D(0, height)); //2
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH / 2.0, height * 2.0)); //3
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 1.5, height * 2.0)); //4
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH, height * 3.0)); //5
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 1.5, 0)); //6
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 2.0, height)); //7
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 2.5, height * 2.0)); //8
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 2.0, height * 3.0)); //9
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 2.5, 0)); //10
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 3.0, height)); //11
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 3.5, height * 2.0)); //12
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 3.0, height * 3.0)); //13
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 3.5, 0)); //14
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 4.0, height)); //15
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 4.5, height * 2.0)); //16
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 4.0, height * 3.0)); //17
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 4.5, 0)); //18
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 5.0, height)); //19
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 5.5, height * 2.0)); //20
addVertex(new Point2D(TRIANGLE_SIDE_LENGTH * 5.0, height * 3.0)); //21
}
}
答案 0 :(得分:1)
似乎确实存在问题。您应该提交错误报告。
关于你的问题:不要使用路径,而是使用e。 G。 strokeLine
。反正它的速度更快。
复制的简单例子:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
double width = 1000;
double height = 1000;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Drawing Operations Test");
Group root = new Group();
Canvas canvas = new Canvas(width, height);
GraphicsContext gc = canvas.getGraphicsContext2D();
drawShapes(gc);
root.getChildren().add(canvas);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
private void drawShapes(GraphicsContext gc) {
double offset = 15; // <=== change this, e. g. 12
gc.setStroke(Color.BLACK);
gc.setFill(Color.BEIGE);
for( int x=0; x < width; x+=offset) {
for( int y=0; y < height; y+=offset) {
gc.setLineWidth(0.5);
gc.beginPath();
gc.moveTo(x, y);
gc.lineTo(x+offset, y+offset);
gc.closePath();
gc.stroke();
}
}
}
}
你应该得到对角线。
一旦降低偏移量,线就会消失。