Announcement

Collapse
No announcement yet.

[Video][Code] How to Get a Perpendicular Vector,optionally relative to Actor Rotation

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [Video][Code] How to Get a Perpendicular Vector,optionally relative to Actor Rotation

    Dear Community,

    Here's the code to find a vector that is perpendicular to a given vector!

    You also have the option of using a version of this code that will find a perpendicular vector relative to a given Actor's Rotation.

    See the video for examples of both!







    Code:
    //put this code in your player object class
    //does not need to be in HUD
    //since using drawdebugline
    //note debugline is slow
    //only used for testing purposes
    //I use my custom drawThickline
    //in the video
    
    //get perp line
    function vector getStaticPerpVectorTo(vector v1){
    local vector v2;
    
    v2.x = v1.z; 
    v2.y = v1.z; 
    v2.z = -v1.x - v1.y;
    
    if(isZero(v2)){
       v2.x = -v1.y - v1.z;
       v2.y = v1.x;
       v2.z = v1.x; 
    }
    
    return v2;
    }
    
    //get perp line
    function vector getPerpVectorTo(vector v1){
    local vector v2;
    local vector x, y, z;
      
      //based on rotation of this player object/Self
      //thanks for reminder about getaxes Spoof!
      getaxes(Rotation, x, y, z);
      
      v2 = v1 cross X;
      if(isZero(v2))
        v2 = v1 cross Y;
      if(isZero(v2))
        v2 = v1 cross Z;
    	
    return v2;
    }
    
    function DrawPerps() {
    	local int v;
    	local rotator angle;
    	local vector v1;
    	local vector v2;
    	local float len;
    	
    	len = 256;
    
    	//draw along yaw
            angle.yaw = 0;
    	for (v = 0; v < 50; v++ ) {
    	  v1 = Location;
    	  v1 += Vector(angle) * len;
    	   DrawDebugLine(Location, v1, 0, 0,255);
    	   v2 = getPerpVectorTo(v1 - Location);
    	   DrawDebugLine(v1, v1 + v2, 255, 0, 0);
    		
    	   angle.yaw += 20 * degtounrrot;	
    	}
    	
               //draw along pitch
    	 angle.yaw = 0;
    	 angle.pitch = 20;
    	 for (v = 0; v < 50; v++ ) {
    	    v1 = Location;
    	    v1 += Vector(angle) * len;
    	    DrawDebugLine(Location, v1, 0, 0,255);
    	    v2 = getPerpVectorTo(v1 - Location);
    	    DrawDebugLine(v1, v1 + v2, 255, 0, 0);
    		
    	    angle.pitch += 20 * degtounrrot;	
    	}
    }
    Make sure to call DrawPerps() in a tick() function, or have the drawdebugline bool set to TRUE for making the lines last permanently and only call it once.

    but for the dynamic version you should definitely use tick()

    but you probably don't need to DrawPerps(), that was just for the video

    have fun with your perpendicular lines for whatever your project is


    ~~~

    How to Draw Thick 3D Lines

    Here's the code I use in the video for thick 3d lines

    I wrote it all from scratch

    Code:
    //In your HUD class
    function drawThicker(vector v1, vector v2, color c, int PosFromCenter) {
    	local vector start;
    	local vector end;
    	
    	//so we can modify
    	start = v1;
    	end = v2;
    	
    	start.x += PosFromCenter;
    	end.x += PosFromCenter;
    	draw3DLine(start, end, c);
    	
    	start.y += PosFromCenter;
    	end.y += PosFromCenter;
    	draw3DLine(start, end, c);
    	
    	start.z += PosFromCenter;
    	end.z += PosFromCenter;
    	draw3DLine(start, end, c);
    	
    	start.x -= PosFromCenter*2;
    	end.x -= PosFromCenter*2;
    	draw3DLine(start, end, c);
    	
    	start.y -= PosFromCenter*2;
    	end.y -= PosFromCenter*2;
    	draw3DLine(start, end, c);
    	
    	start.z -= PosFromCenter*2;
    	end.z -= PosFromCenter*2;
    	draw3DLine(start, end, c);
    }
    function drawThickLine(vector v1, vector v2, color c, int thickness) {
    	local int thickIncrement;
    	
    	//center of line
    	draw3DLine(v1, v2, c);
    	
    	//draw surrounding layers of thickness from center
    	for (thickIncrement = 1; thickIncrement <= thickness; thickIncrement++ ) {
    		drawThicker(v1, v2, c, thickIncrement);
    	}
    }
    Example use:

    Code:
    drawThickLine(v1,v2,makeColor(255,0,0),6);
    ~~~

    Summary

    With this code you can find perpendicular lines / vectors in 3D space, given either just a vector, or a vector and an actor's Rotation!

    Enjoy!

    Rama

    #2
    Hey Rama,

    I decided to go back through the gravity code to fix some things and make it truly like gravity where it effects everything in the map and changes its pull on the ships dynamically based on momentum etc etc.

    Anyway I wanted to use this to see where my earth was exactly pushing my ship because sometimes it pushes it in a slightly off direction from where I am facing. Other times if I roll the ship so that I am upside down relative to the earth it pushes me the exact opposite direction.

    When I try to draw the perp line it draw its always into earth even though it is pushing me across earth, so how would I modify this to show where the push is coming from?
    Code:
    function getHorizontal(){
    local vector v1;
    	local vector v2;
    local Vector shipToPlanetVector;
    
    
      //get local orientation of ship
    	if(!enginesoff)
    	{
    	  GetAxes( self.Rotation, orbitX, orbitY, orbitZ );
    	  //enginesoff = true;
    	}
    
      //get line/vector between ship and planet
      shipToPlanetVector = SpaceBearsType(WorldInfo.Game).planetWORLD.Location - self.Location;
    	if (VSize(SpaceBearsType(WorldInfo.Game).planetWORLD.Location - self.Location) < 110000)
    		range = false;
    	else range = true;
      //cross product is 0 if both vectors are on same axis
      
      //but no planet-ship vector could be on same axis
      //as all 3 of ship's axes
      //so below code finds 2 non coaxial vectors
      //and result will be vector perpendicular
      //to the ship-planet vector
    
      perpVector = shipToPlanetVector cross orbitY;
    
      if(isZero(perpVector))
         perpVector = shipToPlanetVector cross orbitX;
     
      if(isZero(perpVector))
         perpVector = shipToPlanetVector cross orbitZ;
      
    	v1 = self.Location;
    
    	
      //addimpulse
      perpVector = Normal(perpVector);
      perpVector *= horizontalGravityForce;
      `log("PerP: " $perpVector);
      DrawDebugLine(v1, perpVector, 0, 0, 255);
      self.collisionComponent.addimpulse(perpVector);
    }

    Comment


      #3
      Any advice on this?

      Comment


        #4
        you need to start from the ships location when going in the direction of perpVector

        Code:
        DrawDebugLine(v1, v1 + perpVector, 0, 0, 255);
        perpVector is a DIRECTION * a length of horizontalGravityForce,

        and so it is close to origin, where probably your planet is nearer to at all times than your ship

        to get a line the way you want you have to tell the DIRECTION to start from your ship



        Rama

        ps: for other readers,

        Code:
        v1 = self.Location;
        and Self is the ship whose class this code is in

        Comment


          #5
          Oh duh... can't believe I didn't see that.

          That lines helps a lot, hopefully I can figure out the other issues with the gravity now that I can see exactly what its doing.

          I'm assuming
          Code:
          perpVector = shipToPlanetVector cross orbitY;
          is the trouble maker since perpvector flips 180 degrees when i roll the ship with its back to the center of earth but I will play with it.

          Thanks for the reply!

          Comment

          Working...
          X