Find which points from a multitouch are closest to each corner

Aug 21 2014 | 5:32 pm
Hey there, working on a multitouch thing for live projection. The idea is that there are four points on the multitouch which correspond to a cornerpin object. Essentially you can map out a quad live. Problem is, I don't trust the operators to know which child on the multitouch is correct, so I'd like to take that out of the equation. I'm guessing the best way would be to compare each touch to a corner, and then have a series of gate objects to direct them to the proper "bottom_left" type message on cornerpin. Thoughts?

• Aug 21 2014 | 9:38 pm
the quick-n-dirty method to use is by doing taxicab geometry to find each distance: http://en.wikipedia.org/wiki/Taxicab_geometry
This gives you a single number as the distance, and shortest distance wins. It might help if you purposefully made the system a little sluggish, so that you don't get flicker in the center states... perhaps look at http://en.wikipedia.org/wiki/Hysteresis , too.
• Aug 21 2014 | 9:42 pm
Was hoping for a nice MAX object that did it for me, which is usually the case after banging my head against the wall ;-) And thank you for your suggestion, I think the flicker thing is a good point. I ended up doing it in LUA; I'm more of a linear programmer.
this.inlets = 4
this.outlets = 4

function list(x1, y1, x2, y2, x3, y3, x4, y4)
v = {}				-- vector array
v = {x1, y1}
v = {x2, y2}
v = {x3, y3}
v = {x4, y4}

-- find TL point
local bestFit = 100	-- arbitrary starting value to compare to
for i=1,4 do	-- loop 4 times
local d = distance (v[i], v[i], 0, 0)
if d < bestFit then
TL = {v[i], v[i]}	-- assign top left corner
bestFit = d
end
end

-- find TR
local bestFit = 100	-- arbitrary starting value to compare to
for i=1,4 do	-- loop 4 times
local d = distance (v[i], v[i], 1.0, 0.0)
if d < bestFit then
TR = {v[i], v[i]}	-- assign top left corner
bestFit = d
end
end

-- find BR
bestFit = 100	-- arbitrary starting value to compare to
for i=1,4 do	-- loop 4 times
local d = distance (v[i], v[i], 1.0, 1.0)
if d < bestFit then
BR = {v[i], v[i]}	-- assign top left corner
bestFit = d
end
end

-- find BR
bestFit = 100	-- arbitrary starting value to compare to
for i=1,4 do	-- loop 4 times
local d = distance (v[i], v[i], 0.0, 1.0)
if d < bestFit then
BL = {v[i], v[i]}	-- assign top left corner
bestFit = d
end
end

outlet(0,TL)
outlet(1,TR)
outlet(2,BR)
outlet(3,BL)
end

function distance ( x1, y1, x2, y2 )
local dx = x1 - x2
local dy = y1 - y2
return math.sqrt ( dx * dx + dy * dy )
end

• Aug 21 2014 | 9:57 pm
ah, okay, sometimes it's hard to ascern the skill of the patcher guy/girl online here ;)
so yeah, in a "proper scenario" you do the pythagorean formula (like you did at the bottom) and then test for fit. In max we have the lovely "zl sort" which'll happily let you skip about 30 lines of code after you've calculated the distances.
• Aug 22 2014 | 8:04 pm
@PrismSpecs: note that if you're concerned about performance, you could skip the call to math.sqrt() in your distance() function. It is a simple fact of arithmetic that for non-negative numbers, x< y iff x^2 < y^2.
If you do this, you might want to rename the function distance-squared() or distance2().