gpt4 book ai didi

spring - 如何在使用粒子系统进行处理中制作滑动构件

转载 作者:行者123 更新时间:2023-12-04 15:33:01 25 4
gpt4 key购买 nike

我在 Processing 中模拟粒子系统。根据 Daniel Shiffman 的 Nature of Code 一书,我做了一个 Spring ,然后我开始尝试使用 slider 来做一个基于 slider 的长度更长或更短的 slider 。

现在,我正在尝试制作一个通过 slider 滑动的,两个粒子向两个粒子的相同方向移动。
我使用 PVector 添加,找到新位置并绘制节点,但是当我有多个成员并且一个受其他成员影响时,它不起作用。
我需要施加力来执行此操作:请参阅 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);
}

检查下图:

diagram

(一) 是我想要的, (二) 它现在是怎么做的。

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

在第二个长度更大并且不滑动

如果您知道如何施加使成员滑动的力,请告诉我。

谢谢

最佳答案

如果我理解正确,您正在尝试做一些事情:

  • 改变 Spring 长度
  • 沿 Spring 方向平移 Spring 端点
  • 使用 slider 控制上述参数

  • 第一部分很简单,因为 Spring 对象有 len属性(property)。
    第二个涉及到一点 vector math :
  • 一条线的方向是它的两个端点的减法
  • 通过首先对其进行归一化(将其减小使其长度等于 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);
    }
    }

    Slider controlled Spring

    关于spring - 如何在使用粒子系统进行处理中制作滑动构件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32129546/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com