Greetings, GameDev community!
I'm currently working with Box2D, and I'm implementing an explosion-effect.
Therefore, I'm in need of a direction vector to be multiplied by the force (which is based on distance).
In order to make it appear as seamless as possile, I need to first transform the vector so that the highest value of the vector is 1. Let me show you;
A vector of (15, 10) would be (1, 6.67). As would a vector (30,15) be (1, 0.5).
Has anyone done this before and have a code snippet to share? The general theory / principle behind it would be sufficient as well.
Thanks in advance
//pimms
Vector transformation
Compute the maximum of the absolute values of the coordinates and divide every coordinate by it. Is that what you wanted?
i think you're looking for vector normalization to have a unit vector that is the direction? (the link is 3d, just remove any z from calculation and it's fine)
Thanks for the quick replies, guys. Appreciate it a lot
@alvaro
I'm not 100% sure of what you mean - what I've tried (without much success) is to first find the ratio between X and Y, based on the highest value.
If the highest value is > 1.0, I divide X and Y by the highest value. This produces some funny results, though.
If the highest value is < 1.0, I find the ratio by dividing 1 by the highest. Then X and Y is divided by ratio.
The current (faulty) code:
[source]
if ( vector.x > vector.y ) {
for (;;) {
if ( high < 1.0f ) {
ratio = 1.f / high;
x = high * ratio;
y = low * ratio;
break;
}
if ( high > 1.0f ) {
ratio = high / high;
x = high / ratio;
y = low / ratio;
break;
}
}
}
[/source]
@Hassanbasil
I've looked into normalizing the vector, but that would be quite the workaround for me, as I'm calculating the force to be applied as so;
[source]
body->ApplyForce( (hitVector*distance)*force, body->GetWorldCenter() );
[/source]
Where hitVector is the vector I'm trying to calculate.
@alvaro
I'm not 100% sure of what you mean - what I've tried (without much success) is to first find the ratio between X and Y, based on the highest value.
If the highest value is > 1.0, I divide X and Y by the highest value. This produces some funny results, though.
If the highest value is < 1.0, I find the ratio by dividing 1 by the highest. Then X and Y is divided by ratio.
The current (faulty) code:
[source]
if ( vector.x > vector.y ) {
for (;;) {
if ( high < 1.0f ) {
ratio = 1.f / high;
x = high * ratio;
y = low * ratio;
break;
}
if ( high > 1.0f ) {
ratio = high / high;
x = high / ratio;
y = low / ratio;
break;
}
}
}
[/source]
@Hassanbasil
I've looked into normalizing the vector, but that would be quite the workaround for me, as I'm calculating the force to be applied as so;
[source]
body->ApplyForce( (hitVector*distance)*force, body->GetWorldCenter() );
[/source]
Where hitVector is the vector I'm trying to calculate.
I came up with something that works somewhat decent, thought I'd share it as it might be of help to someone out there It's messy as shit, and could use a rewrite, but I'm satisfied considering it's 2:45 AM.
As mentioned, this function returns a vector scaled down to 1.
[source]
inline b2Vec2 scaleVecTo1( b2Vec2 vector ) {
//flag for reversing them to negative before return
bool invX=NO, invY=NO;
float x=0.f, y=0.f;
float ratio;
invX = vector.x < 0.f ? YES : NO;
invY = vector.y < 0.f ? YES : NO;
vector.x *= vector.x < 0.f ? -1.f : 1.f;
vector.y *= vector.y < 0.f ? -1.f : 1.f;
if ( vector.x > vector.y ) {
for (;;) {
if ( vector.x < 1.0f ) {
ratio = 1.f / vector.x;
x = vector.x * ratio;
y = vector.y * ratio;
break;
}
if ( vector.x > 1.0f ) {
ratio = vector.x / vector.x;
x = vector.x / ratio;
y = vector.y / ratio;
break;
}
}
}
if ( vector.x <= vector.y ) {
for (;;) {
if ( vector.y < 1.0f ) {
ratio = 1.f / vector.y;
y = vector.y * ratio;
x = vector.x * ratio;
break;
}
if ( vector.y > 1.0f ) {
ratio = vector.y / vector.y;
y = vector.y / ratio;
x = vector.x / ratio;
break;
}
}
}
x *= invX ? -1.f : 1.f;
y *= invY ? -1.f : 1.f;
return b2Vec2(x,y);
}
[/source]
As mentioned, this function returns a vector scaled down to 1.
[source]
inline b2Vec2 scaleVecTo1( b2Vec2 vector ) {
//flag for reversing them to negative before return
bool invX=NO, invY=NO;
float x=0.f, y=0.f;
float ratio;
invX = vector.x < 0.f ? YES : NO;
invY = vector.y < 0.f ? YES : NO;
vector.x *= vector.x < 0.f ? -1.f : 1.f;
vector.y *= vector.y < 0.f ? -1.f : 1.f;
if ( vector.x > vector.y ) {
for (;;) {
if ( vector.x < 1.0f ) {
ratio = 1.f / vector.x;
x = vector.x * ratio;
y = vector.y * ratio;
break;
}
if ( vector.x > 1.0f ) {
ratio = vector.x / vector.x;
x = vector.x / ratio;
y = vector.y / ratio;
break;
}
}
}
if ( vector.x <= vector.y ) {
for (;;) {
if ( vector.y < 1.0f ) {
ratio = 1.f / vector.y;
y = vector.y * ratio;
x = vector.x * ratio;
break;
}
if ( vector.y > 1.0f ) {
ratio = vector.y / vector.y;
y = vector.y / ratio;
x = vector.x / ratio;
break;
}
}
}
x *= invX ? -1.f : 1.f;
y *= invY ? -1.f : 1.f;
return b2Vec2(x,y);
}
[/source]
@alvaro
I'm not 100% sure of what you mean - what I've tried (without much success) is to first find the ratio between X and Y, based on the highest value.
I mean this:
inline b2Vec2 scaleVecTo1( b2Vec2 vector ) {
float m = std::max(std::abs(vector.x), std::abs(vector.y));
return b2Vec(vector.x/m, vector.y/m);
}
[font="Consolas,"] [/font]
alvaro's method is just what you're asking for - but what you're asking for doesn't seem to be the right way to do it, normalizing the vector and making it a unit vector is actually what looks suitable in your case, since it has the length of 1 (hence the name unit vector)
let's assume you have the vector (5,10), your desired method will make it (0.5,1), now calculate the length of it: sqrt(0.5*0.5+1*1) = sqrt(1.25) != 1
now the normalization method: sqrt((5 / sqrt(5 * 5 + 10 * 10))^2 + (10 / sqrt(5 * 5 + 10 * 10))^2) = 1
let's assume you have the vector (5,10), your desired method will make it (0.5,1), now calculate the length of it: sqrt(0.5*0.5+1*1) = sqrt(1.25) != 1
now the normalization method: sqrt((5 / sqrt(5 * 5 + 10 * 10))^2 + (10 / sqrt(5 * 5 + 10 * 10))^2) = 1
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement