Spring 如何在粒子系统处理中制作滑动构件
我正在模拟处理中的粒子系统。基于Daniel Shiffman的代码书的本质,我做了一个spring,然后我开始用滑块做一个基于滑块的长度更长或更短的滑块 现在,我试着让一个通过滑块滑动,两个粒子向两个粒子相同的方向移动。 我用PVector add完成了这项工作,找到了新的位置并绘制了节点,但是当我有多个成员并且其中一个成员受到其他成员的影响时,它就不起作用了。 我需要施加一个力来实现这一点:请参见applyForce()函数Spring 如何在粒子系统处理中制作滑动构件,spring,processing,simulation,particle-system,Spring,Processing,Simulation,Particle System,我正在模拟处理中的粒子系统。基于Daniel Shiffman的代码书的本质,我做了一个spring,然后我开始用滑块做一个基于滑块的长度更长或更短的滑块 现在,我试着让一个通过滑块滑动,两个粒子向两个粒子相同的方向移动。 我用PVector add完成了这项工作,找到了新的位置并绘制了节点,但是当我有多个成员并且其中一个成员受到其他成员的影响时,它就不起作用了。 我需要施加一个力来实现这一点:请参见applyForce()函数 void update(float distance) { P
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)是它现在的做法
在第一个示例中,长度相同,并且构件滑动(两个粒子)
在第二种情况下,长度更大,不会滑动
请让我知道,如果你知道如何应用一个力量,幻灯片的成员
谢谢你如果我理解正确,你正在尝试做几件事:
len
属性。
第二个涉及到一些:
//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而不是一个断开连接的代码段,你的运气会好得多。