Hi. I am wondering if there are ways to plotting those mathematical functions... For example, y=ax+b, player's can set a and b by vgui and the shape of this function then is plotted somewhere in the game. (Of course the same vgui is the best).
Of course I can plot them by excel or other software, the question is how to upload those .vtf or .vmt file dynamically in the game.
Have any idea? Thanks!
You could plot the functions yourself using the [url=http://wiki.garrysmod.com/?title=Draw]draw library[/url], you just need to loop through the x axis, say from -10 to 10 and calculate the y value, then you can either draw a line from the last value to this one, or just draw a point.
Thanks.. Partly understand...
Completely untested but it should work :
[lua]local function Y(x,a,b)
return a*x+b
end
local a = 3 -- Default values for the example
local b = 5
local xMin = -10 -- Lowest value to draw
local xMax = 10 -- Highest value to draw
local step = 1 --The distance between points on the x axis.
local baseX = ScrW() * 0.5 -- This is the middle of the screen
local baseY = ScrH() * 0.5 -- This is the middle of the screen
hook.Add("HUDPaint", "DrawFunction", function()
if (xMin >= xMax) or (step > xMax - xMin) then return end -- Checking our values
for x1 = xMin,xMax-1,step do
local x2 = x1+step -- Calculating the next value of x so we can draw a line between the 2
local y1 = Y(x1,a,b)
local y2 = Y(x2,a,b)
print("("..x1..", "..y1..") to ("..x2..", "..y2..")") -- For debug purposes
surface.DrawLine( baseX + x1, baseY + (y1*-1),baseX + x2, baseY + (y2*-1) ) -- Adding our points to the coordinates of the middle of the screen. I'm reverting the y because I'm pretty sure that on the screen a lower y is higher. I could be wrong.
end
end)[/lua]
:science:
[QUOTE=Crazy Quebec;20919053]Completely untested but it should work :
[lua]local function Y(x,a,b)
return a*x+b
end
local a = 3 -- Default values for the example
local b = 5
local xMin = -10 -- Lowest value to draw
local xMax = 10 -- Highest value to draw
local step = 1 --The distance between points on the x axis.
local baseX = ScrW() * 0.5 -- This is the middle of the screen
local baseY = ScrH() * 0.5 -- This is the middle of the screen
hook.Add("HUDPaint", "DrawFunction", function()
if (xMin >= xMax) or (step > xMax - xMin) then return end -- Checking our values
for x1 = xMin,xMax-1,step do
local x2 = x1+step -- Calculating the next value of x so we can draw a line between the 2
local y1 = Y(x1,a,b)
local y2 = Y(x2,a,b)
print("("..x1..", "..y1..") to ("..x2..", "..y2..")") -- For debug purposes
surface.DrawLine( baseX + x1, baseY + (y1*-1),baseX + x2, baseY + (y2*-1) ) -- Adding our points to the coordinates of the middle of the screen. I'm reverting the y because I'm pretty sure that on the screen a lower y is higher. I could be wrong.
end
end)[/lua]
:science:[/QUOTE]
Wow, nice.
Wow... Really appreciate!
Another problem is the hook. I find that if I do not use
[lua]
hook.Add("HUDPaint", "DrawFunction", function()
[/lua]
but directly put the surface.DrawLine in a function that mainly describe vgui, there will be no line drew. However, if I use this hook, it will draw at the beginning of the game, which is not what I want.
SO must surface.DrawLine relates to the "HUDPaint" hook or is there anyway that not let "HUDPaint" happen...
THanks
It doesn't really matter where as long as it's in a drawing hook. In your case you should create a derma vgui and do the drawing in one of the panel's Paint hook.
[url]http://wiki.garrysmod.com/?title=DPanel[/url]
[url]http://wiki.garrysmod.com/?title=Vgui.Create[/url]
[b][url=wiki.garrysmod.com/?title=Panel.Paint]Panel.Paint [img]http://wiki.garrysmod.com/favicon.ico[/img][/url][/b]
[editline]02:13PM[/editline]
So that means that when defining your panel you want to draw on you can do this :
[lua]function mypanel:Paint()
if (xMin >= xMax) or (step > xMax - xMin) then return end -- Checking our values
for x1 = xMin,xMax-1,step do
local x2 = x1+step -- Calculating the next value of x so we can draw a line between the 2
local y1 = Y(x1,a,b)
local y2 = Y(x2,a,b)
print("("..x1..", "..y1..") to ("..x2..", "..y2..")") -- For debug purposes
surface.DrawLine( baseX + x1, baseY + (y1*-1),baseX + x2, baseY + (y2*-1) ) -- Adding our points to the coordinates of the middle of the screen. I'm reverting the y because I'm pretty sure that on the screen a lower y is higher. I could be wrong.
end
end[/lua]
And then you can change the a and b values through other derma controls. Also baseX and baseY's values should be the center of the control you want to draw on.
I made this
[img_thumb]http://i44.tinypic.com/2itos5e.jpg[/img_thumb]
[img_thumb]http://i44.tinypic.com/357r3bn.jpg[/img_thumb]
Is it similar to what you are looking for?
[editline]06:31PM[/editline]
Click on the images, the line are a bit thin to see in the thumb.
Looks quite like it, what do you use to draw points? surface.DrawLine(x1,y1,x1,y1) ?
I'm actually using surface.DrawRect(x1 - 1, y1 - 1, 3, 3).
[editline]06:39PM[/editline]
In those images though I was using surface.DrawRect(x1, y1, 1, 1), but I changed it when I realised that this is wrong.
[QUOTE=MakeR;20939152]I made this
[img_thumb]http://i44.tinypic.com/2itos5e.jpg[/img_thumb]
[img_thumb]http://i44.tinypic.com/357r3bn.jpg[/img_thumb]
Is it similar to what you are looking for?
[editline]06:31PM[/editline]
Click on the images, the line are a bit thin to see in the thumb.[/QUOTE]
Almost exactly what I want.
This is my code that define a vgui which belongs to the entity. I paste an example draw circle script inside.
[lua]
function ENT:PanelSetting()
local Frames=vgui.Create("DFrame")
Frames:SetPos(50,50)
Frames:SetSize(450,450)
Frames:SetVisible( true )
Frames:SetDraggable( true ) -- Draggable by mouse?
Frames:ShowCloseButton(true)
local NumSlide=vgui.Create("DNumSlider",Frames)
NumSlide:SetPos(25,25)
NumSlide:SetSize(100,40)
NumSlide:SetMax(24)
NumSlide:SetMin(0)
NumSlide:SetDecimals(0)
--Here is the part to drawing
local center = Vector( ScrW() / 2, ScrH() / 2, 0 )
local scale = Vector( 100, 100, 0 )
local segmentdist = 360 / ( 2 * math.pi * math.max( scale.x, scale.y ) / 2 )
surface.SetDrawColor( 255, 0, 0, 255 )
Msg("Hi Drawing")
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
--Drawing the circle ends here
local Button=vgui.Create("DButton",Frames)
Button:SetPos(25,95)
Button:SetSize(50,50)
Button:SetText("OK")
Button.DoClick=function()
self.Fre=NumSlide:GetValue()
Frames:Close()
end
end
[/lua]
And this is the result:
[IMG]http://i43.tinypic.com/212bk08.jpg[/IMG]
No circle is put.
However, if I did it like this way:
[lua]
function ENT:PanelSetting()
...
end
hook.Add( "HUDPaint", "Circle", function()
local center = Vector( ScrW() / 2, ScrH() / 2, 0 )
local scale = Vector( 100, 100, 0 )
local segmentdist = 360 / ( 2 * math.pi * math.max( scale.x, scale.y ) / 2 )
surface.SetDrawColor( 255, 0, 0, 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
end)
[/lua]
There will be a circle that drawing on the screen when the game start.
[IMG]http://i40.tinypic.com/2iswq3l.jpg[/IMG]
2 things, you're not doing the drawing in your frame's Paint hook and you're using the middle of the screen as a center value. You should be using a value that will make it fit on said frame. If you just want it to draw in the center anyway you could put a condition to the drawing.
I want to let it to be on the vgui panel, looks same as makeR does. However, when I use:
[lua]
local Frames=vgui.Create("DFrame")
Frames:SetPos(50,50)
Frames:SetSize(450,450)
Frames:SetVisible( true )
Frames:SetDraggable( true ) -- Draggable by mouse?
Frames:ShowCloseButton(true)
Frames.Paint=function(
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
)
[/lua]
The nightmare was that the frame will even not come out...
Really Thanks....
[lua] Frames.Paint=function(
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
)[/lua]
That's because you put all of your code in the argument to the function and did not end it. :smile:
This should work better :
[lua]Frames.Paint=function()
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
end[/lua]
Er...................
Sorry........
In my script I did so... with the end on it...
The important part is the parenthesis after function. You put all of the code in them while rhey should be closed.
Er... Seems not this problem... Thank you guys very much.
Sorry, you need to Log In to post a reply to this thread.