Loading...
Logo
Processing Forum
jasonman's Profile
1 Posts
0 Responses
0 Followers

Activity Trend

Last 30 days
Show:
Private Message
    Hi all,i'm a newer on processing,develop a project to show relations of datanodes,like this:
    the whole cavas revolves itself,and the nodes will be added .i redraw all the items every frame and i hope the framespeed is 28-30 frames/second. My trouble is:when the number of nodes is 5 or 6,it runs well;when the number of nodes more than 6,it runs too slowly.Hope somebody help me to make it runs well ,thanks a lot. Here is my code:::::::::::::


    mainclass
    import processing.opengl.*;

    PImage maskImg;
    //递减效果标示
    boolean deleteLineFlag = false;
    boolean deleteNodeFlag = false;
    //外圈大圆半径
    int BigR = 250;
    //展示图片圆的半径
    int smallr = 150;
    //保存图片节点数据,key为图片名称,唯一;值为图片节点对象
    HashMap htNodes = new HashMap();
    //保存节点对象数据
    ArrayList nodes = new ArrayList();
    //保存节点关系连线数据对象
    ArrayList edges = new ArrayList();
    //整体画布重绘次数
    int iLoop=0;
    //已经绘制的节点的数目
    int iDrawNodes=0;
    //已经绘制的关系连接的数目
    int iDrawLines=-50;
    //需要显示的节点数目
    int iNodeNumGroup = 10;
    //已经绘制的节点的数目
    int iNodeNum=0;
    //节点相距角度
    int iDelta = 0;
    //每一帧的整体图片旋转角度
    int iDeltaMod = 1;

    final color backgroundColor   = #F0C070;

    //根据半径、角度计算出x轴偏移量
    double countX(int lengthR,int delta){
      return lengthR * Math.sin(((90-delta)*Math.PI)/180);
    }
    //根据半径、角度计算出y轴偏移量
    double countY(int lengthR,int delta){
      return lengthR * Math.sin((delta*Math.PI)/180);
    }

    //初始化程序运行的基本数据,包括:所有节点数据的加载、所有节点之间关联关系数据的加载
    void initAll(){
      deleteLineFlag = false;
      deleteNodeFlag = false;
      htNodes = new HashMap();
      nodes = new ArrayList();
      edges = new ArrayList();
      iLoop=0;
      iDrawNodes=0;
      iDrawLines=0;
      iNodeNumGroup = 10;
      iNodeNum=0;
      iDelta = 0;
      //解析数据文件,每行为一个节点数据,格式为  节点名称,关系节点A/关系节点B/关系节点C,节点图片路径,如果关系节点信息为空,则必须为空字符串
      String[] infos = loadStrings("relations.txt");
      iNodeNum = infos.length;
      //根据节点数目计算出节点间隔角度
      iDelta = 360 / iNodeNum;
      //循环处理节点信息
      for(int i=0;i<iNodeNum;i++){
        //半角逗号分隔字符串
        String[] nodeInfo = infos[i].split(",");
        //计算出此节点圆心的坐标
        double x = countX(BigR,i*iDelta);
        double y = countY(BigR,i*iDelta);
        //新建节点
        Node node = new Node(iDeltaMod,(width/2 + x),(height/2 + y),200,nodeInfo[0],nodeInfo[2]);
        //将节点名称增加至节点名称数组里
        nodes.add(node.nodeName);
        //将节点信息以节点名称保存于哈希表中
        htNodes.put(nodeInfo[0],node);
        //如果关系节点信息不为空,则解析关系节点信息字符串,并生成连线对象
        if(!nodeInfo[1].equals("")){
          String[] rels = nodeInfo[1].split("/");
          for(int j=0;j<rels.length;j++){
            Edge edge = new Edge(nodeInfo[0],nodeInfo[1]);
            edges.add(edge);
          }
        }
      }
    }

    void setup() {
      maskImg = loadImage("mask.jpg");
      size(800, 800, P2D);
      background(0);
      initAll();
      smooth();
      loop();
    }

    void draw() {
      background(0);
      iLoop++;
      //绘制节点
      DrawNodes dd = new DrawNodes();
      dd.draw();
      //每30帧新增一个节点
      if(iLoop % 30 == 0){
        dd.drawNew();
      }
     
      //当节点绘制完成,开始绘制关系连线
      DrawLines dl = new DrawLines();
      if(iDrawNodes >= nodes.size()){
        //绘制关系连线
        dl.draw();
        //每30帧新增一条关系连线
        if(iLoop % 29 == 0){
          dl.drawNew();
        }
      }
     
      //当关系连线绘制完成,开始删除节点以及对于的关系连线,然后更新数据
      if(iDrawLines >= edges.size()){
        deleteLineFlag=true;
      }
      if(deleteLineFlag){
        if(iLoop % 10 == 0){
          dl.deleteLine();
        }
      }
      if(deleteNodeFlag){
        if(iLoop % 10 == 0){
          dd.deleteNode();
        }
      }
     
      moveNode();
    }

    //移动所有节点,每次移动为顺时针一度
    void moveNode(){
      for(int i=0;i<nodes.size();i++){
        Node node = (Node) htNodes.get((String)nodes.get(i));
        if(node != null){
          double x = countX(BigR,i*iDelta - iDeltaMod);
          double y = countY(BigR,i*iDelta - iDeltaMod);
          node.update((width/2 + x),(height/2 + y),100,i*iDelta - iDeltaMod);
        }
      }
      iDeltaMod++;
      if(iDeltaMod >= 360){
        iDeltaMod = iDeltaMod % 360;
      }
    }




    DrawLines:
    //绘制关系连线类
    class DrawLines{
      //已经绘制的关系连线,每次重绘都要绘制出来
      void draw(){
        for(int i=0;i<=iDrawLines;i++){
          if(i < edges.size()){
            Object obj = edges.get(i);
            if(obj != null){
              Edge edge = (Edge) obj;
              edge.draw();
            }
          }
        }
      }
     
      //新绘制一条关系连线
      void drawNew(){
        iDrawLines=iDrawLines+1;
        if(iDrawLines < edges.size()){
          Edge edge = (Edge)edges.get(iDrawLines);
          edge.draw();
        }else{
          iDrawLines = edges.size();
        }
      }
     
      //删除关系连线
      void deleteLine(){
        if(deleteLineFlag){
          if(edges.size() > 0){
            edges.remove(0);
          }else{
            deleteNodeFlag = true;
          }
        }
      }
     
    }


    DrawNodes:

    //绘制节点类
    class DrawNodes{
      //已经绘制的节点,在每次重绘的时候都要绘制出来
      void draw(){
        for(int i=0;i<=iDrawNodes;i++){
          if(i < nodes.size()){
            Object obj = htNodes.get((String)nodes.get(i));
            if(obj != null){
              Node node = (Node) obj;
              node.draw();
            }
          }
        }
      }
     
      //新绘制一个节点
      void drawNew(){
       
        iDrawNodes = iDrawNodes + 1;
        if(iDrawNodes < nodes.size()){
          //BigR = (int)(BigR * (1+0.05));
          Node node = (Node) htNodes.get((String)nodes.get(iDrawNodes));
          node.draw();
        }else{
          iDrawNodes = nodes.size();
        }
      }
     
      void deleteNode(){
        if(deleteNodeFlag){
          if(nodes.size() > 0){
            htNodes.remove(nodes.get(nodes.size()-1));
            nodes.remove(nodes.size()-1);
          }else{
            initAll();
          }
        }
      }
     
    }


    Edge:::
    class Edge{
      float xsmall=0;
      float xbig=0;
      float ysmall=0;
      float ybig=0;
      float xb1 = 400;
      float xb2 = 400;
      float yb1 = 400;
      float yb2 = 400;
      String from;
      String to;
      Node nodeFrom;
      Node nodeTo;
      Edge(String from,String to){
        this.from = from;
        this.to = to;
      }
     void draw(){
        nodeFrom = (Node)htNodes.get(from);
        nodeTo = (Node)htNodes.get(to);
       
        int rnew = (int) (BigR * 0.7);
        xb1 = width/2 + (float)countX(rnew,nodeFrom.deltaOff);
        yb1 = height/2 + (float)countY(rnew,nodeFrom.deltaOff);
        xb2 = width/2 + (float)countX(rnew,nodeTo.deltaOff);
        yb2 = height/2 +(float)countY(rnew,nodeTo.deltaOff);
    //    println(xb1+"-"+yb1);
        noFill();
        stroke(204, 102, 0);
        bezier((float)nodeFrom.x,(float)nodeFrom.y, xb1,yb1,xb2,yb2,  (float)nodeTo.x,(float)nodeTo.y);
      }
    }


    Node::::::::


    class Node {
      //圆心坐标
      double x, y;
      //偏移角度
      int deltaOff;
      //半径
      int r=200;
      //节点名称
      String nodeName;
      //节点图片路径
      String nodePic;
      float fscal = 0.1;
     
      Node(int deltaOff,double x, double y, int r,String nodeName,String nodePic){
        this.x = x;
        this.y = y;
        this.r = r;
        this.nodeName = nodeName;
        this.nodePic = nodePic;
      }
     
      void update(double x, double y,int r, int deltaOff){
        this.x = x;
        this.y = y;
        this.r = r;
        this.deltaOff = deltaOff;
      }
     
      void draw() {
        PImage img = loadImage(nodePic);
        img.mask(maskImg);
        imageMode(CENTER);
        fscal = (fscal>=0.5 ? 0.5 : fscal + 0.05);
        int iScal = (int)(200*fscal);
        img.resize(iScal,iScal);
        image(img, (float)x, (float)y);
      }
    }