生成等值线的java代码

最近需要做一个生成等值线的组件,看了一些资料,等值线的构造主要可分为两种方法,一是构造三角形,二是构造网格正方形。研究了一下,看到了一个很好的算法,先贴出来,等过两天做出组件来了再具体讨论,也希望有想法或者类似经验的朋友跟贴讨论。

 程序代码

package cn.edu.xaut.transfer.end;

public class Conrec {

    private double  []  h   =  new double [5];
    private int     []  sh  =  new int    [5];
    private double  []  xh  =  new double [5];
    private double  []  yh  =  new double [5];
    
    // Object that knows how to draw the contour
    private Render render = null;

    /** Creates new Conrec */
    public  Conrec(Render render) throws Exception {
        if (render == null){
            throw new Exception ("Render null");
        }
        this.render = render;
    }
    

    /**
     *     contour is a contouring subroutine for rectangularily spaced data
     *
     *     It emits calls to a line drawing subroutine supplied by the user
     *     which draws a contour map corresponding to real*4data on a randomly
     *     spaced rectangular grid. The coordinates emitted are in the same
     *     units given in the x() and y() arrays.
     *
     *     Any number of contour levels may be specified but they must be
     *     in order of increasing value.
     *
     *
     * @param d  - matrix of data to contour
     * @param ilb,iub,jlb,jub - index bounds of data matrix
     *
     *             The following two, one dimensional arrays (x and y) contain the horizontal and
     *             vertical coordinates of each sample points.
     * @param x  - data matrix column coordinates
     * @param y  - data matrix row coordinates
     * @param nc - number of contour levels
     * @param z  - contour levels in increasing order.
     *
     */
    public void contour(double [][] d, int ilb, int iub, int jlb, int jub, double [] x, double [] y, int nc, double [] z) {
        int         m1;
        int         m2;
        int         m3;
        int         case_value;
        double      dmin;
        double      dmax;
        double      x1 = 0.0;
        double      x2 = 0.0;
        double      y1 = 0.0;
        double      y2 = 0.0;
        int         i,j,k,m;
      
        // The indexing of im and jm should be noted as it has to start from zero
        // unlike the fortran counter part
        int     [] im   = {0,1,1,0};
        int     [] jm   = {0,0,1,1};
        
        // Note that castab is arranged differently from the FORTRAN code because
        // Fortran and C/C++ arrays are transposed of each other, in this case
        // it is more tricky as castab is in 3 dimension
        int [][][] castab=
        {
            {
                {0,0,8},{0,2,5},{7,6,9}
            },
            {
                {0,3,4},{1,3,1},{4,3,0}
            },
            {
                {9,6,7},{5,2,0},{8,0,0}
            }
        };
        
        for (j=(jub-1);j>=jlb;j--) {
            for (i=ilb;i<=iub-1;i++) {
                double temp1,temp2;
                temp1 = Math.min(d[i][j],d[i][j+1]);
                temp2 = Math.min(d[i+1][j],d[i+1][j+1]);
                dmin  = Math.min(temp1,temp2);
                temp1 = Math.max(d[i][j],d[i][j+1]);
                temp2 = Math.max(d[i+1][j],d[i+1][j+1]);
                dmax  = Math.max(temp1,temp2);
                
                if (dmax>=z[0]&&dmin<=z[nc-1]) {
                    for (k=0;k<nc;k++) {
                        if (z[k]>=dmin&&z[k]<=dmax) {
                            for (m=4;m>=0;m--) {
                                if (m>0) {
                                    // The indexing of im and jm should be noted as it has to
                                    // start from zero
                                    h[m] = d[i+im[m-1]][j+jm[m-1]]-z[k];
                                    xh[m] = x[i+im[m-1]];
                                    yh[m] = y[j+jm[m-1]];
                                } else {
                                    h[0] = 0.25*(h[1]+h[2]+h[3]+h[4]);
                                    xh[0]=0.5*(x[i]+x[i+1]);
                                    yh[0]=0.5*(y[j]+y[j+1]);
                                }
                                if (h[m]>0.0) {
                                    sh[m] = 1;
                                } else if (h[m]<0.0) {
                                    sh[m] = -1;
                                } else
                                    sh[m] = 0;
                            }
                            //
                            // Note: at this stage the relative heights of the corners and the
                            // centre are in the h array, and the corresponding coordinates are
                            // in the xh and yh arrays. The centre of the box is indexed by 0
                            // and the 4 corners by 1 to 4 as shown below.
                            // Each triangle is then indexed by the parameter m, and the 3
                            // vertices of each triangle are indexed by parameters m1,m2,and
                            // m3.
                            // It is assumed that the centre of the box is always vertex 2
                            // though this isimportant only when all 3 vertices lie exactly on
                            // the same contour level, in which case only the side of the box
                            // is drawn.
                            //
                            //
                            //      vertex 4 +-------------------+ vertex 3
                            //               | /               / |
                            //               |   /    m-3    /   |
                            //               |     /       /     |
                            //               |       /   /       |
                            //               |  m=2    X   m=2   |       the centre is vertex 0
                            //               |       /   /       |
                            //               |     /       /     |
                            //               |   /    m=1    /   |
                            //               | /               / |
                            //      vertex 1 +-------------------+ vertex 2
                            //
                            //
                            //
                            //               Scan each triangle in the box
                            //
                            for (m=1;m<=4;m++) {
                                m1 = m;
                                m2 = 0;
                                if (m!=4) {
                                    m3 = m+1;
                                } else {
                                    m3 = 1;
                                }
                                case_value = castab[sh[m1]+1][sh[m2]+1][sh[m3]+1];
                                if (case_value!=0) {
                                    switch (case_value) {
                                        case 1: // Line between vertices 1 and 2
                                            x1=xh[m1];
                                            y1=yh[m1];
                                            x2=xh[m2];
                                            y2=yh[m2];
                                            break;
                                        case 2: // Line between vertices 2 and 3
                                            x1=xh[m2];
                                            y1=yh[m2];
                                            x2=xh[m3];
                                            y2=yh[m3];
                                            break;
                                        case 3: // Line between vertices 3 and 1
                                            x1=xh[m3];
                                            y1=yh[m3];
                                            x2=xh[m1];
                                            y2=yh[m1];
                                            break;
                                        case 4: // Line between vertex 1 and side 2-3
                                            x1=xh[m1];
                                            y1=yh[m1];
                                            x2=xsect(m2,m3);
                                            y2=ysect(m2,m3);
                                            break;
                                        case 5: // Line between vertex 2 and side 3-1
                                            x1=xh[m2];
                                            y1=yh[m2];
                                            x2=xsect(m3,m1);
                                            y2=ysect(m3,m1);
                                            break;
                                        case 6: //  Line between vertex 3 and side 1-2
                                            x1=xh[m3];
                                            y1=yh[m3];
                                            x2=xsect(m1,m2);
                                            y2=ysect(m1,m2);
                                            break;
                                        case 7: // Line between sides 1-2 and 2-3
                                            x1=xsect(m1,m2);
                                            y1=ysect(m1,m2);
                                            x2=xsect(m2,m3);
                                            y2=ysect(m2,m3);
                                            break;
                                        case 8: // Line between sides 2-3 and 3-1
                                            x1=xsect(m2,m3);
                                            y1=ysect(m2,m3);
                                            x2=xsect(m3,m1);
                                            y2=ysect(m3,m1);
                                            break;
                                        case 9: // Line between sides 3-1 and 1-2
                                            x1=xsect(m3,m1);
                                            y1=ysect(m3,m1);
                                            x2=xsect(m1,m2);
                                            y2=ysect(m1,m2);
                                            break;
                                        default:
                                            break;
                                    }
                                    // Put your processing code here and comment out the printf
                                    //printf("%f %f %f %f %f/n",x1,y1,x2,y2,z[k]);
                                    render.drawContour(x1,y1,x2,y2,z[k]);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private double xsect(int p1, int p2){
        return    (h[p2]*xh[p1]-h[p1]*xh[p2])/(h[p2]-h[p1]);
    }
    
    private double ysect(int p1, int p2){
        return (h[p2]*yh[p1]-h[p1]*yh[p2])/(h[p2]-h[p1]);
    }
}



里面需要用到另外一个类,是最后画等值线用的,也贴出来吧。

 程序代码
package cn.edu.xaut.transfer.end;

public interface Render {
    
    /**
     * drawContour - interface for implementing the user supplied method to
     * render the countours.
     *
     * Draws a line between the start and end coordinates.
     *
     * @param startX    - start coordinate for X
     * @param startY    - start coordinate for Y
     * @param endX      - end coordinate for X
     * @param endY      - end coordinate for Y
     * @param contourLevel - Contour level for line.
     */
    public  void drawContour(double startX, double startY, double endX, double endY, double contourLevel);

}
评论 1 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

yangxjn

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值