Rotating radar around player based on view direction

[lua]
hook.Add( “HUDPaint”, “Circle”, function()
local center = Vector( ScrW() - 75, ScrH() / 3, 0 )
local scale = Vector( 75, 75, 0 )
local segmentdist = 360 / ( 2 * math.pi * math.max( scale.x, scale.y ) / 2 )
surface.SetDrawColor( 200, 200, 200, 255 )

for a = 0, 360 - segmentdist, segmentdist do
	surface.DrawLine( center.x + math.cos( math.rad( a ) ) * scale.x, center.y - math.sin( math.rad( a ) ) * scale.y, center.x + math.cos( math.rad( a + segmentdist ) ) * scale.x, center.y - math.sin( math.rad( a + segmentdist ) ) * scale.y )
end
surface.DrawCircle(ScrW() - 75, ScrH() / 3, 5, Color(0,255,0) )

if InvRadarTable then
	for v,k in pairs(InvRadarTable) do
		if k:IsValid() then
			if k:IsNPC() then
				local relativePos =  LocalPlayer():GetPos() - k:GetPos()
				if relativePos.x > 1000 then
					relativePos.x = 1000
				end
				if relativePos.x < -1000 then
					relativePos.x = -1000
				end
				if relativePos.y > 1000 then
					relativePos.y = 1000
				end
				if relativePos.y < -1000 then
					relativePos.y = -1000
				end
				
				local eyeangrotate = EyeAngles()
				eyeangrotate.pitch = 0
				relativePos:Rotate(eyeangrotate)
				surface.DrawCircle(ScrW() - 75 + (relativePos.x)/20, ScrH() / 3 + (relativePos.y)/20, 5, Color(255,0,0) )
			end
		end
	end
end

end )
[/lua]

Ok so, I am working on my invasion gamemode and cant seem to get the hud correct. right now it works pretty good except for one issue, i cant seem to set the north position on the circle as the aim position of the player

here is a short video showing what i mean.

The radar rotates with the players aim angle but it also rotates with the location of the player…

**Vid taken down due to dropbox being a bitch about bandwidth

its not consistent with the rotation of the player

InvRadarTable = ents:GetAll() (Called every 3 seconds or so)

Snip, better info in my following posts.

the table if entities changes often, though currently just trying to get the radar to work atm

[editline]3rd May 2016[/editline]

need an example, i had basically what you were saying before and it just would not work for me…

I’m currently on my phone and wont have access to my computer probably until tomorrow. ill post a code example eventually.

i understand it matters in the long run, but currently in this faze for the hud it does not

Okay just letting you know, expect to see some code from me soon.

awesome, would help a ton, my main issue i think is rotating the angle. i dont really understand how that works. should i be using this

or should i be doing something else…

[editline]3rd May 2016[/editline]

[lua] local targetAngle = ((k:GetPos() - LocalPlayer():GetPos()):Angle())
local testang = targetAngle - EyeAngles()
testang:Normalize()
print(testang.y)
[/lua]

This seems to be perfect with 0 being looking directly at the npc, now how to translate that into location on the radar…

No that function is mostly for 3d stuff, with 3d stuff I’d rather use a matrix though.

I see what your doing now, your just drawing a plain 2d radar.

Calculate angle of target relative to the player using
thisAngle = (targetpos-playerpos):Angle()

This will give you angles. You really only want the yaw so

thisYaw = thisAngle.y

Now you will have a number like 135.

When you draw your radar, to get this to draw in the right place relative to the center of your radar you use trig functions.

Math.sin and math.cos
These take radians instead of degrees so make variables
Local toRad = math.pi/180
local toDeg = 180/math.pi

So math.sin(135 * toRad) will give you the y axis ratio of 135
math.cos(135 * toRad) will give you the x axis ratio.

math.cos(0*toRad) will equal 1
math.sin(0 * toRad) will equal 0
math.cos(90 * toRad) will equal 0
math.sin(90 *toRad) will equal 1

So once you get your ratios, you can then multiple this value by the distance of the entity from the player scaled to your radar dimensions .

[editline]3rd May 2016[/editline]

Oh also, following same logic as above but using some pseudo code

Cos 180 =-1
Sin 180 = 0
Cos 270 = 0
Sin 270 = -1

gotit

[lua]
hook.Add( “HUDPaint”, “Circle”, function()
local center = Vector( ScrW() - 75, ScrH() / 3, 0 )
local scale = Vector( 75, 75, 0 )
local segmentdist = 360 / ( 2 * math.pi * math.max( scale.x, scale.y ) / 2 )
surface.SetDrawColor( 200, 200, 200, 255 )

for a = 0, 360 - segmentdist, segmentdist do
	surface.DrawLine( center.x + math.cos( math.rad( a ) ) * scale.x, center.y - math.sin( math.rad( a ) ) * scale.y, center.x + math.cos( math.rad( a + segmentdist ) ) * scale.x, center.y - math.sin( math.rad( a + segmentdist ) ) * scale.y )
end
surface.DrawCircle(ScrW() - 75, ScrH() / 3, 5, Color(0,255,0) )

if InvRadarTable then
	for v,k in pairs(InvRadarTable) do
		if k:IsValid() then
			if k:IsNPC() then
				local targetAngle  = ((k:GetPos() - LocalPlayer():GetPos()):Angle())
				local distances = k:GetPos():Distance( LocalPlayer():GetPos() )
				if distances >= 75 * 20 then
					distances = 75 * 20
				end
				local testang = (targetAngle - EyeAngles())
				testang:Normalize()
				testang:RotateAroundAxis(Vector(0,0,1), 90)
				print(testang.y)
				local entdotx = ScrW() - 75 + math.cos( math.rad( testang.y ) ) * (distances/20)
				local entdoty = ScrH() / 3 - math.sin( math.rad( testang.y ) ) * (distances/20)
				surface.DrawCircle(entdotx, entdoty , 5, Color(255,0,0) )
			end
		end
	end
end

end )
[/lua]

