UNPKG

fieldkit

Version:

Basic building blocks for computational design projects. Written in CoffeeScript for browser and server environments.

173 lines (119 loc) 3.57 kB
vector = require '../math/vector' Vec2 = vector.Vec2 Vec3 = vector.Vec3 physics = require './physics' Constraint = physics.Constraint ### Keeps the particle inside the given 3D box ### class Box extends Constraint constructor: (@min = new Vec3(), @max = new Vec3(100, 100, 100)) -> apply: (particle) -> pos = particle.position pos.x = @min.x if pos.x < @min.x pos.y = @min.y if pos.y < @min.y pos.z = @min.z if pos.z < @min.z pos.x = @max.x if pos.x > @max.x pos.y = @max.y if pos.y > @max.y pos.z = @max.z if pos.z > @max.z toString: -> "Box(#{@min}, #{@max})" ### 2D version of Box. ### class Area extends Constraint constructor: (@min = new Vec2(), @max = new Vec2(100, 100)) -> apply: (particle) -> pos = particle.position pos.x = @min.x if pos.x < @min.x pos.y = @min.y if pos.y < @min.y pos.x = @max.x if pos.x > @max.x pos.y = @max.y if pos.y > @max.y toString: -> "Area(#{@min}, #{@max})" ### Keeps a particle within a certain 2D region by wrapping it around a given area. ### class Wrap2 extends Constraint delta = new Vec2() constructor: (@min = new Vec2(), @max = new Vec2(100, 100)) -> prepare: -> delta.set(@max).sub(@min) apply: (particle) -> pos = particle.position prev = particle.prev if pos.x < @min.x pos.x += delta.x prev.x += delta.x if pos.y < @min.y pos.y += delta.y prev.y += delta.y if pos.x > @max.x pos.x -= delta.x prev.x -= delta.x if pos.y > @max.y pos.y -= delta.y prev.y -= delta.y toString: -> "Wrap2(#{@min}, #{@max})" ### Keeps a particle within a certain 2D region by wrapping it around a given area. ### class Wrap3 extends Constraint delta = new Vec3() constructor: (@min = new Vec3(), @max = new Vec3(100, 100, 100)) -> prepare: -> delta.set(@max).sub(@min) apply: (particle) -> pos = particle.position prev = particle.prev if pos.x < @min.x pos.x += delta.x prev.x += delta.x if pos.y < @min.y pos.y += delta.y prev.y += delta.y if pos.z < @min.z pos.z += delta.z prev.z += delta.z if pos.x > @max.x pos.x -= delta.x prev.x -= delta.x if pos.y > @max.y pos.y -= delta.y prev.y -= delta.y if pos.z > @max.z pos.z -= delta.z prev.z -= delta.z toString: -> "Wrap3(#{@min}, #{@max})" ### Stops particles from colliding with each other. ### class Collision extends Constraint physics: null # bouncyness: 1 constructor: (@physics, @searchRadius = 100) -> apply: (particle) -> position = particle.position delta = position.clone() neighbours = @physics.space.search position, @searchRadius # if particle.id == 0 # console.log "found #{neighbours.length} particles" for neighbour in neighbours continue if neighbour == particle # vector from particle to neighbour delta.set(position).sub neighbour.position distSq = delta.lengthSquared() radius = particle.size + neighbour.size radiusSq = radius * radius if distSq < radiusSq dist = Math.sqrt distSq delta.scale (dist - radius)/ radius * 0.5 # slightly faster method # delta.scale (distSq - radiusSq)/ radiusSq * 0.25 particle.position.sub delta neighbour.position.add delta undefined undefined toString: -> "Collision(#{@searchRadius})" module.exports = Box: Box Area: Area Wrap2: Wrap2 Wrap3: Wrap3 Collision: Collision