I made a equilateral triangle:
local W = 540
local H = 700
local r = 150
local r_x = math.sqrt(math.pow(r,2)-math.pow((r/2),2))
local vertices = { 0,-r, r_x , r/2 , -r_x , r/2 }
local block = display.newPolygon( W, H, vertices )
physics.addBody( block )
physics.setGravity(0,0)
block.angularVelocity= 100
I want the triangle to rotate on its axis but it does not happen. why?
I thinks it related to the object's anchor but I dont know how to fix this.
Try yourself if you don't understand what I mean.
Just take all the objects and insert them into a group. Then just rotate the group using the rotate API.
Related
I used surface.DrawTexturedRectRotated() to make filled circle but it rotates from center and i want to make it rotate from left.
I tried to rotate it but it makes full circle when its 180 degrees
function draw.FilledCircle( x, y, w, h, ang, color )
for i=1,ang do
draw.NoTexture()
surface.SetDrawColor( color or color_white )
surface.DrawTexturedRectRotated( x,y, w, h, i )
end
end
How do i make it to be rotated from left?
If you want a function that allows you to create pie-chart-like filled circle by specifying the ang parameter, your best bet is probably surface.DrawPoly( table vertices ). You should be able to use it like so:
function draw.FilledCircle(x, y, r, ang, color) --x, y being center of the circle, r being radius
local verts = {{x = x, y = y}} --add center point
for i = 0, ang do
local xx = x + math.cos(math.rad(i)) * r
local yy = y - math.sin(math.rad(i)) * r
table.insert(verts, {x = xx, y = yy})
end
--the resulting table is a list of counter-clockwise vertices
--surface.DrawPoly() needs clockwise list
verts = table.Reverse(verts) --should do the job
surface.SetDrawColor(color or color_white)
draw.NoTexture()
surface.DrawPoly(verts)
end
I have put surface.SetDrawColor() before draw.NoTexture() as this example suggests it.
You may want to use for i = 0, ang, angleStep do instead to reduce the number of vertices, therefore reducing hardware load, however that is viable only for small circles (like the one in your example) so the angle step should be some function of radius to account for every situation. Also, additional computing needs to be done to allow for angles that do not divide by the angle step with remainder of zero.
--after the for loop
if ang % angleStep then
local xx = x + math.cos(math.rad(ang)) * r
local yy = y - math.sin(math.rad(ang)) * r
table.insert(verts, {x = xx, y = yy})
end
As for the texturing, this will be very different from rectangle if your texture is anything else than solid color, but a swift look at the library did not reveal any better way to achieve this.
I recently made a simple lua class (this is using the love2D engine) that made a hexagon by plotting 6 vertices and tracing them with lines, one of the things I wanted to be able to expand to was a hexagon grid but I didn't know how
All of the websites I found didn't help and I couldn't understand why.
Here's the function where I plot the vertices based on it's radius and x and y position.
My hexagons are in a pointy-topped style.
function hexagon.new(x,y,radius)
local hexagon=setmetatable({},hexagon)
hexagon.Vertices={}
hexagon.x=x or 0
hexagon.radius = radius or 10
hexagon.y=y or 0
for i=0,6 do
local angle = 2 * math.pi / 6 * (i + .5) -- 1 is what is multipled to 90(2*math.pi) so 1*90=90(flat-topped), 0.5*90=45(pointy-topped)
local x = hexagon.x + hexagon.radius * math.cos(angle)
local y = hexagon.y + hexagon.radius * math.sin(angle)
hexagon.Vertices[i]= {x=x,y=y}
end
return hexagon
end
Hope i understood well.
Here is working example of how to create hex and then draw it to grid with as simplified functions as possible, using Love2d engine (v. 0.10.2).
important: made for hex which has all six points on circle, using radius.
this approach is not suitable for all hex shapes.
------------------------------
--lets create hex data with center at position 0,0
--using only simple functions
--table of 6 points
hex = {};
--radius for hex which has all 6 points lying on circle
hex.radius = 10;
--simple loop to generate hex
local i = 1
repeat
--full circle has 2 radians and hex has 6 points
--so 1/3 pi increase per point
local direction = math.pi/3 * (i+0.5)
--rotate hex by 90 degrees: direction = math.pi/3 * i
--generate empty table to insert point coordinations to
hex[i] = {};
--set x,y coordinates
hex[i].x = hex.radius*math.cos( direction )
hex[i].y = hex.radius*math.sin( direction )
i = i+1
until i > 6
------------------------------
------------------------------
function love.draw( dt )
--get distance between 2 hex tiles using trigonometry
local jxOffset = hex.radius*-math.tan( math.pi/1.5 ) --or math.sqrt(3) * hex.radius
--offset new lines by this value
local ixOffset = jxOffset/4
--use direction and distance to get "y" offset between lines
--we got distance in jxOffset, so we just apply direction
local iyOffset = jxOffset*math.sin( math.pi/3 )
--"i" = line, "j" = tile in line
local i = 1
repeat
local j = 1
repeat
love.graphics.push()
--offset drawable position (or draw hex tile at position):
love.graphics.translate( ixOffset+j*jxOffset, i*iyOffset )
--draw poly-line between all hex points - creating hex
love.graphics.line( hex[1].x,hex[1].y, hex[2].x,hex[2].y, hex[3].x,hex[3].y, hex[4].x,hex[4].y, hex[5].x,hex[5].y, hex[6].x,hex[6].y, hex[1].x,hex[1].y );
love.graphics.pop()
j = j+1
until j > 5
--invert for each new line
--keep lines from increasing x coordinates
ixOffset = -ixOffset
i = i+1
until i > 5
end
------------------------------
Excuse me if i made mistake somewhere, ran the code and worked properly on my side. If you discover anything off, comment and i will try to fix it.
Ok, so I'm trying to create hexagons for my game. The first option I had is to have several images of hexagon, but I'm having problems with clickable area since these images are positioned side-by-side.
So i guess my only option is to create objects using polygons. Here is a code from corona sdk's website:
local halfW = display.contentWidth * 0.5
local halfH = display.contentHeight * 0.5
local vertices = { 0,-110, 27,-35, 105,-35, 43,16, 65,90, 0,45, -65,90, -43,15, -105,-35, -27,-35, }
local o = display.newPolygon( halfW, halfH, vertices )
o.fill = { type="image", filename="mountains.png" }
o.strokeWidth = 10
o:setStrokeColor( 1, 0, 0 )
That code is for creating a star. But I don't know how to create a hexagon using vertices.
Try this to create the vertices array:
local R = 45
local N = 6
local vertices = {}
local i = 0
for t = 0, 2*math.pi, 2*math.pi/N do
i=i+1; vertices[i]= R*math.cos(t)
i=i+1; vertices[i]= R*math.sin(t)
end
And this to draw the hexagon:
local halfW = display.contentWidth * 0.5
local halfH = display.contentHeight * 0.5
local hexagon = display.newPolygon( halfW, halfH, vertices )
hexagon.fill = { type="image", filename="mountains.png" }
hexagon.strokeWidth = 10
hexagon:setStrokeColor( 1, 0, 0 )
I chose R=45 to produce a polygon of the same size of your star.
You could always use a graphics.newMask() to apply a mask to each image hex that would make the outside area not touchable.
I'm having trouble even figuring out where to start with this. ANY help would be highly appreciated!
Using the Corona SDK I want to draw a circle that will slowly fill as a percentage increases.
The fill effect will follow the path of the circle, going anti-clockwise until the entire circle/area is completely filled a different color.
Thanks!
This sample from caronalabs.com forums shows how you might draw an arc, which provides the discrete algorithm you would need to do what you're asking:
function display.newArc(group, x,y,w,h,s,e,rot)
local theArc = display.newGroup()
local xc,yc,xt,yt,cos,sin = 0,0,0,0,math.cos,math.sin --w/2,h/2,0,0,math.cos,math.sin
s,e = s or 0, e or 360
s,e = math.rad(s),math.rad(e)
w,h = w/2,h/2
local l = display.newLine(0,0,0,0)
l:setColor(54, 251, 9)
l.width = 4
theArc:insert( l )
for t=s,e,0.02 do
local cx,cy = xc + w*cos(t), yc - h*sin(t)
l:append(cx,cy)
end
group:insert( theArc )
-- Center, Rotate, then translate
theArc.x,theArc.y = 0,0
theArc.rotation = rot
theArc.x,theArc.y = x,y
return theArc
end
function display.newEllipse(group, x, y, w, h, rot)
return newArc(group, x, y, w, h, nil, nil, rot)
end
It would appear that all you need to do is continue allocating new lines from the center out to the circumference of the circle over time.
Disclaimer: I've not tested this code, you will likely need to modify it further, but at a glance the math looks correct.
HTH!
I was wondering how you would go about this assuming you were working with a 2D coordinate frame in pixels. I created some examples of what I mean:
Red dot represents the origin point
Grey circle shows the radius but wouldn't actually be drawn
Green dots have a set amount and get evenly distributed along the
circle
With 3 dots:
http://prntscr.com/5vbj86
With 8 dots:
http://prntscr.com/5vbobd
Spektre answered my question but in C++, here it is in lua for anyone interested:
local x,y
local n = 10
local r = 100.0
local x0 = 250.0
local y0 = 250.0
local da = 2.0 * math.pi/n
local a = 0.0
for i = 0, n - 1 do
x = x0 + r * math.cos(a)
y = y0 + r * math.sin(a)
-- draw here using x,y
a = a + da
end
on circle very easy
for evenly distributed points the angle is increasing with the same step
so for N points the step is da=2.0*M_PI/N;
The code in C++ is like this:
int i,n=10;
double x,y,a,da;
double r=100.0,x0=250.0,y0=250.0; // circle definition
da=2.0*M_PI/double(n);
for (a=0.0,i=0;i<n;i++,a+=da)
{
x=x0+r*cos(a);
y=y0+r*sin(a);
// here draw or do something with (x,y) point
}