On Tue, 5 May 2009, Zhichu Chen wrote:
On Tue, May 5, 2009 at 11:04 PM, Taco Hoekwater
wrote: Zhichu Chen wrote:
What I want exactly is how to determine if there's anything on some region of the picture. I need this to test if the random point I picked is useful.
That is easy to answer: you can't (well, not unless you invest a *lot* of effort into creating a bitmap edge structure). Well, quick and pain.
However what you can do is ask metapost to calculate intersectionpoints with (the most likely ones of) the already existing objects. This may be the easiest solution (even though it will be so slow that for large numbers of items you may be forced to start a division tree).
The core trick is that you randomly place a circle with random radius inside an x-y field, and you keep those paths/pictures in an array. For each newlyt generated circle, you look for an intersection with all the already existing ones (and the rectangle borders) and keep trying to re-place it until there are no more collisions.
Seems that I don't have too many choices. Maybe using lua to do the math and throwing the result to metapost is faster? I think I can do this, but I don't know how. The documents are a little limited.
Here is an attempt with lua. Aditya \startluacode third = third or {} function third.generate (x,y,r) return { ["center"] = {math.random() * x, math.random()*y} , ["radius"] = math.random() * r } end function third.distance (p1, p2) return math.sqrt( (p1[1] - p2[1])^2 + (p1[2] - p2[2])^2 ) end function third.feasible (c, list) if list then for i,v in pairs(list) do if third.distance (c["center"], v["center"]) < c["radius"] + v["radius"] then return false end end end return true end function third.add_circle (x,y,r,list) local c = {} repeat c = third.generate(x,y,r) until third.feasible(c,list) return c end function third.fill_circles(n,x,y,r) local list = {} for i=1,n do table.insert(list, third.add_circle(x,y,r, list)) end return list end function third.toMP(c, scale) local tprint = function(s) tex.sprint(tex.ctxcatcodes,s) end local scaled = function(p) return ("(" .. p .. "*" .. scale .. ")") end tprint("draw fullcircle scaled " .. scaled(2*c["radius"]) .. " shifted (" .. scaled(c["center"][1]) .. "," .. scaled(c["center"][2]) .. "); \n") end function third.show_circles(n,x,y,r) local tprint = function(s) tex.sprint(tex.ctxcatcodes,s) end local list = third.fill_circles(n,x,y,r) tprint("\\startMPcode") for i,v in pairs(list) do third.toMP(v, "1cm") end tprint("\\stopMPcode") end \stopluacode \def\drawCircles{\ctxlua{third.show_circles(100,10,10,2)}} \starttext \drawCircles \stoptext