agent

seek, group

by jmcjc5u

HTML

<div id="info">Agents</div>
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js">


</script>

CSS

#info {
  position: absolute;
  top: 0px;
  width: 100%;
  padding: 10px;
  text-align: center;
  color: #ffff00
}

body {
  overflow: hidden
}

JavaScript

class PDControllerR2 {
  constructor(x = 0, y = 0, xref = 0, yref = 0) {
    this.x = x;
    this.xref = xref;
    this.y = y;
    this.yref = yref;
    this.vx = 0;
    this.vy = 0;
    this.KP = 150; // 'spring constant'
    this.KD = 20; // 'damping'
  }

  update(dt) {
    let fx = -this.KP * (this.x - this.xref) - this.KD * this.vx;
    let fy = -this.KP * (this.y - this.yref) - this.KD * this.vy;
    this.vx += fx * dt;
    this.x += this.vx * dt
    this.vy += fy * dt;
    this.y += this.vy * dt
    return [this.x, this.y]
  }
  setRef(xref, yref) {
    this.xref = xref;
    this.yref = yref;
  }
}
function setTarget(rawAngle) {
	// convert angle to (x,y) on unit circle
  return [Math.cos(rawAngle), Math.sin(rawAngle)]
}

class Agent {
  constructor(pos, mesh) {
    this.pos = pos.clone();
    this.vel = new THREE.Vector3();
    this.force = new THREE.Vector3();
    this.target = new THREE.Vector3();
    this.size = 3;
    this.mesh = mesh;
    this.MAXSPEED = 50;
    this.ARRIVAL_R = 30;
    this.nbhd = [];
    
    // for orientable agent
    this.angle = 0;
  }
  update(dt) {
    this.accumulateForce();
    this.vel.add(this.force.clone().multiplyScalar(dt));
    // velocity modulation
    let diff = this.target.clone().sub(this.pos)
    let dst = diff.length();
    if (dst < this.ARRIVAL_R) {
      this.vel.setLength(dst)
    }
    this.pos.add(this.vel.clone().multiplyScalar(dt))
    this.mesh.position.copy(this.pos)
    
    // for orientable agent
    // non PD version
    if (this.vel.length() > 0.1) {
	    	this.angle = Math.atan2 (-this.vel.z, this.vel.x)
    		this.mesh.rotation.y = this.angle
   	}
 /*   
    if (this.vel.length() > 0.1) {
    
        let target = setTarget(Math.atan2 (-this.vel.z, this.vel.x));
        pdControl.setRef(target[0], target[1]);
    
				let pos = pdControl.update (0.01);
  
  			// convert back to theta
  		  this.angle = Math.atan2(pos[1],pos[0])
    		this.mesh.rotation.y = this.angle
    }
    
 */
  }
 ...