Jump to content

How to create a 2 point Bezier Curve? (Node Graph)


Vida Marcell
 Share

Recommended Posts

  • 2 weeks later...

Hi, I wrote this script while ago.

Create a new blank project, replace the main.lua script with:

--[[

	Bezier in action

	Autor: Juan Ignacio Odriozola (aka Charrua)

	I rewrite a code in lua from an old work on the subject...
	math is all over the net, here i show a simple example of usage
	I'm interpolating just 2 axes, is 2d but with simple modifications you can make it 3d
    (as this is a "challenge month" try your self to make it 3d :)

	Usage:
		TAB to change selected point: green one
		Arrows to move it up/down, left/right (x,y axes)
	
	Enjoy!
	

]]--

spheres = {}
controlOnes = {}
current = 0
changed = false

function App:Start()

        self.window = Window:Create("beziers",0,0,800,600)
        self.context = Context:Create(self.window)
        self.world = World:Create()
        self.camera = Camera:Create()
        self.camera:Move(0,0,-10)
        local light = DirectionalLight:Create()
        light:SetRotation(35,35,0)
        
		for i=0, 99 do
			spheres[i]=Model:Sphere()
			spheres[i]:SetScale(0.2)
			spheres[i]:SetColor(0.0,0.0,1.0)	--blue
		end
		for i=0, 3 do
			controlOnes[i]=Model:Sphere()
			controlOnes[i]:SetPosition(-3+i*2,0,0)
			controlOnes[i]:SetScale(0.5)
			controlOnes[i]:SetColor(1.0,0.0,0.0)	--red
		end
		controlOnes[current]:SetColor(0.0,1.0,0.0)	--selected: green
		
		reposition()
		
        return true
end

function App:Loop()
        
        if self.window:Closed() or self.window:KeyHit(Key.Escape) then return false end

		--TAB to change Current selected Point 
		if self.window:KeyHit(Key.Tab) then
			controlOnes[current]:SetColor(1.0,0.0,0.0) --left selection, returns to red
			current = current + 1 
			if current == 4 then current=0 end 
			controlOnes[current]:SetColor(0.0,1.0,0.0)	--selected: green 
		end

		if self.window:KeyDown(Key.Left) then
			controlOnes[current]:Translate(-.01,  0, 0)
			changed=true 
		end 

		if self.window:KeyDown(Key.Right) then
			controlOnes[current]:Translate( .01,  0, 0) 
			changed=true 
		end 

		if self.window:KeyDown(Key.Up) then 
			controlOnes[current]:Translate( 0,  .01, 0) 
			changed=true 
		end
			
		if self.window:KeyDown(Key.Down) then 
			controlOnes[current]:Translate( 0, -.01, 0) 
			changed=true 
		end

		if changed then
			--time to recalc positions
			changed = false
			reposition()
		end
        
        Time:Update()
        self.world:Update()
        self.world:Render()
        self.context:Sync()

        return true
end

function reposition()
    
	local t=0.0
	local step=0.0
	local p1Pos=Vec3(0,0,0)

	p1Pos = controlOnes[0]:GetPosition(true)
	p2Pos = controlOnes[1]:GetPosition(true)
	p3Pos = controlOnes[2]:GetPosition(true)
	p4Pos = controlOnes[3]:GetPosition(true)
	System:Print(p1Pos.x .. " " .. p1Pos.y .. " " .. p1Pos.z)
	System:Print(p2Pos.x .. " " .. p2Pos.y .. " " .. p2Pos.z)
	System:Print(p3Pos.x .. " " .. p3Pos.y .. " " .. p3Pos.z)
	System:Print(p4Pos.x .. " " .. p4Pos.y .. " " .. p4Pos.z)

    for i=0, 99 do
		step = i
        t = step/100.0
		spheres[i]:SetPosition(interpolatePos(t, p1Pos, p2Pos, p3Pos, p4Pos),true)
    end
    
end


function interpolatePos(t, p1, p2, p3, p4)
	
	local retVal=Vec3(0,0,0)
	local t3, t2, t1

	t_3 = (1.0-t)^3
	t_2 = (1.0-t)^2
	t_1 = (1.0-t)
	t2 = t^2 
    t3 = t^3
	
	retVal.x = p1.x * t_3 + 3 * p2.x * t_2 * t + 3 * p3.x * t_1 * t2 + p4.x * t3
	retVal.y = p1.y * t_3 + 3 * p2.y * t_2 * t + 3 * p3.y * t_1 * t2 + p4.y * t3
	retVal.z = p1.z * t_3 + 3 * p2.z * t_2 * t + 3 * p3.z * t_1 * t2 + p4.z * t3

	return retVal

end

TAB to change the selected point (green one)

Arrows to move the selected point (2D exmple)

 

App.lua

  • Thanks 1

Paren el mundo!, me quiero bajar.

Link to comment
Share on other sites

Method DrawCurve(x0:Int,y0:Int,x1:Int,y1:Int)
	Local curve:Float
	Local m:Float
	Local dx:Float = x1-x0
	Local dy:Float = y1-y0
	m=Sqr(dx*dx+dy*dy)
	curve = m*0.5
	DrawBezier x0,y0,x0+curve,y0,x1,y1,x1-curve,y1
EndMethod
    
Function DrawBezier(x1:Float,y1:Float,vx1:Float,vy1:Float,x2:Float,y2:Float,vx2:Float,vy2:Float)
	Local t:Float,lx:Float,ly:Float
	Local pointx:Float,pointy:Float
	Local steps:Float=20
	For Local i:Int=0 To steps+1't#=0 To 1 Step 0.25'0.05
		t=1.0/(steps+1)*Float(i)
		pointx# = x1*(1.0-t)^3.0 + 3.0*vx1*(1.0-t)^2.0*t + 3.0*vx2*(1.0-t)*t^2.0 + x2*t^3.0
		pointy# = y1*(1.0-t)^3.0 + 3.0*vy1*(1.0-t)^2.0*t + 3.0*vy2*(1.0-t)*t^2.0 + y2*t^3.0
		If t>0
			leDrawLine lx,ly,pointx,pointy
		EndIf
		lx=pointx
		ly=pointy
	Next
EndFunction

(BlitzMax code)

  • Thanks 1

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

  • Vida Marcell changed the title to How to create a 2 point Bezier Curve? (Node Graph)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...