简体   繁体   English

在Java中使用jzy3d绘制3D表面

[英]Using jzy3d to plot 3D surface in Java

I have a tab-delimited CSV file that has a header, and its first column are labels for each row. 我有一个制表符分隔的CSV文件,该文件具有标题,其第一列是每一行的标签。 For example. 例如。

Label   Sample1   Sample2    Sample3    Sample4    Sample5
U.S.A.    10.1      3.2       5.6       6.9       7.3
Canada    9.8       4.5       5.7       6.8       7.9 

I use superCSV to parse this CSV file and create polygons for each point, for example: (1, 1, 10.1) [meaning first row, first column]. 我使用superCSV解析此CSV文件并为每个点创建多边形,例如:(1、1、10.1)[表示第一行,第一列]。 The points are added to a list of polygons. 这些点将添加到多边形列表中。 I then use the polygons to create a surface, but the surface is not continuous. 然后,我使用多边形创建一个曲面,但是该曲面不是连续的。 I have attached a screenshot of my plotting 我已附上我的绘图屏幕截图

在此处输入图片说明

Part of my code is as follows: 我的部分代码如下:

public void init() {


        /* build a list of polygons out of the CSV file */
        List<Polygon> polygons = null;
        try {
            polygons = parseCSV("my_CSVFile.csv");
        } catch (IOException e) {
            e.printStackTrace();
        }


        System.out.println("size of polygons is: " + polygons.size());


        // Creates the 3d object
        Shape surface = new Shape(polygons);
        surface.setColorMapper(new ColorMapper(new ColorMapRainbow(), surface.getBounds().getZmin(), surface.getBounds().getZmax(), new org.jzy3d.colors.Color(1,1,1,1f)));
        surface.setWireframeDisplayed(true);
        surface.setWireframeColor(org.jzy3d.colors.Color.BLACK);

        chart = AWTChartComponentFactory.chart(Quality.Advanced, getCanvasType());
//        chart = new Chart();
        chart.getScene().getGraph().add(surface);
    }

    public List<Polygon> parseCSV(String csvFile) throws IOException
    {
        if (csvFile.isEmpty())
            System.exit(-1);

        File inputFile = new File(csvFile);
        String[] header = null;  /* header row */

        if (inputFile.exists())
        {
            FileReader fr = new FileReader(inputFile);
            LineNumberReader lineReader = new LineNumberReader(fr);
            String headerLine = null;

            while (lineReader.getLineNumber() == 0)
            {
                headerLine = lineReader.readLine();
            }
            lineReader.close();


            if (headerLine != null)
            {
                header = headerLine.split("\\t");
            }

        }

        ICsvListReader listReader = null;
        List<Polygon> polygons = new ArrayList<Polygon>();

        try {
            listReader = new CsvListReader(new FileReader(csvFile), CsvPreference.TAB_PREFERENCE);
            listReader.getHeader(true);

            List<String> contentList;
            int rowIndex = 1;           // excluding the header row
            while((contentList = listReader.read()) != null)
            {
                if (contentList.size() != header.length) {
                    System.out.println("contentList size is: " + contentList.size() + ", header length is: " + header.length);
                    continue;
                }

                Polygon polygon = new Polygon();
                for (int i = 1; i < contentList.size(); i++)
                {
                    if (DoubleFactory.tryParseDouble(contentList.get(i)) != -1)  /* unsuccessful double parse returns -1 */
                    {
                        polygon.add(new Point(new Coord3d(rowIndex, i, Double.parseDouble(contentList.get(i)))));
                    }
                }
                rowIndex++;
                polygons.add(polygon);
            }


        } finally {
            if(listReader != null) {
                listReader.close();
            }
        }

        return polygons;

    }

    /* inner class for parsing string to double */
    private static class DoubleFactory
    {
        public static double tryParseDouble(final String number)
        {
            double result;
            try {
                result = Double.parseDouble(number);
            } catch (NumberFormatException e) {
                result = -1;  /* default failed parsing*/
            }

            return result;
        }
    }

I need help with creating a continuous smooth 3D surface out of my CSV contents (the numbers) 我需要帮助以CSV内容(数字)创建连续的平滑3D曲面

My code for creating the polygon list is as follows 我创建多边形列表的代码如下

List<Polygon> polygons = new ArrayList<Polygon>();
for (int i = 0; i < m_data.rows-k; i++) {
    for (int j = 0; j < m_data.columns-k; j++) {
        Polygon polygon = new Polygon();
        polygon.add(new Point(new Coord3d(i,  j,  m_data.get(i,  j  ))));
        polygon.add(new Point(new Coord3d(i+1,j,  m_data.get(i+1,j  ))));
        polygon.add(new Point(new Coord3d(i+1,j+1,m_data.get(i+1,j+1))));
        polygon.add(new Point(new Coord3d(i,  j+1,m_data.get(i,  j+1))));
        polygons.add(polygon);
    }
}

where m_data is a class variable and a matrix. 其中, m_data是类变量和矩阵。 As far as I know, this is the way you should create a polygon. 据我所知,这就是创建多边形的方式。 A polygon only consisting of a single point seems rather unlikely to be correct. 仅包含一个点的多边形似乎不太可能是正确的。


Related question: Build a 3d surface plot using xyz coordinates with jzy3d 相关问题: 使用带有jzy3d的xyz坐标构建3d表面图

When you draw a polygon, it will connect the vertices in the order that you've added them. 绘制多边形时,它将按照添加顶点的顺序连接顶点。 Look at the lines on your plot - they go from one point to the next, jumping from the end of one row to the beginning of the next. 查看图中的线条-它们从一个点到下一个,从一行的结尾跳到下一行的起点。

What you want is a surface. 您想要的是表面。 I am not familiar with jzy3d, but there should be some built-in surface generators where you can just add all your points and ask it to return a surface. 我对jzy3d并不熟悉,但是应该有一些内置的表面生成器,您可以在其中添加所有点并要求它返回表面。 If not, you just have to connect groups of 3 (triangles) or 4 (quads) vertices and draw a polygon with them as Didii coded for you already. 如果没有,您只需要连接3个(三角形)或4个(方形)顶点的组,并按照Didii为您编写的代码绘制一个多边形。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM