The above video goes away if you are a member and logged in, so log in now!

 Would you like to get all the newest Gaming News fromQJ.NET in your email each day? Want to learn more about the team who brings you the QJ news?

## [wip]lua polyLib

This is a discussion on [wip]lua polyLib within the PSP Development Forum forums, part of the PSP Development, Hacks, and Homebrew category; I was disappointed when I first started using lua and realized that the only built in function for shapes in ...

 Tweet
1. ## [wip]lua polyLib

I was disappointed when I first started using lua and realized that the only built in function for shapes in lua player was one for drawing rectangles, so I've started working on a library with functions for drawing other polygons. Eventually I'm going to try to add free-form and animated polygons (I.E. have one shape morph into another) but for now I've only got three functions done.

Although it might be possible to make these functions draw filled polys, for speed purposes right now I'll be sticking to outline shapes only

*edit*

http://www.mediafire.com/?4jqna20jzvn

the archive contains the polyLib.lua file and a test script that displays all the current functions

current function list:

draw_poly(x, y, radius, rotation, sides, sides_to_draw, closed, color)

draws a regular polygon (i.e. all sides are the same length)
x,y - the center point of the poly
radius - distance from the center point to each corner of the poly
rotation - angle in degrees in which to rotate the poly around it's center
sides - number of sides the poly has
sides_to_draw - number of sides that will actually be drawn
closed - if true and sides_to_draw is less than sides then it will draw a line connecting the end points
color - color to draw the poly

function draw_tri(x, y, side1, side2, angle, rotation, color)
draws a triangle rotated around the start point with two sides of the specified length at the given angle

draw_para(x,y, side1, side2, angle, rotation, color)
draws a parallelogram rotated around the start point, side1 and side2 are the lengths of each pair of sides, angle is the angle of the two sides that meet at the start point

draw_free(x, y, ptable, scale, color)

this one lets you draw free-form polys

ptable is basically a table with a list of coordinates relative to x,y. This example table has the coords to draw an outline of an x:
Code:
```polytable = {
{x = 1, y = 0},
{x = 0, y = 1},
{x = 1, y = 2},
{x = 0, y = 3},
{x = 1, y = 4},
{x = 2, y = 3},
{x = 3, y = 4},
{x = 4, y = 3},
{x = 3, y = 2},
{x = 4, y = 1},
{x = 3, y = 0},
{x = 2, y = 1},
{x = 1, y = 0},
}```
"scale" will let you change the size the poly is drawn at, set it to 1 for no change
I've remove the "closed" argument in this version, if you want to close the poly, just repeat the first point at the end of the table

polymorph.new(poly_table, frames, delay)

creates a new polymorph object (setup is similar to animlib)

poly_table is a table that contains 2 of the same type of tables used for draw_free. Although the 2 poly tables don't have to be the exact same size, the smaller table must have at least half the number of points as the larger table.

frames is the number of animation frames you want it to take to morph one poly into the other,

delay is the delay between frames.

polymorph:start()
starts the animation timer

polymorph:set_auto(auto_t ype, wait)
sets up the automatic switching, auto_type is a string value:

"reverse" -sets it to auto-reverse the animation
"reset" -sets it to auto-reset to the first frame of the animation
"stop" -stops the animation timer

wait is a number value, it sets how long to wait before starting the next animation loop. If left out it will continue to use the previous wait value (default is 0)

polymorph:draw(x, y, scale, color)
draws the polymorph animation

this is an advanced version of the draw_free function, by adding a few things to the poly table you can change the way it gets drawn:

Code:
```poly1 = {
{color = green, x = 1, y = 0},
{x = 0, y = 1},
{x = 1, y = 2},
{x = 2, y = 1},
{x = 1, y = 0},
{command = "break"},
{color = red, x = 1, y = 3},
{x = 0, y = 4},
{x = 1, y = 5},
{x = 2, y = 4},
{x = 1, y = 3},
{command = "break"},
{color = blue, x = 4, y = 0},
{x = 3, y = 1},
{x = 4, y = 2},
{x = 5, y = 1},
{x = 4, y = 0},
{command = "break"},
{color = white, x = 4, y = 3},
{x = 3, y = 4},
{x = 4, y = 5},
{x = 5, y = 4},
{x = 4, y = 3},
}```
putting color = newcolor in any index will change the current drawing color. Although you can still put in a color when calling the function, it will be over-ridden by any color codes in the poly table

