On Tue, 5 May 2009, Zhichu Chen wrote:

On Tue, May 5, 2009 at 11:04 PM, Taco Hoekwater <t...@elvenkind.com> 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

___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the 
Wiki!

maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
webpage  : http://www.pragma-ade.nl / http://tex.aanhet.net
archive  : https://foundry.supelec.fr/projects/contextrev/
wiki     : http://contextgarden.net
___________________________________________________________________________________

Reply via email to