So when you debug it does length come out as 0.0?

If so .. there is your problem. vector2d_length may be using a very poor square root …

Please log in or register to post a reply.

So when you debug it does length come out as 0.0?

If so .. there is your problem. vector2d_length may be using a very poor square root …

@Goz

Yes the length does come out as 0.0 and I have caught it many times using the assert macro. What do you mean by poor square root ? I’m using the sqrt function from math.h

@Goz

If so .. there is your problem. vector2d_length may be using a very poor square root …

I think it’s not the square root that’s the problem, it’s the quadratation of the components before doing the square root that causes trouble. A float has an 8-bit exponent ranging from -127 to 128. Squaring values between 0 and 1 effectively halves the exponent, so as soon as the values get smaller than around 2-64 (\~1e-20) you’re in trouble.

If you want to be able to normalize vectors with such small components, first scale them up, then normalize them.

Something like

```
vector normalize(vector v)
{
const float smallvalue = 1.0e-20f;
const float largevalue = 1.0e20f;
if ((abs(v.x) < smallvalue && abs(v.y) < largevalue) ||
(abs(v.y) < smallvalue && abs(v.x) < largevalue))
{
v.x *= smallvalue;
v.y *= smallvalue;
}
// do the rest of the normalization here
}
```

.edit: made it somewhat more robust.

vector2d_length computes the length as sqrt(x * x + y * y). So if x and/or y are very small then squaring them could result in underflow (zero), or denormal numbers (using only part of the normal precision). It’s possible that sqrt turns denormals into zero too.

The solution: scale both x and y up by a power of two (say 2\^20), then normalize.

@.oisyn

`vector normalize(vector v) { const float smallvalue = 1.0e-20f; const float largevalue = 1.0e20f; if ((abs(v.x) < smallvalue && abs(v.y) < largevalue) || (abs(v.y) < smallvalue && abs(v.x) < largevalue)) { v.x *= smallvalue;// here and v.y *= smallvalue;// here } // do the rest of the normalization here }`

Shouldn’t the multiplies be ‘largevalue’

@Blaxill

Shouldn’t the multiplies be ‘largevalue’

Yes I think it should be largevalue and we can apply the same logic for 3d vectors as well:

```
vector *vector_normalize(vector *a)
{
double length;
const double smallvalue = 1.0e-20;
const double largevalue = 1.0e20;
if ((fabs(a->x) < smallvalue && fabs(a->y) < largevalue && fabs(a->z) < largevalue) ||
(fabs(a->y) < smallvalue && fabs(a->x) < largevalue && fabs(a->z) < largevalue) ||
(fabs(a->z) < smallvalue && fabs(a->x) < largevalue && fabs(a->y) < largevalue))
{
a->x *= largevalue;
a->y *= largevalue;
a->z *= largevalue;
}
length = vector_length(a);
if (length != 0.0)
{
a->x /= length;
a->y /= length;
a->z /= length;
}
return (a);
}
```

- Upcoming Multiplatform Game Program...
- Our first game - looking for feedbacks
- Network Emulation Tool
- Trouble with accessing GLSL array
- Fiction
- Game Programming Patterns: Bytecode
- Interactive WebGL Water Demo
- Skeletal Animation Tutorial with GP...
- Unreal Engine 4
- Microsoft xbox one selling poorly

How do I handle this gracefuly ?

But what if I want to calculate some vector even when the components are very small ?? The above approach won’t normalize the vector and simply leave it as it is.