putting in command = "break" will stop the function from drawing a line between the points before and after the command

2. sounds interesting and cool at the same time.

3. post screens

4. OK, here's some screens. One with draw_tri and draw_para. 3 with draw_poly - full, partial, and partial closed. And one that uses multiple draw_para to make a design.

5. check the first post, I added another function

6. Wow, this looks awesome! This might be useful in the future.... Good job!

7. Alright, I got the polymorph partially working. When I run my test script it works fine. I then tried to convert it to an animlib style metatable, but I can't get that to work.

Here's my working test script:

Code:
```function draw_free(x, y, ptable, scale, closed, color)
for i = 1, table.getn(ptable) do
if ptable[i+1] then
screen:drawLine(x+(ptable[i].x*scale), y+(ptable[i].y*scale), x+(ptable[i+1].x*scale), y+(ptable[i+1].y*scale), color)
end
end
if closed then
screen:drawLine(x+(ptable[1].x*scale), y+(ptable[1].y*scale), x+(ptable[table.getn(ptable)].x*scale), y+(ptable[table.getn(ptable)].y*scale), color)
end
end

white = Color.new(255,255,255)
blue  = Color.new(0,0,255)
red   = Color.new(255,0,0)
green = Color.new(0,255,0)

poly1 = {
{x = 1, y = 0},
{x = 0, y = 1},
{x = 1, y = 2},
{x = 0, y = 3},
{x = 1, y = 4},
{x = 2, y = 3},
{x = 3, y = 4},
{x = 4, y = 3},
{x = 3, y = 2},
{x = 4, y = 1},
{x = 3, y = 0},
{x = 2, y = 1},
{x = 2, y = 1},
}

poly2 = {
{x = 1, y = 1},
{x = 1, y = 2},
{x = 0, y = 2},
{x = 1, y = 3},
{x = 2, y = 3},
{x = 2, y = 3},
{x = 2, y = 4},
{x = 3, y = 3},
{x = 3, y = 2},
{x = 4, y = 2},
{x = 3, y = 1},
{x = 2, y = 1},
{x = 2, y = 0},
}

morphtable = {}
for i = 1, 13 do
morphtable[i] = { x=0, y=0}
end

timer = Timer.new()
frames = 50
frame = 1
step = 1
delay = 50

timer:start()

alpha = frame/frames
if timer:time() > delay then
for i = 1, table.getn(poly1) do
morphtable[i].x = poly1[i].x + alpha *(poly2[i].x - poly1[i].x)
morphtable[i].y = poly1[i].y + alpha *(poly2[i].y - poly1[i].y)
end
frame = frame + step
if frame == frames or frame == 1 then step = -step end
timer:reset()
end

screen:clear()
draw_free(100, 100, morphtable, 20, true, green)
screen:flip()
end```
Here's the non-working metatable/metamethod version:

