Get value from vectors by index

Hello,
my sugestion is to add a at(index) and setAt(index, v) to the vectors. For example:
with at and setAt, we can avoid the code repetion to check each value of the vector.

    let v = new BABYLON.Vector3(1,2,3)
    let p = new BABYLON.Vector3(4,5,6)
    if (v.x > p.x)
      //do something
    else if (v.y > p.y)
      //do something
    else if (v.z > p.z)
      //do something

Note we check which value with the dot operator. If Vectors had a at(index) our code stays more simple:

    let v = new BABYLON.Vector3(1,2,3)
    let p = new BABYLON.Vector3(4,5,6)
    for (let i = 0; i < 3; i++)
      if (v.at(i) > p.at(i))
        //do something

With setAt, we just use something like:

    for (let i = 0; i < 3; i++)
      v.setAt(i, 42) //for set to 42

Sorry, the code formating doesn’t not format here.

To format code use ```javascript before the code see Hello, I am a little confused about a lot of things - #3 by Vinc3r

let v = new BABYLON.Vector3(1,2,3)
let p = new BABYLON.Vector3(4,5,6)
if (v.x > p.x) {
    //do something
} else if (v.y > p.y) {
    //do something
} else if (v.z > p.z) {
    //do something
}

For me the occasional coding advantage of using at and setAt is outweighed by the loss in readability.

Ok, thanks for the help with formating.

The at and setAt will be only used on some special cases.
For example:
Yesterday I had to do a code like this:

look as the code stays without at and setAt
v, p, min, max are Vector3
if (v.x < 0)
  p.x = (p.x - min.x) / p.x;
else if (v.x > 0)
  p.x = (p.x - max.x) / p.x;

if (v.y < 0)
  p.y = (p.y - min.y) / p.y;
else if (v.y > 0)
  p.y = (p.y - max.y) / p.y;

if (v.z < 0)
  p.z = (p.z - min.z) / p.z;
else if (v.z > 0)
  p.z = (p.z - max.z) / p.z;

Now, look as the code stays with at and setAt:

for (let i = 0; i < 3; i++) {
  if (v.at(i) < 0)
    p.setAt(i, (p.at(i) - min.at(i)) / p.at(i));
  else if (v.at(i) > 0)
    p.setAt(i, (p.at(i) - max.at(i)) / p.at(i));
}

At and setAt will not substitue the dot operator, but is just to facilitate iterates over the vectors. And, in some cases like the above, it will facilitate the iteration over the vector.

You can do this right now though:

for (let i of ['x', 'y', 'z']) {
  if (v[i] < 0)
    p[i] = (p[i] - min[i]) / p[i];
  else if (v[i] > 0)
    p[i] = (p[i] - max[i]) / p[i];
}
2 Likes

Hi @cpusam

Given the use-case would be rare, why not include a small snippet locally in your project?

BABYLON.Vector3.prototype.at = function(index){
    switch(index){
        case 0:
            return this.x;
        case 1:
            return this.y;
        case 2:
            return this.z;
        default:
            return 'NaN';
    }
}

BABYLON.Vector3.prototype.setAt = function(index, value){
    switch(index){
        case 0:
            this.x = value;
            break;
        case 1:
            this.y = value;
            break;
        case 2:
            this.z = value;
            break;
        default:
            throw Error('No such index: '+index+' in Vector3');
            break;
    }
}
1 Like

@Gijs wow man, so simple! With this, now I agree that there isn’t need for at and setAt.
@aWeirdo I did something like this, but not directly added the at and setAt, cool idea.

1 Like

@cpusam ;
@Gijs solution is indeed nice and simple :smiley:, but carefully note that for-of is ES6.

You can check browser compatibility at the bottom of the following page & be sure it’s compatible for your needs;

As a side-note i suggest declaring and reusing [‘x’, ‘y’, ‘z’] as a global variable.

var vec3Indexes = ['x', 'y', 'z'];

... let i of vec3Indexes 

:slight_smile:

2 Likes

@aWeirdo ok man, thanks for the help. I use only ES6 on my projects, but it’s a good idea to know about browser compatibility.