3d 如何在加工过程中从中心连接球体?

3d 如何在加工过程中从中心连接球体?,3d,processing,3d,Processing,目前,我正在尝试连接在设定距离内很近的球体。我尝试使用line(x1,y1,z1,x2,y2,z2)函数,但这会产生一些随机的线条。然后我尝试使用beziers,但仍然得到奇怪的结果 以下是迄今为止的代码: import peasy.*; ArrayList<Position> positions; int count=0; int distanceToDrawLines = 20; PeasyCam camera; void setup() { size(1280, 720

目前,我正在尝试连接在设定距离内很近的球体。我尝试使用line(x1,y1,z1,x2,y2,z2)函数,但这会产生一些随机的线条。然后我尝试使用beziers,但仍然得到奇怪的结果

以下是迄今为止的代码:

import peasy.*;

ArrayList<Position> positions;
int count=0;
int distanceToDrawLines = 20;
PeasyCam camera;

void setup() {
  size(1280, 720, P3D);
  stroke(255);
  positions = new ArrayList<Position>();
  smooth(8);
  lights();
}

void draw() {  
  float randomX, randomY, randomZ;
  //camera(mouseX, height/2, (height/2) / tan(PI/6), width/2, height/2, 0, 0, 1, 0);
  //camera = new PeasyCam(this, 0, 0, 0, 0);
  randomX = random(0, width);
  randomY = random(0, height);
  randomZ = random(0, 40);

  Position newPosition = new Position(new PVector(randomX, randomY, randomZ), 20);
  positions.add(newPosition);
  fill(255, 0, 0, 75);
  stroke(0);
  newPosition.Draw();


  for (int i=0; i<positions.size(); i++) {
    Position position = positions.get(i);
    noFill();
    beginShape();
    vertex(position.vector.x,position.vector.y,position.vector.z);
    if (position!=newPosition) {
      float d = dist(position.vector.x, position.vector.y, position.vector.z, newPosition.vector.x, newPosition.vector.y, newPosition.vector.z);

      if (d<=distanceToDrawLines && d!=0) {
        println(d, positions.size(), position.vector, newPosition.vector);
        bezierVertex(position.vector.x, position.vector.y, position.vector.z, newPosition.vector.x, newPosition.vector.y, newPosition.vector.z);
      }
    }
    endShape();
  }

}
任何帮助都将不胜感激


谢谢

您尚未发布Position类,因此我假设它大致如下所示:

class Position{
  PVector vector;
  float radius;

  Position(PVector pos,float rad){
    vector = pos;
    radius = rad; 
  }

  void Draw(){
    pushMatrix();
    translate(vector.x,vector.y,vector.z);
    sphere(radius);
    popMatrix();
  }

}
有两件事似乎不能反映你的意图:

  • 绘制新帧时,您没有清除背景。由于未清除帧缓冲区,因此在旋转相机时,可能会在整个位置产生线条
  • 相机当前已被注释掉,可能应该在
    setup()
    中初始化一次,而不是在
    draw()中每帧多次初始化
  • 每秒多次生成球体的渲染成本会很高,而且有点混乱:我建议限制最初生成球体的数量。也许这就是您的
    count
    变量的意图
  • 本部分:
  • 在设定距离内接近的球体

    听起来有点不清楚。看起来并没有设置该距离,因为您在最近的位置实例中比较的距离之一位于随机位置。(除非您确实希望将距离与最近的球体/位置实例进行比较)

    除此之外,我还有一些提示可以简化此设置:

  • 对随机值使用正负范围将有助于“居中”球体分布(因为只有正值才会使组向右移动)
  • 利用它做的事情和

    距离(position.vector.x,position.vector.y,position.vector.z,newPosition.vector.x,newPosition.vector.y,newPosition.vector.z); 但是保持语法更清晰:
    position.vector.dist(newPosition.vector)

  • 您可以根据您的代码在修订版和注释版中尝试这些建议(使用向上/向下键更改距离阈值):


    你所说的“有些随机的线条”到底是什么意思?你能发布一个屏幕截图吗?我已经添加了Position类。另外,
    distanceToDrawLines
    是一个变量,用于检查球体是否是这个变量,以绘制线。有道理吗?对不起,回复太晚了……你试过我上面发布的代码了吗(并阅读了注释)?还没有,我回家后会看一看,并将其标记为答案。:)我已经设法做到了我想要的程度。不过还是有个简单的问题。如果它们是大约500个球体,那么相机的移动非常缓慢。我能做些什么来提高帧率吗?
    class Position{
      PVector vector;
      float radius;
    
      Position(PVector pos,float rad){
        vector = pos;
        radius = rad; 
      }
    
      void Draw(){
        pushMatrix();
        translate(vector.x,vector.y,vector.z);
        sphere(radius);
        popMatrix();
      }
    
    }
    
    in-processing
    import peasy.*;
    
    ArrayList<Position> positions;
    int count=0;
    
    //increase the distance threshold value: with a wider range of random values there will be less chances of spheres being so close to each other
    int distanceToDrawLines = 200;
    PeasyCam camera;
    
    //keep a reference to the most recent Position instance
    Position newPosition = null;
    
    void setup() {
      size(1280, 720, P3D);
      stroke(255);
      positions = new ArrayList<Position>();
      smooth(8);
      lights();
    
      //use simplified spheres (will look blockier, but will render faster)
      sphereDetail(5);
      //setup PeasyCam once in setup
      camera = new PeasyCam(this, 100);
      camera.setMinimumDistance(50);
      camera.setMaximumDistance(500);
    }
    
    void draw() {  
      background(127);
    
      //generate a limited amount of spheres
      if(count < 100){
    
        float randomX, randomY, randomZ;
        randomX = random(-width, width);
        randomY = random(-height, height);
        randomZ = random(-40, 40);
    
        newPosition = new Position(new PVector(randomX, randomY, randomZ), 20);
        positions.add(newPosition);
    
        count++;
      }
    
    
      for (int i=0; i<positions.size(); i++) {
        Position position = positions.get(i);
    
        noFill();
    
        if (position != newPosition) {
    
          float d = position.vector.dist(newPosition.vector);
    
          if (d<=distanceToDrawLines && d!=0) {
            println(d, positions.size(), position.vector, newPosition.vector);
            line(position.vector.x, position.vector.y, position.vector.z, newPosition.vector.x, newPosition.vector.y, newPosition.vector.z);
          }
        }else{
          //hightlight newest Position instance in transparent red
          fill(255, 0, 0, 75);
        }
        //render every Position instance (after the noFill() / fill() have been set
        position.Draw();
    
      }
    
    }
    //test - play with UP/DOWN arrows to tinker with distance
    void keyPressed(){
      if(keyCode == UP) distanceToDrawLines += 10;
      if(keyCode == DOWN) distanceToDrawLines -= 10;
      distanceToDrawLines = constrain(distanceToDrawLines,20,2000);
      println("distanceToDrawLines: " + distanceToDrawLines);
    }
    
    class Position{
      PVector vector;
      float radius;
    
      Position(PVector pos,float rad){
        vector = pos;
        radius = rad; 
      }
    
      void Draw(){
        pushMatrix();
        translate(vector.x,vector.y,vector.z);
        sphere(radius);
        popMatrix();
      }
    
    }
    
    import peasy.*;
    
    ArrayList<Position> positions;
    Position newPosition;
    int count=0;
    int distanceToDrawLines = 500;
    PeasyCam cam;
    
    PShape nodes;
    
    int fcount, lastm;
    float frate;
    int fint = 3;
    
    void setup() {
      size(1280, 720, P3D);
      positions = new ArrayList<Position>();
      smooth(8);
      lights();
    
      //use simplified spheres (will look blockier, but will render faster)
      sphereDetail(0);//5
      frameRate(60);
      cam = new PeasyCam(this, 100);
      cam.setMinimumDistance(50);
      cam.setMaximumDistance(500);
    
      nodes = createShape(GROUP);
    
      while (count < 300) {
        float randomX, randomY, randomZ, randomRadius;
        randomX = random(-width*2, width*2);
        randomY = random(-height*2, height*2);
        randomZ = random(-1000*2, 1000*2);
        randomRadius = random(10, 40);
        newPosition = new Position(new PVector(randomX, randomY, randomZ), randomRadius);
        positions.add(newPosition);
        count++;
      }
      println("positions initialized");
    
      //calculate distances once, rather than multiple times per seconds
      //similarly instantiate geometries, which will simply be rendered in draw() 
      float distanceToDrawLinesSq = distanceToDrawLines * distanceToDrawLines;
      int numPositions = positions.size();
      for (int i=0; i<numPositions-1; i++) {
        for (int j=i+1; j<positions.size(); j++) {
          Position iPosition = positions.get(i);
          //iPosition.DrawSphere();
          nodes.addChild(getSphere(iPosition));
          Position jPosition = positions.get(j);
          //jPosition.DrawSphere();
          nodes.addChild(getSphere(jPosition));
          //cam.lookAt(iPosition.vector.x, iPosition.vector.y, iPosition.vector.z, 5);
    //      float d = iPosition.vector.dist(jPosition.vector);
    //      if (d <= distanceToDrawLines) {
          //using distance squared (more useful in draw() than setup though
          float dSq = PVector.sub(iPosition.vector,jPosition.vector).magSq();
          if (dSq <= distanceToDrawLinesSq) {
    
            PShape line = createShape(LINE,iPosition.vector.x, iPosition.vector.y, iPosition.vector.z, jPosition.vector.x, jPosition.vector.y, jPosition.vector.z);
            line.setStroke(color(255));
            line.setFill(false);
            nodes.addChild(line);
    
            //stroke(255);
            //line(iPosition.vector.x, iPosition.vector.y, iPosition.vector.z, jPosition.vector.x, jPosition.vector.y, jPosition.vector.z);
          }
        }
      }
      println("geometries initialized");
    
    }
    PShape getSphere(Position p){
        PShape sphere = createShape(SPHERE, 1.0);
        sphere.setStroke(false);
        sphere.setFill(p.fillColor);
        sphere.translate(p.vector.x,p.vector.y,p.vector.z);
        sphere.scale(p.radius);
        return sphere;
    }
    void draw() {  
      background(0);
    
      hint(DISABLE_DEPTH_TEST);
    
      pushMatrix();
      translate(width/2, height/2, -500);
      rotateY(frameCount * 0.01);
      rotateX(frameCount * 0.01);
    
      shape(nodes);
      popMatrix();
    
      hint(ENABLE_DEPTH_TEST);
    
      fcount += 1;
      int m = millis();
      if (m - lastm > 1000 * fint) {
        frate = float(fcount) / fint;
        fcount = 0;
        lastm = m;
        println("fps: " + frate);
      }
    
      //saveFrame("/output3/sequence####.tga");
      //saveFrame in separate thread
      TImage frame = new TImage(width,height,RGB,sketchPath("frame_"+nf(frameCount,3)+".tga"));
      frame.set(0,0,get());
      frame.saveThreaded();
    }
    
    class TImage extends PImage implements Runnable{//separate thread for saving images
      String filename;
    
      TImage(int w,int h,int format,String filename){
        this.filename = filename;
        init(w,h,format);
      }
    
      public void saveThreaded(){
        new Thread(this).start();
      }
    
      public void run(){
        this.save(filename);
      }
    
    }
    
    public class Position {
      private float speed;
      public PVector vector;
      public float radius;
      public int fillColor = color(200, 0, 0, 75);
    
      public Position(PVector vector, float radius) {
        this.vector = vector;
        this.radius = radius;
        this.speed = 0.05;
      }
    
      public void DrawSphere() {
        noStroke();
        vector.x+=random(-speed, speed);
        vector.y+=random(-speed, speed);
        vector.z+=random(-speed, speed);
        fill(fillColor);
        pushMatrix();
        translate(vector.x, vector.y, vector.z);
    
        sphere(radius);
        popMatrix();
      }
    
      public void DrawEllipse() {
        pushMatrix();
        translate(vector.x, vector.y, vector.z);
        ellipse(vector.x, vector.y, radius, radius);
        popMatrix();
      }
    }