Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 如何在粒子系统处理中制作滑动构件_Spring_Processing_Simulation_Particle System - Fatal编程技术网

Spring 如何在粒子系统处理中制作滑动构件

Spring 如何在粒子系统处理中制作滑动构件,spring,processing,simulation,particle-system,Spring,Processing,Simulation,Particle System,我正在模拟处理中的粒子系统。基于Daniel Shiffman的代码书的本质,我做了一个spring,然后我开始用滑块做一个基于滑块的长度更长或更短的滑块 现在,我试着让一个通过滑块滑动,两个粒子向两个粒子相同的方向移动。 我用PVector add完成了这项工作,找到了新的位置并绘制了节点,但是当我有多个成员并且其中一个成员受到其他成员的影响时,它就不起作用了。 我需要施加一个力来实现这一点:请参见applyForce()函数 void update(float distance) { P

我正在模拟处理中的粒子系统。基于Daniel Shiffman的代码书的本质,我做了一个spring,然后我开始用滑块做一个基于滑块的长度更长或更短的滑块

现在,我试着让一个通过滑块滑动,两个粒子向两个粒子相同的方向移动。 我用PVector add完成了这项工作,找到了新的位置并绘制了节点,但是当我有多个成员并且其中一个成员受到其他成员的影响时,它就不起作用了。 我需要施加一个力来实现这一点:请参见applyForce()函数

void update(float distance) {
  PVector force = PVector.sub(b.location, a.location); 
  float d = force.mag();
  float x = d - distance;
 //direction of the force
  force.normalize();
  force.mult(-1 * k* x/mass);
 //apply to one node
  b.applyForce(force); 
  force.mult(-1);
 //apply opposite to the other node
  a.applyForce(force);
}

//Newton's law: F = M * A
void applyForce(PVector force) {
  PVector f = force.get();
  f.div(mass);
  acceleration.add(f);
}
检查下图:

(a)是我想要的,(b)是它现在的做法

在第一个示例中,长度相同,并且构件滑动(两个粒子)

在第二种情况下,长度更大,不会滑动

请让我知道,如果你知道如何应用一个力量,幻灯片的成员


谢谢你

如果我理解正确,你正在尝试做几件事:

  • 改变弹簧的长度
  • 沿弹簧的方向平移弹簧的端点
  • 使用滑块控制上述参数
  • 第一部分很简单,因为Spring对象具有
    len
    属性。 第二个涉及到一些:

  • 直线的方向是两个端点的差
  • 向量可以很容易地缩放到任意长度,方法是先对其进行归一化(减小它,使其长度等于1.0),然后乘以标量值
  • 只需将另一个向量添加到向量本身,即可转换向量
  • 以下是实现上述要点的注释草图:

    //sliders to control spring rest length and translation
    Slider rlength = new Slider("rest length", 5, 5, 200, 20, 50, 250, 100, false);
    Slider translate = new Slider("translate", 5, 30, 200, 20, -10, 10, 0, false);
    
    Spring spring = new Spring(new Bob(75,350),new Bob(350,75),(int)rlength.value);
    
    void setup(){
      size(400,400);
      spring.k = 0.01;//tweak elasticity
    }
    void draw(){
      //  update
      //update sliders
      rlength.update(mouseX,mouseY,mousePressed);
      translate.update(mouseX,mouseY,mousePressed);
      //update spring
      spring.a.update();
      spring.b.update();
      spring.update();
      //make both points draggable
      spring.a.drag(mouseX, mouseY);
      spring.b.drag(mouseX, mouseY);
      //draw
      background(255);
      rlength.draw();
      translate.draw();
      spring.display();
    }
    //handle mouse events for spring points dragging
    void mousePressed() {
      spring.a.clicked(mouseX, mouseY);
      spring.b.clicked(mouseX, mouseY);
    }
    void mouseReleased() {
      spring.a.stopDragging();
      spring.b.stopDragging();
    }
    //handle slider events
    void onSliderUpdate(Slider s){
      if(s == rlength) spring.len = rlength.value;
      if(s == translate){
        //compute the direction of the spring by subtracting the two points
        PVector direction = PVector.sub(spring.a.location,spring.b.location);
        //normalize the vector -> it will not have a length/magnitude of 1.0, but will still point in the line direction
        direction.normalize();
        //scale or multiply the normalized vector to the translation amount
        direction.mult(translate.value);
        //finally, add the result to each spring point, essentially offsetting/translating
        spring.a.location.add(direction);
        spring.b.location.add(direction);
      } 
    }
    //Slider
    class GUIElement{
      float w,h,x,y;//width, height and position
      color bg = color(200);//background colour
      color fg = color(0);//foreground colour
      String label;
      GUIElement(String label,float x,float y,float w,float h){
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        this.label = label;
      }
      void update(int mx,int my,boolean md){}
      void draw(){}
    }
    class Slider extends GUIElement{
      float min,max,value,pvalue;//slider values: minimum, maximum and current
      float cx,pw = 20;//current slider picker position, picker width
    
      boolean updating,liveDrag = true,isInt = false;
      //label to display on slider, it's position(x,y), size(w,h) and values(min, max and default/current)
      Slider(String label,float x,float y,float w,float h,float min,float max,float value,boolean isInt){
        super(label,x,y,w,h);
        this.min = min;
        this.max = max;
        this.value = value;
        this.isInt = isInt;
        cx = map(value,min,max,x,x+w);
      }
      void update(int mx,int my,boolean md){
        if(md){
          if((mx >= x && mx <= (x+w)) &&
             (my >= y && my <= (y+h))){
            cx = mx;
            value = map(cx,x,x+w,min,max);
            updating = true;
            if(liveDrag){
              boolean updated = (isInt ? ((int)value != (int)pvalue) : (value != pvalue));
              if(updated){
                pvalue = value;
                onSliderUpdate(this);
              }
            }
          }else updating = false;
        }else{
          if(updating){
            updating = false;
            onSliderUpdate(this);
          }  
        }
      }
      void draw(){
        pushStyle();
        noStroke();
        fill(bg);
        rect(x,y,w,h);
        fill(fg,64);
        rect(x,y,cx-x,h);//this displays a rect that stretches based on the value
        fill(0);
        text(label+": "+(isInt ? (int)value : value),x+pw,y+h*.75);
        popStyle();
      }
      String toString(){
        return label + ":" + value;
      }
    }
    
    // The Nature of Code
    // Daniel Shiffman
    // http://natureofcode.com
    
    // Bob class, just like our regular Mover (location, velocity, acceleration, mass)
    
    class Bob { 
      PVector location;
      PVector velocity;
      PVector acceleration;
      float mass = 12;
    
      // Arbitrary damping to simulate friction / drag 
      float damping = 0.95;
    
      // For mouse interaction
      PVector dragOffset;
      boolean dragging = false;
    
      // Constructor
      Bob(float x, float y) {
        location = new PVector(x,y);
        velocity = new PVector();
        acceleration = new PVector();
        dragOffset = new PVector();
      } 
    
      // Standard Euler integration
      void update() { 
        velocity.add(acceleration);
        velocity.mult(damping);
        location.add(velocity);
        acceleration.mult(0);
      }
    
      // Newton's law: F = M * A
      void applyForce(PVector force) {
        PVector f = force.get();
        f.div(mass);
        acceleration.add(f);
      }
    
    
      // Draw the bob
      void display() { 
        stroke(0);
        strokeWeight(2);
        fill(175);
        if (dragging) {
          fill(50);
        }
        ellipse(location.x,location.y,mass*2,mass*2);
      } 
    
      // The methods below are for mouse interaction
    
      // This checks to see if we clicked on the mover
      void clicked(int mx, int my) {
        float d = dist(mx,my,location.x,location.y);
        if (d < mass) {
          dragging = true;
          dragOffset.x = location.x-mx;
          dragOffset.y = location.y-my;
        }
      }
    
      void stopDragging() {
        dragging = false;
      }
    
      void drag(int mx, int my) {
        if (dragging) {
          location.x = mx + dragOffset.x;
          location.y = my + dragOffset.y;
        }
      }
    }
    
    // Nature of Code 2011
    // Daniel Shiffman
    // Chapter 3: Oscillation
    
    // Class to describe an anchor point that can connect to "Bob" objects via a spring
    // Thank you: http://www.myphysicslab.com/spring2d.html
    
    class Spring { 
    
      // Location
      PVector anchor;
    
      // Rest length and spring constant
      float len;
      float k = 0.2;
    
      Bob a;
      Bob b;
    
      // Constructor
      Spring(Bob a_, Bob b_, int l) {
        a = a_;
        b = b_;
        len = l;
      } 
    
      // Calculate spring force
      void update() {
        // Vector pointing from anchor to bob location
        PVector force = PVector.sub(a.location, b.location);
        // What is distance
        float d = force.mag();
        // Stretch is difference between current distance and rest length
        float stretch = d - len;
    
        // Calculate force according to Hooke's Law
        // F = k * stretch
        force.normalize();
        force.mult(-1 * k * stretch);
        a.applyForce(force);
        force.mult(-1);
        b.applyForce(force);
      }
    
    
      void display() {
        strokeWeight(3);
        stroke(0);
        line(a.location.x, a.location.y, b.location.x, b.location.y);
        ellipse(a.location.x, a.location.y,10,10);
        ellipse(b.location.x, b.location.y,10,10);
      }
    }
    
    //用于控制弹簧座长度和平移的滑块
    滑块长度=新滑块(“静止长度”,5,5200,20,50,250,100,假);
    滑块平移=新滑块(“平移”,5,30,200,20,-10,10,0,假);
    弹簧弹簧=新弹簧(新摆锤(75350),新摆锤(350,75),(整数)长度值);
    无效设置(){
    尺寸(400400);
    spring.k=0.01;//调整弹性
    }
    作废提款(){
    //更新
    //更新滑块
    更新(mouseX、mouseY、mousePressed);
    更新(mouseX、mouseY、mousePressed);
    //更新弹簧
    spring.a.update();
    spring.b.update();
    spring.update();
    //使这两个点都可以拖拉
    弹簧a.阻力(mouseX,mouseY);
    弹簧b.阻力(mouseX,mouseY);
    //画
    背景(255);
    rlength.draw();
    translate.draw();
    spring.display();
    }
    //处理用于拖动弹簧点的鼠标事件
    void mousePressed(){
    spring.a.点击(mouseX,mouseY);
    spring.b.点击(mouseX,mouseY);
    }
    void mouseereleased(){
    spring.a.停止拖动();
    spring.b.停止拖动();
    }
    //处理滑块事件
    滑块更新时无效(滑块s){
    如果(s==rlength)spring.len=rlength.value;
    如果(s==translate){
    //通过减去两点计算弹簧的方向
    PVector方向=PVector.sub(弹簧a位置,弹簧b位置);
    //规范化向量->它的长度/大小不为1.0,但仍将指向直线方向
    方向。规范化();
    //将标准化向量缩放或乘以平移量
    方向.mult(translate.value);
    //最后,将结果添加到每个弹簧点,基本上是偏移/平移
    弹簧.a.位置.add(方向);
    弹簧。b。位置。添加(方向);
    } 
    }
    //滑块
    类gui元素{
    浮动w、h、x、y;//宽度、高度和位置
    color bg=color(200);//背景色
    color fg=color(0);//前景色
    字符串标签;
    GUI元素(字符串标签、浮点x、浮点y、浮点w、浮点h){
    这个.x=x;
    这个。y=y;
    这个.w=w;
    这个,h=h;
    this.label=标签;
    }
    无效更新(int-mx,int-my,boolean-md){}
    void draw(){}
    }
    类滑块扩展GUI元素{
    浮点最小值、最大值、值、pvalue;//滑块值:最小值、最大值和当前值
    浮点cx,pw=20;//当前滑块选择器位置,选择器宽度
    布尔更新,liveDrag=true,isInt=false;
    //要在滑块上显示的标签、其位置(x、y)、大小(w、h)和值(最小值、最大值和默认值/当前值)
    滑块(字符串标签、浮点x、浮点y、浮点w、浮点h、浮点最小值、浮点最大值、浮点值、布尔isInt){
    超级(标签,x,y,w,h);
    this.min=min;
    this.max=max;
    这个值=值;
    this.isInt=isInt;
    cx=映射(值、最小值、最大值、x、x+w);
    }
    无效更新(int mx、int my、布尔md){
    if(md){
    
    如果((mx>=x&&mx=y&&my)你说它不工作是什么意思?你能发布一个?@KevinWorkman吗?请检查图表并让我知道它是否有用。如果你发布一个MCVE而不是一个断开连接的代码段,你的运气会好得多。