You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'd like to package and publish the submodule of this project that draws things on a view of the hyperbolic plane. It currently uses Compose as a backend, because:
I like Compose's declarative style.
This makes it easy to include hyperbolic drawings in a larger Compose layout.
One of my goals for the package is to integrate my hyperbolic drawing features more smoothly into the existing Compose interface. I'd love to have guidance from the Compose community on how to do this (and whether it's a sensible thing to do). With that goal in mind, I have a more specific question about Compose's internals below.
If this issue tracker is the wrong place for this discussion, please redirect me to the right one!
Subtyping Context to manage views
Conceptually, each view of the hyperbolic plane gives its own way to turn hyperbolic forms into Euclidean ones that can be drawn on a page. Correspondingly, I'm inclined to represent each view as a subtype of Context which takes hyperbolic forms as its children, and specifies how to turn them into ordinary Compose forms. A usage mock-up is shown below.
Can I?
Can a subtype of Context do this? Maybe all it would take is a new dispatch rule for compose!, like this:
# PoincaréDiskContext <: HyperbolicView <: Container# HyperbolicContext <: Container# HyperbolicFormPrimitive <: FormPrimitivefunctioncompose!(a::PoincaréDiskView, b::Form{P}) where P <:HyperbolicFormPrimitive# use the poincaré disk model to turn `b` into an ordinary form
a.form_children =cons(applyview(a, b), a.form_children)
return a
endfunctioncompose!(a::PoincaréDiskView, b::HyperbolicContext)
# apply the view recursively to the children of `b`
a.container_children =cons(applyview(a, b), a.container_children)
return a
endcompose!(a::Context, b::Form{P}) where P <:HyperbolicFormPrimitiveerror(@sprintf("Invalid composition: hyperbolic primitives only nest inside HyperbolicView and HyperbolicContext containers."))
endcompose!(a::Context, b::HyperbolicContext)
error(@sprintf("Invalid composition: HyperbolicContext only nests inside HyperbolicView and HyperbolicContext."))
end
Does that seem like a sensible approach? Would any functions other than compose! need new dispatch rules? Should the type structure be revised? (For example, maybe it's better to not make HyperbolicForm a subtype of Form).
Should I?
Some features of Compose, like the transformation system, carry over nicely to the hyperbolic plane. However, I'm worried that other parts of this hyperbolic drawing extension would go against the spirit of Compose. For example, the composition operators hstack and vstack, don't make much sense in the hyperbolic context, and the HyperbolicView contexts described above affect the composition tree in a weird way. Have I chosen a good way to integrate hyperbolic drawing into Compose? Is that even a sensible thing to do?
Mock-up
# UpperHalfPlanePoint <: HyperbolicPoint
a =UpperHalfPlanePoint([im, 1])
b =UpperHalfPlanePoint([cis(π/3), 1])
c =UpperHalfPlanePoint([1, 0])
# HyperbolicView <: Container# typeof(uhp_view) == UpperHalfPlaneContext <: HyperbolicView# typeof(disk_view) == PoincaréDiskContext <: HyperbolicView
uhp_view =hyperbolicview(model=UpperHalfPlane(-1, 1, 2))
disk_view =hyperbolicview(model=PoincaréDisk())
# the contexts `uhp_view` and `disk_view` specify different ways to turn# the hyperbolic `line` and `polygon` forms into ordinary `curve` and# `bezigon` forms. `hypcontext` creates a HyperbolicContext
uhp_img =compose(uhp_view,
(hypcontext(), line([a, b]), stroke("black")),
(hypcontext(), polygon([a, b, c]), fill("deepskyblue"))
)
disk_img =compose(disk_view,
(hypcontext(), line([a, b]), stroke("black")),
(hypcontext(), polygon([a, b, c]), fill("deepskyblue"))
)
# since hyperbolic views are a kind of context, we can compose them as usual
img =compose(context(),
hstack(
compose(context(0.1, 0.1, 0.8, 0.8), rectangle(), stroke("red"), uhp_img),
compose(context(0.1, 0.1, 0.8, 0.8), circle(), stroke("red"), uhp_img)
)
)
The text was updated successfully, but these errors were encountered:
I'd like to package and publish the submodule of this project that draws things on a view of the hyperbolic plane. It currently uses Compose as a backend, because:
One of my goals for the package is to integrate my hyperbolic drawing features more smoothly into the existing Compose interface. I'd love to have guidance from the Compose community on how to do this (and whether it's a sensible thing to do). With that goal in mind, I have a more specific question about Compose's internals below.
If this issue tracker is the wrong place for this discussion, please redirect me to the right one!
Subtyping
Context
to manage viewsConceptually, each view of the hyperbolic plane gives its own way to turn hyperbolic forms into Euclidean ones that can be drawn on a page. Correspondingly, I'm inclined to represent each view as a subtype of
Context
which takes hyperbolic forms as its children, and specifies how to turn them into ordinary Compose forms. A usage mock-up is shown below.Can I?
Can a subtype of Context do this? Maybe all it would take is a new dispatch rule for
compose!
, like this:Does that seem like a sensible approach? Would any functions other than
compose!
need new dispatch rules? Should the type structure be revised? (For example, maybe it's better to not makeHyperbolicForm
a subtype ofForm
).Should I?
Some features of Compose, like the transformation system, carry over nicely to the hyperbolic plane. However, I'm worried that other parts of this hyperbolic drawing extension would go against the spirit of Compose. For example, the composition operators
hstack
andvstack
, don't make much sense in the hyperbolic context, and theHyperbolicView
contexts described above affect the composition tree in a weird way. Have I chosen a good way to integrate hyperbolic drawing into Compose? Is that even a sensible thing to do?Mock-up
The text was updated successfully, but these errors were encountered: