janpaul123 / paperprograms

Run Javascript on pieces of paper!
https://paperprograms.org
MIT License
484 stars 55 forks source link

Expose marker data #53

Closed paulsonnentag closed 6 years ago

paulsonnentag commented 6 years ago

This pull request changes two things:

I haven't implemented the local position conversion, because I realized that it's possible that a paper has multiple canvases with different sizes. I think it's better to have a utility function to convert global coordinates to local coordinates. I want to wait until #44 is merged which restructures paper.js to allow imports.

shaunlebron commented 6 years ago

I realized that it's possible that a paper has multiple canvases with different sizes. I think it's better to have a utility function to convert global coordinates to local coordinates

I was wanting something like this too. Might make sense to attach a projection matrix to each canvas returned by paper.get('canvas', ...)

paulsonnentag commented 6 years ago

I need some help with transforming the point to local coordinates. I don't really understand how the matrix calculations work. I thought I could do it like this:

const projectionMatrix = forwardProjectionMatrixForPoints(program.points)
const relativePosition = projectPoint(marker.position, projectionMatrix)

Both marker.position and program.points are the original coordinates from detectProgram (value range between 0 and 1). I expected to get a transformed position relative to the top left of the paper (value range between 0 and 1) but this doesn't work.

shaunlebron commented 6 years ago

I learned about it mainly from the figure below in this paper, and experimented with it in this notebook:

screen shot 2018-05-03 at 9 06 06 pm

The forward projection (case 1 above) maps unit-square coords to those inside the given quad corners. For example, it maps 1,1 to corner 2.

In context, if you take a local coord inside the paper's canvas, divide it by the canvas size, then project it with the result of forwardProjectionMatrixForPoints you will get its coordinates on the supporter canvas.

This marker problem requires the inverse (case 2 above). Luckily, the paper describes that the inverse of a projection mapping is itself a projection mapping, and it can be created by taking the adjugate:

const forward = forwardProjectionMatrixForPoints(program.points);
const inverse = forward.adjugate();

let relativePosition = projectPoint(marker.position, inverse);
relativePosition = mult(relativePosition, {x: canvas.width, y: canvas.height}); // rescale

And actually, you can avoid that rescaling part by multiplying it with a "canvas size" matrix, though I can never remember the right order (sorta like case 3 above). Example is here though:

https://github.com/janpaul123/paperprograms/blob/c4eeb5a57ff0002f40541c87da2d623e59bab5e0/client/projector/Program.js#L179-L181

janpaul123 commented 6 years ago

@paulsonnentag would you like me to merge this PR and then follow up with local coordinates in a second PR (after you figure out the matrix stuff) or want to do it all at once?

paulsonnentag commented 6 years ago

I would like to finish the local coordinates first and also update the documentation

paulsonnentag commented 6 years ago

@janpaul123 ready to merge

janpaul123 commented 6 years ago

So cool. Can't wait to try this out soon!