Code:
```function draw_free(x, y, ptable, scale, closed, color)
for i = 1, table.getn(ptable) do
if ptable[i+1] then
screen:drawLine(x+(ptable[i].x*scale), y+(ptable[i].y*scale), x+(ptable[i+1].x*scale), y+(ptable[i+1].y*scale), color)
end
end
if closed then
screen:drawLine(x+(ptable[1].x*scale), y+(ptable[1].y*scale), x+(ptable[table.getn(ptable)].x*scale), y+(ptable[table.getn(ptable)].y*scale), color)
end
end

polymorph ={}
function polymorph.new(poly_table, frames, delay)
if table.getn(poly_table[1]) ~= table.getn(poly_table[2]) then
if table.getn(poly_table[1]) > table.getn(poly_table[2]) then
local aa = table.getn(poly_table[1]) - table.getn(poly_table[2])
for i = 2, (aa*2), 2 do
table.insert(poly_table[2], i, poly_table[2][i-1])
end
else
local aa = table.getn(poly_table[2]) - table.getn(poly_table[1])
for i = 2, (aa*2), 2 do
table.insert(poly_table[1], i, poly_table[1][i-1])
end
end
end

morph_table = {}
for i = 1, table.getn(poly_table[1]) do
morph_table[i] = {x=0, y=0}
end

local temp = setmetatable(
{
poly = poly_table,
morph = morph_table,
frames = frames,
delay = delay,
frame = 1,
step =1,
timer = Timer.new(),
},
{
__index = polymorph
}
)
return temp
end

function polymorph:start()
self.timer:start()
end

function polymorph:draw(x, y, scale, closed, color)
alpha = self.frame/self.frames
if self.timer:time() > self.delay then
for i = 1, table.getn(self.poly[1]) do
self.morph[i].x = self.poly[1][i].x + alpha *(self.poly[2][i].x - self.poly[1][i].x)
self.morph[i].y = self.poly[1][i].y + alpha *(self.poly[2][i].y - self.poly[1][i].y)
end
self.frame = self.frame + self.step
if self.frame == self.frames or self.frame == 1 then self.step = -self.step end
self.timer:reset()
end
draw_free(100, 100, self.morph, scale, closed, color)
end

white = Color.new(255,255,255)
blue  = Color.new(0,0,255)
red   = Color.new(255,0,0)
green = Color.new(0,255,0)

polytable1 = {
{x = 1, y = 0},
{x = 0, y = 1},
{x = 1, y = 2},
{x = 0, y = 3},
{x = 1, y = 4},
{x = 2, y = 3},
{x = 3, y = 4},
{x = 4, y = 3},
{x = 3, y = 2},
{x = 4, y = 1},
{x = 3, y = 0},
{x = 2, y = 1},
}

polytable2 = {
{x = 1, y = 1},
{x = 1, y = 2},
{x = 0, y = 2},
{x = 1, y = 3},
{x = 2, y = 3},
{x = 2, y = 3},
{x = 2, y = 4},
{x = 3, y = 3},
{x = 3, y = 2},
{x = 4, y = 2},
{x = 3, y = 1},
{x = 2, y = 1},
{x = 2, y = 0},
}

morph_test = polymorph.new({polytable1, polytable2}, 50, 50)
morph_test:start()

screen:clear()
morph_test:draw(100, 100, 20, true, green)
screen:flip()
end```
The second version only draws the first poly and I can't figure out why.

*edit*

Got it, needed to have the timer.start() inside the draw() metamethod

8. I've discovered a bug in my script, but I'm not sure what the exact problem is.

In this bit of code I'm drawing a pentagon that rotates around and gets larger as it rotates. By the end of the rotation the corners should be outside the screen area but instead end up "sticking" to the screen edge.

Code:
```function newx(x, radius, radian) return (x + math.cos(radian)*radius) end

function draw_poly(x, y, radius, rotation, sides, sides_to_draw, closed, color)
for i = 1, sides_to_draw do
screen:drawLine(x1, y1, x2, y2, color)
end
if closed then
screen:drawLine(x1, y1, x2, y2, color)
end
end

white = Color.new(255,255,255)
blue  = Color.new(0,0,255)
red   = Color.new(255,0,0)
green = Color.new(0,255,0)

r=0
step = 1
r = r + step
if r > 360 or r < -0 then step = -step end
screen:clear()
draw_poly(240, 136, r, r, 5, 5, closed, blue)
screen:flip()
end
screen.waitVblankStart()
end```
anyone have any ideas why it's happenening like this?

9. screen:drawLine only draws on screen. If you attempt to draw it off screen, it draws a line on screen closest to where you intended to draw it off screen.

10. another update, check the first post

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•

All times are GMT -8. The time now is 12:37 AM.

Use of this Web site constitutes acceptance of the TERMS & CONDITIONS and PRIVACY POLICY