Author Topic: Another issue with vectors/position  (Read 374 times)

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Another issue with vectors/position
« on: August 18, 2013, 10:01:23 pm »


               Hi, Im working on a feat that allows deflect ranged touch spell. It works well, but Im having problem with positioning the deflect area. Often happens that the target deflects the beam behind himself.

What I would like is to position the deflected beam only at 45° from the original line between caster and target

I draw image to explain it better:
'Posted
A - caster
B - target
pink line = original spell beam

and I would like to position the deflect impact somewhere between the orange lines in 90° angle.


so far I have this code if it helps:

  else if(nTouch < 0)//deflected by monk
  {
  vector v = GetPosition(spell.Target);
  v.x+= d4();
  v.x-= d4();
  v.y+= d4();
  v.y-= d4();
  location l = Location(GetArea(spell.Target),v,GetFacing(spell.Target));
  object newTarget = CreateObject(OBJECT_TYPE_PLACEABLE,"x0_rodwonder",l);
  DestroyObject(newTarget,2.0);
  ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBeam(VFX_BEAM_COLD, spell.Target, BODY_NODE_CHEST), newTarget, 1.7);
  }


               
               

               


                     Modifié par ShaDoOoW, 18 août 2013 - 09:02 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Another issue with vectors/position
« Reply #1 on: August 19, 2013, 12:41:27 am »


               subtract Position B from position A.  
That will give you the vector that A is from B.  I will call this vector vBaseVector.


To get the random angle of deflection  simply convert the vBaseVector to an angle.  add your  + or - 45 degrees. ( Random(90) - 45)  and convert it back into a vector.   This vector will have a magnitude of 1.   So multiply it by the distance you want it to be from the target, then simply add the vector to the  position of point B    to get your deflection position.  



EDIT: 

location GetDeflectionLocation( object oAttacker, object oDeflector, float fDist)
{
  vector  pDeflector = GetPosition( oDeflector);
  vector  vBaseVector = GetPosition(oAttacker) - pDeflector;

  vector vDeflect=AngleToVector(VectorToAngle ( vBaseVector) + Random(90)-45 );
  vDeflect *= fDist;

  return    Location
                    (
                         GetArea(oDeflector),   //oArea
                         pDeflector + vDeflect, //vPosition
                         0.0                    //fOrientation
                    );
}
               
               

               


                     Modifié par Lightfoot8, 19 août 2013 - 12:25 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Another issue with vectors/position
« Reply #2 on: August 19, 2013, 02:05:41 am »


               awesome Lightfoot8, thank you. Havent expected I get the help so fast.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Another issue with vectors/position
« Reply #3 on: August 19, 2013, 02:43:31 am »


               and works like a charm!
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Another issue with vectors/position
« Reply #4 on: August 19, 2013, 03:43:24 am »


               Do you have a good resource discussing vector math in depth? The Lexicon isn't much use in that regard.

Thanks,
Funky
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Another issue with vectors/position
« Reply #5 on: August 19, 2013, 07:16:17 am »


               Vectors are rather simple to use once you get a grasp of what they are.  

A Vector is simply the change in X and the Change in Y from any given point or (ΔX, ΔY) where Δ represents a change.

when you add two vectors together  you are simply adding the x's together and the y's together.
i.e.   v(x1,y1) + v(x2,y2)  = (x1+x2 , y1+y2)  

when you multiply or divide  a vector by a number  you are doing that operation to both elements in the vector.
  i.e.  v( x, y) * 2 = v( 2x ,2y)   // this basically effects the magnitude of the vector only.

given a vector you can associate both an angle and a magnitude (Distance) to it.  If we had the vector (2,2)  two up and two to the right, after doing a little math we could figure out that it has an angle of 45 degrees and a magnitude(length) of 2.83 .  

any vector that has a length of 1 is said to be normalized. Normalizing a vector leaves the current angle but changes the magnitude to 1.  

The above v(2,2) vector normalized would be v(0.707, 0.707), same 45 degree angle and a length of 1.  

A Position  is simply a vector from the origin or point 0.0 on the grid.  

adding a vector  to a Position simply gets the point that is at distance (magnitude) and angle away from the position.  example  pos( 5,4) + v(2.2) =  pos( 7,6). the point that is at 45 degrees and 2.83 distance from pos(5,4).

I know not easy to follow yet.   So lets use some nwn examples.  




Problem.   We have a guard that we want to walk 5m forward.  

The first thing we need to find is the angle that the guard is facing.
then change that facing into a vector wich will already be normalized to have a distance of 1.
we then simply multiply that vector by 5 to increase its length (magnitude) to 5.
adding this magnitude 5 vector to the position of the guard will give us the position 5m in the direction the guard was facing.
 

float   fFacing = GetFacing( oGuard);
vector vFacing = AngleToVector( fFacing);
vFacing = vFacing * 5.0:
vector vNewPosition = GetPosition(oGuard) + vFacing;

there you have it your new position to wrap up into your location and move the guard to.  




problem.   Finding the point half way between  a guard (oGuard) and a target (oTarget)

Since a vector is simply the change in x and y between two points we can get the vector that oTarget is from oGuard by  subtracting the position of oGuard from the position of oTarget.
to find the half way point we just need a vector with the same angle and half the magnitude or a vector with half the change in x and y.  That is simply dividing the vector by 2.

So the point that is half way between  is.

vector  posGuard = GetPosition ( oGuard);
vector  vToTarget  = GetPosition( oTarget) - posGuard;
vector  posHalfWayPoint = posGuard + vToTarget / 2.0;


I hope that helps.
L8
 

Edit:  To answer the question youtube does have some good vidios on vector algerbra.  But in my opion most of it goes way to far into trig.   The whole point in using vectors in nwn is to use the internal function so that you do not have to do the trig.  but it never does hurt to watch the vids. 


http://www.youtube.c...ube.kmfSBg38VCw
               
               

               


                     Modifié par Lightfoot8, 19 août 2013 - 07:57 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Another issue with vectors/position
« Reply #6 on: August 19, 2013, 07:52:48 pm »


               Thanks very much, I think the missing link for me was the assumed magnitude of 1. I'll watch the video when I get home.

Funky
               
               

               
            

Legacy_Squatting Monk

  • Hero Member
  • *****
  • Posts: 776
  • Karma: +0/-0
Another issue with vectors/position
« Reply #7 on: August 19, 2013, 11:33:22 pm »


               Thanks, Lightfoot. This is gold.