function draw()
translate(300,300)
rotate(30)
scale(2,1.5)
fill(255, 255, 255, 255)
rect(0,0,100,100)
end
Which draws a tilted rectangle somewhere on the screen. I wonder how can I detect if a given point (e.g. touch) is inside the rectangle? Any thoughts are appreciated.
SOLUTION
Thanks to @Ignatz and @LoopSpace I ended up with pretty simple and elegant solution for 2D rects. Just few lines of code allow to convert a point from world coordinates to current matrix and vice verse. The full code is below.
mm = matrix()
function draw()
translate(300,300)
rotate(30)
scale(2,1.5)
fill(255, 255, 255, 255)
rect(0,0,100,100)
mm = modelMatrix()
end
function touched(touch)
if touch.state ~= BEGAN then return end
local localPoint = worldToLocal(touch)
local worldPoint = localToWorld(localPoint)
print(touch.x, touch.y) -- the original touch point
print(localPoint) -- the point in rect coordinates
print(worldPoint) -- this should be the same as the original touch
if localPoint.x >= 0 and localPoint.x <= 100 and
localPoint.y >= 0 and localPoint.y <= 100 then
print("HIT!")
end
end
function multiplyVec2ByMatrix(vec, mat)
vec = vec4(vec.x, vec.y, 0, 1)
-- Normaly the code below should look like "local resultVec = mat*vec"
-- but as soon as something is broken in Codea right now multiply them manualy
local resultVec = vec4(
mat[1]*vec[1] + mat[5]*vec[2] + mat[09]*vec[3] + mat[13]*vec[4],
mat[2]*vec[1] + mat[6]*vec[2] + mat[10]*vec[3] + mat[14]*vec[4],
mat[3]*vec[1] + mat[7]*vec[2] + mat[11]*vec[3] + mat[15]*vec[4],
mat[4]*vec[1] + mat[8]*vec[2] + mat[12]*vec[3] + mat[16]*vec[4]
)
return vec2(resultVec.x, resultVec.y)
end
function localToWorld(localPoint)
return multiplyVec2ByMatrix(localPoint, mm)
end
function worldToLocal(worldPoint)
if mm:determinant() == 0 then
return nil
else
local resultVec = multiplyVec2ByMatrix(worldPoint, mm:inverse())
return vec2(resultVec.x, resultVec.y)
end
end
Many of them. Mostly sprites. Rectangle is just an example.
Trying to figure out how this locating from coolcodea works.
Meanwhile what is the difference between modelMatrix(), viewMatrix() and projectionMatrix()?
@Iavmax If your going to be drawing sprites, then maybe you could use circles or overlapping circles or ellipses instead of rectangles. It’s very easy to determine if a touch is within a circle or ellipse.
@LoopSpace Well, if you have it already explained somewhere, please link, I would try to read for self education even if it’s too math.
BTW. I get how to convert a world point (touch) to my rect or sprite coordinates. But is it possible somehow to use this code for the opposite conversion? I mean if I have a point inside a rect how do I get a wold point?
@Ignatz thank you, this really works. And mat4 * vec4 is really broken in Codea. But thanks to @LoopSpace I have function applymatrix4(v,m) which works
So if
worldPoint = localPoint * modelMatrix()
then I can assume that getting local point should be as simple as
localPoint = worldPoint / modelMatrix()
But how to divide vec4 / mat4? Or it’s too naive and I can’t really do like this?j
@Ignatz and @LoopSpace - thank you guys for your help. I finally figured it out. The solution is in the original question above to make it easier to find if somebody will need it.