# Is there any way to get the position ( x, y, z) from a function parameter?

was trying to build a flag based on the cloth example in the three.js documentation but I have trouble in defining the constraints for the flag.
https://threejs.org/examples/#webgl_animation_cloth
Source code of the example: https://github.com/mrdoob/three.js/blob/e0a31ea77c0242ae29ef6e951fa588216e1d247f/examples/webgl_animation_cloth.html

I had already tried my best to comment every block of code since the code has ~300 lines.

In my interpretation, `function SatisfyConstraints` makes a subtraction between two points in order to get the differentiation vector . Then it calculates the length and derive corrections from it.
The āsimulateā function at the end of the code uses `SatisfyConstraints` to regulate how the flag should be flown.

``````var container, renderer, scene, camera, controls;
var near, far;
``````
``````var params = {
enableWind: true,
showBall: false
}
var DAMPING = 0.03;
var MASS = 0.15;
var DRAG = 1 - DAMPING;
var DistanceUntilRest = 25;
var GRAVITY = 981 * 1.4;
var gravityVector = new THREE.Vector3( 0, - GRAVITY, 0 ).multiplyScalar( MASS );  // F = mg
var ForceVector = new THREE.Vector3();
var windForce = new THREE.Vector3( 0, 0, 0 );

var TIMESTEP = 18 / 1000;
var TIMESTEP_SQ = TIMESTEP * TIMESTEP;

var xSegs = 10, ySegs = 10;

var clothFunction = planeEquation( DistanceUntilRest * xSegs,  DistanceUntilRest * ySegs );
var cloth = new Cloth(xSegs, ySegs);

function planeEquation (width, height) {
return function (a, b, target) {
var x = (a - 0.5) * width;
var y = (b + 0.5) * height;
var z = 0;  // idk why z has to be 0
target.set( x, y, z);
}
}

function Particles (x, y, z, mass) {
this.position = new THREE.Vector3();
this.previous = new THREE.Vector3();
this.original = new THREE.Vector3();
this.acceleration = new THREE.Vector3( 0 , 0 , 0);
this.mass = mass;
this.invMass = 1 / mass;
this.FVector = new THREE.Vector3();
this.tmp = new THREE.Vector3();

// initializing clothFunction so planeEquation can set the target

clothFunction(x, y, this.position);
clothFunction(x, y, this.previous);
clothFunction(x, y, this.original);

};

// after each time sequence the new position adds itself by the amount of drag and acceleration

Particles.prototype.integrate = function (timeSequence) {
var newPos = this.tmp.subVectors(this.position, this.previous);

// passes tmp down to this.previous then assumes this.position as the new position

this.tmp = this.previous;
this.previous = this.position;
this.position = newPos;

// resetting acceleration

this.acceleration.set(0, 0, 0);
}

var diff = new THREE.Vector3();

function SatisfyConstraints (point, next_point, distance) {
diff.subVectors(next_point.position, point.position);
var currentDist = diff.length();
if (currentDist === 0) return;

var correction = diff.multiplyScalar(1 - distance / currentDist);
var correctionHalf = correction.multiplyScalar(0.5);
next_point.position.sub( correctionHalf );
}
function Cloth(width, height) {
this.width = width || 10;
this.height = height || 10;

var particles = [], constraints = [];
var i, j, u, v;

for (i = 0; i <= height; i++ ) {
for (j = 0; j <= width; j++) {
particles.push( new Particles( i / width, j / height, 0, MASS) )
}
}

// Providing structure for cloth - similar to drawing
for (i = 0; i <= height; i++ ) {
for (j = 0; j <= width; j++) {
constraints.push([
particles[index(i, j)],
particles[index(i, j + 1)],
DistanceUntilRest
]);

constraints.push([
particles[index(i, j)],
particles[index(i + 1, j)],
DistanceUntilRest
])
}
}

for ( u = width, v = 0; v < height; v ++ ) {
constraints.push( [
particles[ index( u, v ) ],
particles[ index( u, v + 1 ) ],
DistanceUntilRest
] );
}

for ( v = height, u = 0; u < width ; u ++ ) {
constraints.push( [
particles[ index( u, v ) ],
particles[ index( u + 1, v ) ],
DistanceUntilRest
] );
}

this.particles = particles;
this.constraints = constraints;

function index( u, v ) {
return u + v * ( width + 1 );
}
this.index = index;
}

function simulate( time ) {
if ( ! lastTime ) {
lastTime = time;
return;
}
var i, j, il, particles, particle, constraints, constraint;
// Aerodynamics forces
if ( params.enableWind ) {
var indx;
var normal = new THREE.Vector3();
var indices = clothGeometry.index;
var normals = clothGeometry.attributes.normal;
particles = cloth.particles;
for ( i = 0, il = indices.count; i < il; i += 3 ) {
for ( j = 0; j < 3; j ++ ) {
indx = indices.getX( i + j );
normal.fromBufferAttribute( normals, indx );
tmpForce.copy( normal ).normalize().multiplyScalar( normal.dot( windForce ) );
}
}
}
for ( particles = cloth.particles, i = 0, il = particles.length; i < il; i ++ ) {
particle = particles[ i ];
particle.integrate( TIMESTEP_SQ );
}
// Start Constraints
constraints = cloth.constraints;
il = constraints.length;
for ( i = 0; i < il; i ++ ) {
constraint = constraints[ i ];
SatisfyConstraints( constraint[ 0 ], constraint[ 1 ], constraint[ 2 ] );
}

var pos;

// Ball Constraints
ballPosition.z = - Math.sin( Date.now() / 600 ) * 90; //+ 40;
ballPosition.x = Math.cos( Date.now() / 400 ) * 70;
if ( params.showBall ) {
sphere.visible = true;
for ( particles = cloth.particles, i = 0, il = particles.length; i < il; i ++ ) {
particle = particles[ i ];
pos = particle.position;
diff.subVectors( pos, ballPosition );
if ( diff.length() < ballSize ) {
// collided
diff.normalize().multiplyScalar( ballSize );
}
}
} else {
sphere.visible = false;
}
// Floor Constraints
for ( particles = cloth.particles, i = 0, il = particles.length; i < il; i ++ ) {
particle = particles[ i ];
pos = particle.position;
if ( pos.y < - 250 ) {
pos.y = - 250;
}
}
}
``````

I also attempted to use ` position.copy(point), position.copy(next_point) ` in ` SatisfyConstraints) ` to copy the coordinates and paste the passed parameters into a new variable but it doesnāt work.

``````function SatisfyConstraints (point, next_point, distance) {
var pointPos, next_pointPos;
pointPos.position.copy(point);
next_pointPos.position.copy(next_point);
diff.subVectors(pointPos, next_pointPos);
...
}
``````

Iād expected `SatisfyConstraints` to function as usual but instead I received the error message as follows:

Uncaught TypeError: Cannot read property āpositionā of undefined
at SatisfyConstraints (simulation3D.html:102)
at simulate (simulation3D.html:212)
at animate (simulation3D.html:419)

That is because pointPos is undefined. You have only declared it with `var pointPos`.

Even if I define pointPos as a new THREE.Vector3() it still wonāt work.

`Vector3` has no `position` property. `Object3D` has, though. I guess you mean:

``````var pointPos = new THREE.Vector3();
pointPos.copy(point);
``````

if `point` is a `Vector3`, or

``````var pointPos = new THREE.Vector3();
pointPos.copy(point.position);
``````

if `point` is an `Object3D`.

Yeah exactly.
I never thought about Object3D at all. .Thanks a lot

1 Like