草庐IT

toxiclibs中的粒子和弹簧

大龙10 2023-09-21 原文

书名:代码本色:用编程模拟自然系统
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
目录

5.16 toxiclibs中的粒子和弹簧

1、粒子

  • 在Box2D的例子中,我们创建了自己的类(比如Particle类),并在其中加入了一个Box2D物体对象变量。
class Particle {
    Body body;
  • 这样的实现方式显得有些多余,因为Box2D在内部维护了所有物体对象。但是,这种写法允许我们直接获取物体对象的某些信息(继而得到物体的绘制方式),而不需要遍历Box2D内部的对象列表。
  • 让我们看看如何将同样的方法作用在toxiclibs的VerletParticle2D类中。为了方便地绘制粒子对象,并在粒子中加入某些自定义属性,我们还是要定义自己的Particle类。代码如下所示:
class Particle {
    VerletParticle2D p; 粒子对象有一个指向VerletParticle对象的引用
    Particle(Vec2D pos) {
    p = new VerletParticle2D(pos); VerletParticle对象需要一个初始位置(x坐标和y坐标)
}
void display() {
    fill(0,150);
    stroke(0);
    ellipse(p.x,p.y,16,16); 当我们在绘制粒子时,需要向VerletParticle对象询问x坐标和y坐}
}
  • 从上面的代码可以看出,绘制粒子是一件很简单的事,可以直接使
    用VerletParticle2D对象的x坐标和y坐标,不需要烦琐的坐标转换,因为toxiclibs用的就是像素坐标。
  • 除此之外,你还会发现这个粒子类只有一个作用,那就是存放VerletParticle2D对象的引用。请回顾第4章讨论的继承特性:这也是一个粒子系统,除了存放VerletParticle2D对象的引用,粒子对象还有什么其他特性?我们是否可以让Particle类继承VerletParticle2D类?
class Particle extends VerletParticle2D {
    Particle(Vec2D loc) {
    super(loc); 调用super()函数,确保对象以正确的方式初始化
}
void display() { 我们只需要实现一个display()函数
     fill(175);
    stroke(0);
    ellipse(x,y,16,16); 从VerletParticle类中继承了x坐标和y坐标
  }
}
  • 还记得Box2D示例程序的处理步骤吗?我们需要向Box2D物体对象询问它的位置,再将坐标转换为像素坐标,最后根据转换后的坐标绘图。在这里,由于我们从VerletParticle2D类中继承了所有功能,剩下的任务只是根据x坐标和y坐标处绘制图形!
    顺便再提一点,VerletParticle2D类是Vec2D的子类,因此除了从VerletParticle2D继承的特性,我们的粒子类还有Vec2D对象的所有功能。现在,我们可以在Sketch的任意位置创建粒子对象。
Particle p1 = new Particle(new Vec2D(100,20));
Particle p2 = new Particle(new Vec2D(100,180));
  • 仅仅创建一个粒子是不够的,还应该用addParticle()函数将粒子对象添加到物理世界中。
physics.addParticle(p1);
physics.addParticle(p2);
  • 从toxiclibs的文档中可以看到,addParticle()函数的参数是一个VerletParticle2D对象。
addParticle(VerletParticle2D particle);
  • 如何在addParticle()函数中传入自己的粒子对象?面向对象编程中有多态特性,由于Particle类继承自VerletParticle2D类,我们可以把这个粒子实例当作两种对象——Particle对象和VerletParticle2D对象。这是面向对象编程中一个很强大的特性。如果自定义类都继承自toxiclibs的类,它们就可以直接将其用在toxiclibs物理库中。

2、弹簧

  除了VerletParticle类,toxiclibs还提供了一些连接粒子的弹簧类。toxiclibs有3种类型的弹簧。

  • VerletSpring 
    该类在两个粒子之间创建连接,包括刚性连接和弹性连接。其
    中的某个粒子可以被固定,只有弹簧的另一端可以移动。
  • VerletConstrainedSpring 
    可以通过VerletConstrainedSpring对象限
    制连接的最大长度,这样弹性系统具有较好的稳定性。
  • VerletMinDistanceSpring 
    VerletMinDistanceSpring对象可以保证物体之间的距离不小于静止长度,如果你想让物体之间保持一定距离,但不关心它们之间的最大距离,可以使用这个类。

  前面提到的继承和多态技术同样适用于弹簧对象的创建,创建一个弹簧对象需要传入两个VerletParticle对象,由于我们的Particle类继承自VerletParticle对象,因此VerletSpring的构造函数也接受粒子对象作为参数。以下代码展示了如何在粒子对象p1和p2之间创建一个弹性连接,该连接有指定的静止长度和弹性强度。

float len = 80; 弹簧的静止长度
float strength = 0.01; 弹簧的强度
VerletSpring2D spring=new VerletSpring2D(p1,p2,len,strength);
  • 和粒子一样,为了让弹簧成为toxiclibs物理世界的一部分,我们需要在物理世界中添加这个对象。
physics.addSpring(spring);

有关toxiclibs中的粒子和弹簧的更多相关文章

  1. 详解Unity中的粒子系统Particle System (二) - 2

    前言上一篇我们简要讲述了粒子系统是什么,如何添加,以及基本模块的介绍,以及对于曲线和颜色编辑器的讲解。从本篇开始,我们将按照模块结构讲解下去,本篇主要讲粒子系统的主模块,该模块主要是控制粒子的初始状态和全局属性的,以下是关于该模块的介绍,请大家指正。目录前言本系列提要一、粒子系统主模块1.阅读前注意事项2.参考图3.参数讲解DurationLoopingPrewarmStartDelayStartLifetimeStartSpeed3DStartSizeStartSize3DStartRotationStartRotationFlipRotationStartColorGravityModif