[editline]3rd May 2016[/editline]

Thanks for you help man, it got my mind on the right track :slight_smile: il post a vid of it working soonish

Also. If your radar (assuming its a circle) is 200 pixel units, and your max world distance is 10000

You do
local scaleToRadar = 200/10000

Then you get distance from player to target doing

Vector:Distance(Vector)
Or thisDist = player:GetPos():Distance(target:GetPos())

Lets say this value is 8000

Your radar draw distance scaled to be under 200, would be radarDist= (thisDist*scaleToRadar)

Then from the center of your radar, the pixel unit adjustment would be

yOffset= math.sin(135toRad) * radarDist
xOffset = math.cos(135
toRad) * radarDist

You then add these values to your radar center origin to get the xy position of where to draw the target on the radar.

=]

and uploaded, feel free to check out that vid. it works perfectly. now to optimize,

Glad you got it working, looks great!

[editline]3rd May 2016[/editline]

Seems like you’ve already figured this out, but ill post it for others to see just in case.

You’ll want to math.clamp the radarDist value from (in this case) 0 to 200, or just not draw entities further than max dist. With the math.clamp they would still show up on the radar though, they’ll just be on the edge until they get closer than max distance.

http://images.akamai.steamusercontent.com/ugc/499148155512344257/5458C7C162829AC52FB6A764AF68129F450CA06D/

[lua]
local InvRadarTable

function draw.Circle( x, y, radius, seg )
local cir = {}

table.insert( cir, { x = x, y = y, u = 0.5, v = 0.5 } )
for i = 0, seg do
	local a = math.rad( ( i / seg ) * -360 )
	table.insert( cir, { x = x + math.sin( a ) * radius, y = y + math.cos( a ) * radius, u = math.sin( a ) / 2 + 0.5, v = math.cos( a ) / 2 + 0.5 } )
end

local a = math.rad( 0 ) -- This is need for non absolute segment counts
table.insert( cir, { x = x + math.sin( a ) * radius, y = y + math.cos( a ) * radius, u = math.sin( a ) / 2 + 0.5, v = math.cos( a ) / 2 + 0.5 } )

surface.DrawPoly( cir )

end

function FindInvEnts()

InvRadarTable = ents:GetAll()

end

local triangle = {
{ x = ScrW() - 75, y = (ScrH() / 3) + - 8  },
{ x = ScrW() - 80, y = ScrH() / 3 + 2  },
{ x = ScrW() - 70, y = ScrH() / 3 + 2 }
}

hook.Add( “HUDPaint”, “Circle”, function()
local center = Vector( ScrW() - 75, ScrH() / 3, 0 )
local scale = Vector( 75, 75, 0 )
local segmentdist = 360 / ( 2 * math.pi * math.max( scale.x, scale.y ) / 2 )
surface.SetDrawColor( 200, 200, 200, 255 )
for a = 0, 360 - segmentdist, segmentdist do
surface.DrawLine( center.x + math.cos( math.rad( a ) ) * scale.x, center.y - math.sin( math.rad( a ) ) * scale.y, center.x + math.cos( math.rad( a + segmentdist ) ) * scale.x, center.y - math.sin( math.rad( a + segmentdist ) ) * scale.y )
end

surface.SetDrawColor( 0, 200, 0, 255 )
surface.DrawPoly( triangle )
if InvRadarTable then
	for v,k in pairs(InvRadarTable) do
		if k:IsValid() then
			if k:IsNPC() then
				local entpos = k:GetPos()
				local plypos = LocalPlayer():GetPos()
				local targetAngle  = ((entpos - plypos):Angle())
				entpos.z = 0
				plypos.z = 0
				local distances = math.Clamp(entpos:Distance( plypos ), 0, 75 * 20 )
				local testang = (targetAngle - EyeAngles())
				testang:Normalize()
				testang:RotateAroundAxis(Vector(0,0,1), 90)
				local entdotx = ScrW() - 75 + math.cos( math.rad( testang.y ) ) * (distances/20)
				local entdoty = ScrH() / 3 - math.sin( math.rad( testang.y ) ) * (distances/20)
				surface.SetDrawColor( 255, 0, 0, 255 )
				draw.Circle(entdotx, entdoty , 5, 10 )
			end
		end
	end
end

end )[/lua]

[editline]3rd May 2016[/editline]

well… just got a pretty odd issue, not sure what is causing this

Ill post my take on it tomorrow for fun, been thinking about adding it to my game mode, and now I’ve got it all thought out :p.

[editline]3rd May 2016[/editline]

Lol nice glitch, worthy enough to post this on one of those error bragging threads xD. No idea on this one lol.