Why vector.nomalize() do not print 1?

// Ex 1.6 Normalizing a vector The Nature of Code

void draw() {
background(255);
PVector mouse = new PVector(mouseX,mouseY);
PVector center = new PVector(width/2,height/2);
//sub() — subtract vectors
mouse.sub(center);
//normalize() — normalize the vector to a unit length of 1
mouse.normalize();
//mult() — scale the vector with multiplication
//mouse.mult(50);
//mag() — calculate the magnitude of a vector
print(mouse.mag());
//https://processing.org/reference/translate_.html
translate(width/2,height/2);
line(0,0,mouse.x,mouse.y);
noLoop();

}

/*
In this example, after the vector is
normalized, it is multiplied by 50 so that it is
viewable onscreen. Note that no matter
where the mouse is, the vector will have the
same length (50) due to the normalization
process.
*/

// Why nomalize() do not output 1, instead give 0.99999994?

1 Like

-a- please format your code and reduce it to the problem point,
so it looks like

PVector mouse = new PVector(mouseX,mouseY);

void setup() {
  size(200,200);
  fill(0);
}

void draw() {  
  background(200,200,0);
  mouse.set(mouseX,mouseY);
  mouse.normalize();
  text("X "+mouseX+" Y "+mouseY+" norm mag "+nf(mouse.mag(),1,8),10,10);
}

-b- check on the used function
https://processing.org/reference/PVector_mag_.html
it states that the result is a float.

-c- yes, the shown result jumps between 1.0 and 0.99999994

-d- i would say that is more a general question about using float numbers on any computer, any programming language.
the resolution is limited to certain number range, here JAVA
https://processing.org/reference/float.html

-e- so it is inherent to a calculation, but to avoid that SHOW of a strange number
can use function like
https://processing.org/reference/nf_.html

The internal representation of a vector is x,y. It will assign the x,y that approximates length 1.
Note that it won’t find the closest possible float representation of that magnitude – only the closest possible one along the current line.

If we don’t care as much about the heading as about the length, it is often easy to find neighboring x and y values that are closer to length 1.0. Here is a very simple example that just checks if a slightly higher x value gives a magnitude that is closer to 1.0:

void setup() {
  frameRate(1);
}
void draw() {
  PVector vec = new PVector(random(10), random(10));
  println();
  println(vec, vec.mag());

  vec.normalize();
  println(vec, vec.mag(), "normed");

  float nudged = Math.nextUp(vec.x);
  if (abs(1.0 - nudged) < abs(1.0 - vec.x)) {
    vec.x = nudged;
    println(vec, vec.mag(), "nudged");
  } else {
    println("not nudged");
  }
}

So, we can often nudge a normalized vector to make its .mag() display even closer to 1.0 length – HOWEVER, in doing so, we slightly changed its angle clockwise or counterclockwise. What normalize does instead is prioritizes preserving angle.

Keep in mind that these are very small values – and they almost are all approximations whether or not they appear to be .9999994 or 1.0 etc. It isn’t that one is imprecise and the other isn’t. They are both / all imprecise.

For example, if you look closely at the output, you will see that all combinations of nudging are “closer” or “not closer”:

// nudged, displays as 1.0
[ 8.462109, 5.3119826, 0.0 ] 9.991219
[ 0.8469546, 0.53166515, 0.0 ] 0.99999994 normed
[ 0.84695464, 0.53166515, 0.0 ] 1.0 nudged

// nudged, still displays as .99
[ 0.36812425, 7.538138, 0.0 ] 7.5471215
[ 0.048776776, 0.99880964, 0.0 ] 0.99999994 normed
[ 0.04877678, 0.99880964, 0.0 ] 0.99999994 nudged

// did display as 1.0, still nudged, still displays as
[ 1.9437051, 9.681125, 0.0 ] 9.874318
[ 0.19684449, 0.9804348, 0.0 ] 1.0 normed
[ 0.1968445, 0.9804348, 0.0 ] 1.0 nudged

// nudged past 1.0, still closer than "1.0" !
[ 9.634562, 5.9459205, 0.0 ] 11.321605
[ 0.85098904, 0.52518356, 0.0 ] 1.0 normed
[ 0.8509891, 0.52518356, 0.0 ] 1.0000001 nudged

// displays .99, nudging doesn't make it closer
[ 0.1304692, 8.879499, 0.0 ] 8.880458
[ 0.014691721, 0.99989206, 0.0 ] 0.99999994 normed
not nudged

// etc.
1 Like

Dear KLL
Thanks for your explanation!
Best!
Andres

Dear Jeremy
Thanks for your answer!
Best
Andres