brownplt / code.pyret.org

Website for serving Pyret to folks.
Other
24 stars 45 forks source link

add-polygon #304

Closed BootstrapJen closed 4 years ago

BootstrapJen commented 5 years ago

add-polygon needs to be implemented in Pyret.

https://docs.racket-lang.org/teachpack/2htdpimage.html#%28def._%28%28lib._2htdp%2Fimage..rkt%29._add-polygon%29%29

blerner commented 5 years ago

Let's break this down into simpler pieces, please, and figure out the use-cases a bit better. I don't want to blindly copy the 2htdp/image API here; I don't think its design is a great fit for Pyret. add-polygon does several things at once, none of which are directly supported in one step by Pyret. It takes a list of points (which are used nowhere else in the API) and an image, treats the image as if it had absolute coordinates (which is unlike all other image-processing combinators), and overlays the polygon onto the image (which is already supported by overlay and overlay-xy). In other words, add-polygon is similar to overlay/xy combined with polygon (from 2htdp/image)

What is the usage scenario in which we need this function? Would that need be satisfied by some version of supporting polygon? How do you want students to specify points? When do they learn how to process lists well enough to construct a usage of this API?

BootstrapJen commented 5 years ago

If polygon were supported, then yes, we could make it work in conjunction with overlay/xy. Thanks!

This is for an internal library, being used for placing teacher- and student-defined polygons on a graph image to teach geometric transformations in a teachpack. In this teachpack, there is a data structure called Shape which is a list of Posns and a color.

Students would be given a template with which to create their own shapes, such as: myShape = shape([list: posn(-0, 4), posn(-3, -4), posn(4, -4), posn(4, 6)], "green")

Here's a link to the teachpack in its current state (render and render-both are commented out, since they were the functions that relied on add-polygon.)

https://code.pyret.org/editor#share=176YonBpGfPAXiFXtLKAJRUH6gBUUjClX&v=bf92f5e

jpolitz commented 5 years ago

In WeScheme Posn is a built-in concept, I'd vote for just using tuples in Pyret.

If we want to be as “raw” as possible we could use

polygon :: Array<{Number;Number}> -> Image

Though given the availability and prevalence of lists, I think

polygon :: List<{Number; Number}> -> Image

probably makes the most sense. It will be most reasonable for students to write [list: ...] probably.

There's a bit of a design space here. We could even get away with making this be a collection constructor that takes a raw array of 2-tuples for the points:

[polygon: {1; 4}, {100; 300}]

That would certainly save typing at the cost of new syntax. It would definitely not quite look like WeScheme, and the direct translation might have some value.

There's definitely a way to add this, though, and since it's mostly in a library we just need to pick the right primitive for image to provide and build on that. I think

polygon :: List<{Number; Number}> -> Image

is probably the way to go here. It will also jive nicely with what we teach physics teachers, which includes tuples.

blerner commented 5 years ago

The downside to this, as I'd emailed with Jen about separately, is that's we'd be baking in the interpretation of pairs-of-numbers as Cartesian points, as opposed to e.g. polar points. Making Point be a datatype gives us the flexibility later to add a second constructor, if we so chose. It also allows us to talk about my-point.x and my-point.y, rather than my-point.{0}, which for this audience I think would be a large win for readability.

The downside, of course, is verbosity in constructing lots of points.

jpolitz commented 5 years ago

Thanks for summarizing here. I don't object to making Point be a datatype that's exposed by image.

schanzer commented 5 years ago

Ditto. I like the idea of a Point datatype that’s extensible, and having a nice mapping to WeScheme is icing on the cake.

shriram commented 5 years ago

Also, Cartesian points may be 2d or 3d (and I suppose 1d as well).

@blerner Can we prioritize this item? Jen is waiting on it for something teachers are asking about.

blerner commented 5 years ago

2d points and 3d points aren't work-alike, though, right? Unlike Cartesian and polar representations of 2d points, both of which could be used in making a polygon, a 3d point can't. You could have Cartesian, cylindrical, and spherical coordinates that are all work-alike, and form a separate data type Point3D. So this seems to argue to me that Point should be a datatype, and alias it to Point2D (or maybe the other way around), and that we create a Point3D datatype so that in the future if we decide to design a 3d graphics package, the type is ready for us.

blerner commented 5 years ago

Working on implementing (a prototype of) this on the new image library branch. I'm calling the function point-polygon :: List<Point>, Mode, Color -> Image, to contrast it with regular-polygon that already exists. Question: which way is positive-y? Specifically, if I have the points [list: point(100, 100), point(100, 130), point(200, 100)], is the right angle in the bottom-left corner and the whole thing points up, or is the right angle in the top-left corner and the whole thing points down? (I think it's uncontroversial that positive-x points right, so the right angle here must be on the left side of the image...)

Additionally: following the rest of the polygonal images, the pinhole of this image is placed at the average of its points. I'll expose a new pair of functions image-pinhole-x/image-pinhole-y :: Image -> Number to obtain the pinhole of an image, so that you can translate it how you wish as part of your teachpack. By default, though, the image will appear to be centered at its own origin: i.e., the following two images will appear identical: point-polygon([list: point(0, 0), point(0, 3), point(4, 0)], ...) and point-polygon([list: point(10, 10), point(10, 13), point(14, 10)], ...). (Their only difference will be in their pinholes, which will be offset by (10,10) relative to each other.)

blerner commented 5 years ago

Err... the average of its points, after translating to touch the x or y axes. So, the pinhole won't actually help you very much, on an absolute basis.

BootstrapJen commented 5 years ago

The right angle would be on the bottom-left corner. Thanks!

BootstrapJen commented 5 years ago

Checking in on this - any updates?

On Mon, Jul 1, 2019 at 1:38 PM Ben Lerner notifications@github.com wrote:

Err... the average of its points, after translating to touch the x or y axes. So, the pinhole won't actually help you very much, on an absolute basis.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/brownplt/code.pyret.org/issues/304?email_source=notifications&email_token=AKJHOUQOMCF4SXZMD3HHTMLP5JFKNA5CNFSM4HDMLUUKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODY67RUQ#issuecomment-507377874, or mute the thread https://github.com/notifications/unsubscribe-auth/AKJHOURURP3PB62IF3G74Z3P5JFKNANCNFSM4HDMLUUA .

-- Jennifer Poole Midwest Regional Manager https://www.bootstrapworld.org

blerner commented 4 years ago

This is implemented, but not yet merged. https://github.com/brownplt/code.pyret.org/blob/new-image-lib/src/web/js/trove/make-image.js#L598-L613 and https://github.com/brownplt/code.pyret.org/blob/new-image-lib/src/web/arr/trove/image-structs.arr#L9-L17 provide the implementation, but Joe and I still need to merge the big image library update PR, which we finally can feasibly do, now that the modules work has landed.

BootstrapJen commented 4 years ago

Checking in - has the merge gone through?

blerner commented 4 years ago

This has just now landed on horizon, and will be available to play with soon :)

schanzer commented 4 years ago

CHRISTMAS CAME EARLY

jpolitz commented 4 years ago
image