  2. 弹簧靴2.0.0 m1-执行器不起作用 - 2

    我有一个弹簧启动项目,该项目使用Spring-Boot执行器提供应用程序统计和指标。通过在项目中添加“弹簧启动-启动器”来提供执行器功能。在这一点上,安全性是禁用的,因此该项目不会导入春季安全性。使用Spring-boot1.5.x,所有执行器端点(自动提供,作为/信息以及我的特定定义端点)都可以正常工作。更新到Spring-Boot2.0.0M1后,执行器端点不再暴露。调用/信息端点返回以下错误:{"timestamp":1496948526890,"status":404,"error":"NotFound","message":"Nomessageavailable","path":"/

  3. php - 永久链接不适用于自定义帖子和类别 - 2

    我正在尝试在wordpress中添加wordpress自定义帖子类型和类别add_action('init','work_register');functionwork_register(){$labels=array('name'=>_x('Work','posttypegeneralname'),'singular_name'=>_x('WorkItem','posttypesingularname'),'add_new'=>_x('AddNew','workitem'),'add_new_item'=>__('AddNewWorkItem'),'edit_item'=>__('E

  4. php - 从 WordPress 搜索结果中分离帖子和页面 - 2

    我正在寻找一种在我的自定义wordpress主题中显示搜索结果的方法。我希望能够像这样呈现结果:显示“测试”的4个搜索结果页面测试页1测试页2帖子测试帖1测试帖2我写了一个函数is_type_page,我可以在循环(2个循环)中使用它,但这会破坏分页功能。有什么建议可以实现吗? 最佳答案 我会在页面上运行2个单独的循环,在页面的第一个循环运行rewind_posts()之后再次运行循环。分页的关键还在于确保全局变量$paged被两个循环拾取。$paged是wordpress将帖子分成页面的方式。即,如果您转到某个内容的第2页,则全局

  5. php - 表单帖子和 jquery 帖子之间的区别 - 2

    我需要知道以下两者之间的确切区别:和varurl="https://mywebsite/signon.php";$.ajax({url:url,type:'POST',//dataType:'html',--thiswassomethingItriedlater//data:"harv_acc="+accountnumber+"&harv_eml="+email,thisisalsowhatItriedlastbutbelowiswhatItriedfirstdata:{harv_acc:account,harv_eml:email},success:function(data){cl

  6. c++ - 苹果、橘子和指向最派生的 c++ 类的指针 - 2

    假设我有一堆水果:classFruit{...};classApple:publicFruit{...};classOrange:publicFruit{...};以及一些对所述水果进行​​操作的多态函数:voidEat(Fruit*f,Pesticide*p){...}voidEat(Apple*f,Pesticide*p){ingest(f,p);}voidEat(Orange*f,Pesticide*p){peel(f,p);ingest(f,p);}好的,等等。停在那儿。请注意,任何理智的人都会将Eat()设为Fruit类的虚拟成员函数。但这不是一个选择,因为我不是一个理智的人

  7. ios - 适用于 iOS 的粒子动画 - 2

    我在基于UIView的2D游戏中需要粒子动画。目前我正在使用一组图像来制作粒子动画。这使我的应用程序大小增加,有时会导致内存泄漏。有什么方法可以使用CoreAnimation制作粒子动画吗? 最佳答案 cocos2d(参见http://cocos2d-iphone.org/)是一个为iPhone开发2d游戏的框架。许多示例的源代码包括一些粒子动画演示。 关于ios-适用于iOS的粒子动画,我们在StackOverflow上找到一个类似的问题: https://

  8. ios - Facebook 上的新闻提要帖子和帖子 "name"后面的链接 - 2

    我正在使用以下代码在当前用户供稿上发布帖子:NSMutableDictionary*postParams=[[NSMutableDictionaryalloc]initWithObjectsAndKeys:@"http://url.com/image.jpg",@"picture",@"Thetitleofthepostonthefeed",@"name",@"Captiontext",@"caption",@"Descriptiontext",@"description",nil];[self.facebookrequestWithGraphPath:@"me/feed"andPar

  9. objective-c - OpenGL ES - 如何批量渲染 500 多个具有/不同 alpha、旋转和缩放的粒子? - 2

    我正在开发一款iOS游戏,需要一次渲染500-800个粒子。我了解到,最好在OpenGLES中批量渲染许多Sprite,而不是在游戏中的每个Sprite上调用glDrawArrays(..),以便能够渲染更多Spritew/out帧率急剧下降。我的问题是:我如何批量渲染500多个粒子,它们都具有不同的alpha、旋转和缩放,但共享相同的纹理图集?这个问题的重点在于每个粒子的不同alphas、旋转和尺度。我意识到这个问题与HowdoIdraw1000+particles(w/uniquerotation,scale,andalpha)iniPhoneOpenGLESparticlesys

  10. sorting - MongoDB 日期排序的粒度? - 2

    是否可以对MongoDB的日期值进行粒度排序?我想按日期排序我的结果,但我不关心小时/分钟/秒数据。我不想存储额外的参数,例如“20101215”。 最佳答案 对您的问题的简短回答是“否”。不存储另一个字段是不可能的。即使有可能在Mongo中排序时您不希望b/c,您确实需要索引您排序所依据的字段,否则数据库将需要扫描数据库中的每个文档以进行排序。因此,如果您要按照您的建议进行操作,您还需要在部分日期字段上建立索引,这在mongo中也是不可能的。我认为最好的方法是存储2个字段,一个用于年/月/日,另一个用于小时/分钟/秒。这样您就可以

随机推荐