-
-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add arrows and arrows3d renderers #67
Conversation
add arrow-head-size-scale & arrow-head-angle-scale to allow user change behavior of function draw-arrow.
add two parametersto function draw-arrow now it is (draw-arrow v1 v2 [head-size-scale (arrow-head-size-scale)][head-angle-scale(arrow-head-size-scale)])
add arrows and arrows3d to plot arrows
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some comments about his changes, but it is getting late here and I will finish up the review tomorrow. In particular I would like to propose some changes to the documentation wording of the new parameters and renderers.
Overall the changes look good, but there are two things I find odd, although they won't prevent merging this pull request:
- the fact that arrows are connected to each other seems un-intuitive to me, I would have expected each arrow with start and end points to be specified individually. Also, I would have expected to be able specify the arrow as a position + direction (with magnitude) vector, in addition to the start and end positions
- the fact that the arrow head parameters cannot be specified as function parameters for the renderer seems a limitation to me. It is OK to have parameters at the "plot level", but other drawing attributes of the arrows (e.g. line style, width and color) can be set for each individual renderer.
I think you're comment about wanting to specify the arrow by base-point and vector is valid. If it's ok I will also move the renderers to their own files. |
Tomorrow I will try to expose the arrow-head parameters to the renderer. And add more tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some more comments based on your last updates, but overall the changes look good. At this time, it seems you are the only one which will use the arrows renderer and if this interface suits you, we can stop here. We can always extend the interface later to accept the size and head as parameters to the renderer.
With regards to merging or rebasing
I will squash merge this pull request, so it does not matter to me. I personally prefer merging, as it seems simpler to me and there is less chance of loosing changes, but it is your repository, and your choice :-)
With regards to adding tests
This pull request should add tests which cover the basic functionality, but we don't need to add too many individual tests. I think the following would be sufficient:
- one 2D plot of "connected arrows" and "point +_magnitude" arrows (on the same plot), with a custom arrow size using absolute values and a custom arrow angle
- one 3D plot of "connected arrows" and "point + magnitude" arrows (on the same plot), with a custom arrow size using relative values and a custom arrow angle
- one 2D vector field plot with a custom arrow size using absolute values and a custom arrow angle
- one 3D vector field plot with a custom arrow size using relative values and a custom arrow angle
for the vector field plots, you can copy some existing vector field examples -- however, add the new tests to the test file of this pull request -- one way to be confident that this code does not break existing plots is that the existing tests don't change...
I think this fixes the remaining points. Thanks already for putting your time into reviewing this. |
Thanks for removing the mention of the "nan". As you know, the feature will remain in the code base and it is unlikely to change. Also, I actually have a use case which draws a lot of disconnected lines as separate lines renderers -- this is somewhat slow as there are thousands of lines. I will try the "nan" trick to see if the rendering is faster in that case and if it turns out that using this technique improves rendering performance, I will update the documentation and add some unit tests to make it official. I will give this PR another look tomorrow morning (Australia time...) before merging it in, but it looks good to me. Thanks for making all the changes and picking up the work that was started two years ago. |
Unfortunately, we have a bug when zooming, unzooming the plot: This is probably caused by the fact that the plot-area draw-arrow method will not draw an arrow if its base is not in view, but given that this is used for vector fields as well, I don't want to immediately remove it, although probably extending the check to include whether
|
I added a check to render an arrow if either end is in the plot area, but now it fails if both ends are outside, but the body is inside the plot -- I think the main issue for this is that the original arrow code assumed that arrows would be small, since they were used for vector fields. Now with these renderers arrows can be quite long. I don't want to remove the end-point check unconditionally, as I am not sure what effect would have on the performance of the vector field renderers. The 3d plot seems to handle this case differently, but it would have problems with the arrow head: if both ends are outside of the plot, it uses |
My only idea now is to have another method on I don't want to add a "clip" flag to A similar thing needs to be done for the 3D plot. Do you have any other idea about this? |
This reverts commit d8c90de.
I reverted my last change, as I think we should leave Four arrows should be visible in each plot (the relevant part of them). Once this is fixed, the code below can be converted to a unit test, to make sure the functionality will not be broken in the future. #lang racket
(require plot)
(arrow-head-size-or-scale '(= 50))
(plot (list
(arrows '((0 5) (3 5)) #:color 1 #:width 3 #:label "start OUT, end OUT")
(arrows '((0 4) (2 4)) #:color 2 #:width 3 #:label "start OUT, end IN")
(arrows '((1.5 3) (3 3)) #:color 3 #:width 3 #:label "start IN, end OUT")
;; Note: the two ends of the arrow head should be visible inside the plot
(arrows '((1.5 2) (2.6 2)) #:color 4 #:width 3 #:label "start IN, end JUST OUT (ears visible)")
(arrows '((0 1) (2.6 1)) #:color 5 #:width 3 #:label "start OUT, end JUST OUT (ears visible)"))
#:x-min 1 #:x-max 2.5
#:y-min 0 #:y-max 6
#:legend-anchor 'bottom-left)
(plot3d (list
(arrows3d '((0 5 0) (3 5 0)) #:color 1 #:width 3 #:label "start OUT, end OUT")
(arrows3d '((0 4 0) (2 4 0)) #:color 2 #:width 3 #:label "start OUT, end IN")
(arrows3d '((1.5 3 0) (3 3 0)) #:color 3 #:width 3 #:label "start IN, end OUT")
;; Note: the two ends of the arrow head should be visible inside the plot
(arrows3d '((1.5 2 0) (2.6 2 0)) #:color 4 #:width 3 #:label "start IN, end JUST OUT (ears visible)")
(arrows3d '((0 1 0) (2.6 1 0)) #:color 5 #:width 3 #:label "start OUT, end JUST OUT (ears visible)")
)
#:x-min 1 #:x-max 2.5
#:y-min 0 #:y-max 6
#:z-min -1 #:z-max 1
#:legend-anchor 'bottom-left) |
Cool. |
Thinking a bit more about this, I want to check how often vector-field skips a vector. If I remember correctly, it divides the given area in squares and uses it's center point to draw an arrow. If the arrows are automatically scaled, the vectors will always be inside the plotting area. If a different scaling is used. I think an argument can be made for leaving the base of the vector drawn anyway, even if the end is not. |
I decided not to draw the arrow-head when the end-point is not in the plot. It gets very unpredictable/counterintuitive when you start zooming. If the size is absolutely defined, zooming in just behind the end might make the arrow-head disappear (because in pixels, the end is now a long way away). Similarly, the angle is defined in absolute dc-coordinates, if you zoom in with a wide y range and a short x range, the end of the arrow can jump around in unexpected ways. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not have time to review the changes in detail (will do so over the next few days, but here is some initial feedback)
There are two mistakes in the documentation (I pointed them out in comments)
I would like the test cases to be simplified and based on the example given in one of my previous comments. The problem is that, when tests fail, the developer has to compare the sample image with the new image to determine what is wrong, and this can be sometimes difficult if the plots show a seemingly random assortment of arrows. As such it would be good if the sample plots would show clear and easy to follow examples of for both the 2d and 3d plots (each case should have a different color and a short label identifying it in the legend):
- an arrow drawn completely inside the plot area
- an arrow drawn with the start outside the plot area but the end inside
- an arrow drawn with the start inside and the end outside ("just outside" can also be made a test case, to show that we don't draw the arrow head)
- an arrow drawn with the start and end outside
- the above can be mixtures of point-to-point arrows and "origin + magnitude" arrows as well as different combinations of the head size and angle specifications.
- perhaps add an example of "chaining of arrows", i.e. drawing multiple arrows using a single renderer.
The example I gave already covers most of these cases.
@@ -358,24 +358,27 @@ For example, to plot an estimated density of the triangle distribution: | |||
[#:width width (>=/c 0) (arrows-line-width)] | |||
[#:style style plot-pen-style/c (arrows-line-style)] | |||
[#:alpha alpha (real-in 0 1) (arrows-alpha)] | |||
[#:arrow-head-size-or-scale size (or/c (list/c '= (>=/c 0)) (>=/c 0)) (arrow-head-size-or-scale)] | |||
[#:arrow-head-size-or-scale angle (>=/c 0) (arrow-head-angle)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would presumably be arrow-head-angle
?
@@ -142,6 +142,8 @@ Returns a renderer that plots a vector-valued function of time. For example, | |||
[#:width width (>=/c 0) (arrows-line-width)] | |||
[#:style style plot-pen-style/c (arrows-line-style)] | |||
[#:alpha alpha (real-in 0 1) (arrows-alpha)] | |||
[#:arrow-head-size-or-scale size (or/c (list/c '= (>=/c 0)) (>=/c 0)) (arrow-head-size-or-scale)] | |||
[#:arrow-head-size-or-scale angle (>=/c 0) (arrow-head-angle)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing the latest round of changes -- I think adding the arrow renderers was more work than you initially estimated...
There are a few more issues with the arrows renderers, but they are not critical and I think this pull request is good to merge. I will document the remaining problems in a separate issue, and we'll work on them as time allows.
PR to address remaining issues of #42
some points:
Sample code:
Produces: