# Arrows do not behave correctly under scaling #112

Closed
opened this Issue Sep 15, 2013 · 3 comments

Projects
None yet
2 participants
Owner

### byorgey commented Sep 15, 2013

 The head/tail are scale invariant and but the shaft is not: that is as it should be. However, the interaction of these facts with the way we do joints leads to funny gaps after scaling. For example: ```a = arrowAt origin unitX main = defaultMain \$ mconcat [ square 5 # alignBL # translate (r2 (-1,-1)) , a , a # scale 4 # translateY 1 ]``` produces
Owner

### byorgey commented Sep 15, 2013

 One possibility that occurs to me for fixing this is to make a new primitive for arrows. All the functions that currently draw arrows would now simply create an arrow primitive; the current implementation would be provided as a default way for backends to draw them. That way we do not actually commit to drawing an arrow until it is done being transformed. I am not 100% sure that this will actually work.
Owner

### jeffreyrosenbluth commented Sep 15, 2013

 This is not primarily a problem with the way we do joints but more just a consequence of the fact the shaft is not scale invariant and the heads and tails are. The shaft in the above example is just too small after scaling. Even arrows with no joints will present problems with scaling. For example if you scale a diagram that has an arrow connecting two points. The two points will not be connected in the result (If the you scale by a factor > 1 the arrow will not reach the points). This can be demonstrated visually by using arrowHead = tri, which has an empty joint. Here is the math for a straight horizontal arrow. Suppose the head and tail (including their joints) are both of length x and the shaft is of length s. This arrow will connect two points A and B, that are s + 2x units apart. After scaling the diagram containing this arrow by n, the points A and B are now n(s + 2x) units apart. Since the head and tail are scale invariant, in order for the arrow to connect A and B the shaft has to be scaled by n + 2(n-1)x/s, instead of n. Things get even more complicated when we consider curved arrows as there may not be a closed form solution for the proper scale factor of a curved shaft. This does not mean byorgey's proposed fix will not work, it may. However, since the arrow heads are pretty much custom, I don't think any of the back ends would be able to draw them without using the provided default.
Owner

### byorgey pushed a commit to diagrams/diagrams-core that referenced this issue Nov 10, 2013

 Brent Yorgey `initial work on implementing "delayed" subtrees` ```Delayed subtrees consist of a continuation which generate a QDiagram when given the accumulated d-annotation at that point in the tree. Useful for things which need to know the final transformation applied to them before deciding what diagram to generate. The prototypical use case is arrows: see diagrams/diagrams-lib#112 . However, I hope this may be useful for other things as well: for example, diagrams which scale normally until hitting some maximum or minimum size, at which point they refuse to scale any further (or more generally diagrams which scale as some non-linear function of the transformation applied to them). The only downside is that the u-annotation must be fixed ahead of time---doing otherwise requires a more general solution for constraint solving.``` `8bb5e17`

### byorgey pushed a commit that referenced this issue Nov 13, 2013

 Brent Yorgey `change arrow' to produce a delayed leaf.` ```The idea is that arrow' can now take the *final* transformation into account so it can properly decide what to draw. See #112. Things seem to be almost working... but it seems we don't quite handle frozen transforms properly yet, since things are flipped in the Y-axis.``` `c355559`

Merged

Merged