Jump to content

math related question, impress everyone and solve it!


Slothman

Recommended Posts

I am need of a way that a client could calculate the angles of a surface.

i need to be able to take 2 xyz coords and detect if an object is between them (easy so far using processlineofsight)

but if there is something blocking the line, then i need to know its surface angle. I imagine this would be done by measuring the coords of 3 or 4 parralell lines of sight and using them to calculate the angle of the item. this is where im stuck.

I threw together this diagram to help you see what i mean:

mathpuzzlea.png

keep in mind it needs to be 3d, not 2d, and the angles would be needed for placing objects. any pointing in the right direction would be appreciated from any math whizzes

Link to comment

what about using 2 of these functions https://wiki.multitheftauto.com/wiki/Useful_Functions

something like

  
function getLineHitAngle(Point1X, Point1Y, Point1Z, Point2X, Point2Y, Point2Z) 
    local Hit, HitX, HitY, HitZ = processLineOfSight(Point1X, Point1Y, Point1Z, Point2X, Point2Y, Point2Z) 
    if Hit then 
        local LineAngle = findRotation(Point1X, Point1Y, Point2X, Point2Y) 
        local LineDistance = 2 
        local Point3X, Point3Y = getPointFromDistanceRotation(Point1X, Point1Y, LineDistance, LineAngle - 90) 
        local Point4X, Point4Y = getPointFromDistanceRotation(Point2X, Point2Y, LineDistance, LineAngle - 90) 
         
        local Hit2, Hit2X, Hit2Y, Hit2Z = processLineOfSight(Point3X, Point3Y, Point1Z, Point4X, Point4Y, Point2Z) 
        if Hit2 then 
            return findRotation(HitX, HitY, Hit2X, Hit2Y) - LineAngle 
        end 
    end 
    return false 
end 
  

Link to comment

thanks, that really got me started. It'll need some back up parts for when the calculations dont make sense (like a player aims too close to a corner)

one of the uses for this is to update my grapple script, but this sort of calculation could be used to add things like bullet hole marks, spray tags, blood splatters, etc.

so heres part of the script so far:

function getPointFromDistanceRotation(x, y, dist, angle) 
    local a = math.rad(90 - angle); 
    local dx = math.cos(a) * dist; 
    local dy = math.sin(a) * dist; 
    return x+dx, y+dy;  
end 
  
function findRotation(x1,y1,x2,y2) 
    local t = -math.deg(math.atan2(x2-x1,y2-y1)) 
    if t < 0 then t = t + 360 end; 
    return t; 
end 
  
grapplegun = 26 --WHICH GUN WILL BE USED AS A GRAPPLE? 
gunrange = 80 --HOW FAR WILL THE GRAPPLE RANGE BE? 
  
  
function onClientPlayerWeaponFireFunc(weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement ) 
    if weapon == grapplegun then 
        if source == getLocalPlayer() then 
                         
            local Point1X, Point1Y, Point1Z = getPedTargetStart(getLocalPlayer()) 
            local lx, ly, lz = getPedTargetEnd(getLocalPlayer()) 
            local len = getDistanceBetweenPoints3D(Point1X, Point1Y, Point1Z, lx, ly, lz) 
            local Point2X = Point1X + (lx - Point1X)/len*gunrange 
            local Point2Y = Point1Y + (ly - Point1Y)/len*gunrange 
            local Point2Z = Point1Z + (lz - Point1Z)/len*gunrange 
         
            local Hit, HitX, HitY, HitZ = processLineOfSight(Point1X, Point1Y, Point1Z, Point2X, Point2Y, Point2Z) -- first line of sight 
            if Hit then 
             
             
                local LineAngle = findRotation(Point1X, Point1Y, Point2X, Point2Y) 
                local LineDistance = .2 
                local Point3X, Point3Y = getPointFromDistanceRotation(Point1X, Point1Y, LineDistance, LineAngle - 90) 
                local Point4X, Point4Y = getPointFromDistanceRotation(Point2X, Point2Y, LineDistance, LineAngle - 90) 
                 
                local Hit2, Hit2X, Hit2Y, Hit2Z = processLineOfSight(Point3X, Point3Y, Point1Z, Point4X, Point4Y, Point2Z) -- second line of sight, directly left 
                if Hit2 then 
                    angle = findRotation(HitX, HitY, Hit2X, Hit2Y) 
                end 
                             
                createObject ( 1318, HitX, HitY, HitZ ,90, 0, angle ) 
                 
            end 
        end 
    end 
end 
  
addEventHandler ( "onClientPlayerWeaponFire", getRootElement(), onClientPlayerWeaponFireFunc ) 

the problem with this is that it seems to jump 180 degrees when at certain angles. this would definitly be a problem for my purposes. any advice?

Link to comment

In case 1.1 is in use, processLineOfSight( ) has 3 nice variables to return, which are normalX, normalY, normalZ ( nothing else, but a surface normal ). To have 6 points is just enough to get angles you need, using getPointFromDistanceRotation( ) as been supposed.

This basically makes it possible to cast 1 ray instead of 2.

Link to comment

You need to cast a minimum of three rays, I think there are some edge cases that would require more.

You need to cast three rays with the same direction, in a triangle - let's call them rays A, B and C.

The angle ABC should be at 90 degrees along the direction of the ray.

Assuming all three rays hit, you should calculate the vectors B -> A and B -> C

Normalize those vectors.

Cross product those two vectors.

You should have the surface's normal.

You'll have problems if one vector doesn't hit (the very edge of an object) and also at the intersection of two objects, but if you make the distance between the rays as small as possible, you shouldn't really notice this.

It also won't work at very acute angles.

Or just wait for 1.1 :)

Link to comment

I don't know whether this may help or not, but on The_GTA's testing server there is a resource called "surface" and I asked what it was and he claims it's a default resource. I havnt seen if it is, but if it isn't I will try and get it and post it on here.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...