ginga
ginga copied to clipboard
Feature Request: Arc Canvas Type
It would be nice if Ginga had a canvas type for drawing Arc
s. Some background; I use ginga to make a finding chart tool for the HiPERCAM instrument - hfinder
We need to add an element to represent the patrol field of a pickoff arm (see the yellow area below). If there was an Arc
type, I could implement the patrol field in a similar way to the Annulus
object. I've tried adding this myself, but got stuck, and thought it might be a generally useful addition to Ginga.
@StuartLittlefair, sounds like a good addition, and probably would not be too hard. As a temporary workaround, you could make the arm out of a polygon, where the points are made from two bezier curves. I believe there is a function in ginga to return the points for a bezier curve. You would just need to connect the ending point of one arc with the starting point of the second one and vice versa, of course.
Nice looking app, BTW!
Is it always a circular arc, or is possible to be elliptical?
If you want to explore the Bezier approach, there is a function called get_bezier(steps, points)
in ginga.util.bezier
. If, for the points
parameter you pass it 8 control points (for the two bezier curves) and a steps
parameter of something like 30, the output is a set of points that can be passed to Polygon
to make the shape. You'll have to experiment with the steps
parameter, but generally you want the fewest number of points that makes a smooth looking curve. Because it is a polygon, it will handle all rotations, transformations and containment tests naturally.
You might consider adding a Compass
to the canvas, if that would help orient users. Also, the 'o' and 'O' keystroke commands are useful for orienting the field.
Also, off-topic, but apropos showing the nodding of the telescope: we did a similar kind of finder app for Hyper-Suprime Cam (but as a ginga reference viewer plugin). We handled showing the dithering by marking the dither positions by a set of points and making the detector overlay into a CompoundObject
. We then could just calculate the offset from each dither position to the center of the overlay object and simply call the move_delta()
method on the overlay to shift its position for each dither position. I think you could do something very similarly for nodding. We used a combobox where you could scroll using the mouse to set the dither position, and I think we also set up a ginga key binding to go next/prev position.
Here is the method that was called when the dither position changed:
def _show_step(self, n):
self.logger.info("moving to step %d" % (n))
ra, dec = self.calc_dither(n)
image = self.fitsimage.get_image()
data_x, data_y = image.radectopix(ra, dec)
delta_x = data_x - self.ctr_pt.x
delta_y = data_y - self.ctr_pt.y
self.ccd_overlay.move_delta(delta_x, delta_y)
self.canvas.update_canvas()
return True
This is brilliant, thanks @ejeschke ! Using a bezier curve worked perfectly. Thanks for the other suggestions as well!
Update this issue with a screen shot showing the patrol field!
As requested... The yellow area shows the patrol field for the pickoff arm, and the green "Darth Vader helmet" shows the region left unvignetted by the guide probe. A set of mirrors can pick off any star along the yellow arc and re-image on the CCD to use as a comparison! Need to work on the colour scheme...
Interesting!
What's with the "BAD WCS" in red text? From the line below the image it looks like the image has a valid WCS.
That's caused by the following code failing
(x, y, xn, yn, xe, ye) = image.calc_compass_center()
self.logger.info("x=%d y=%d xn=%d yn=%d xe=%d ye=%d" % (
x, y, xn, yn, xe, ye))
Compass = self.fitsimage.getDrawClass('compass')
compass = Compass(0.9*image.width, 0.1*image.height, xn/5, yn/5, xe/5, ye/5)
compass.color = 'red'
compass.fontsize = 14
self.fitsimage.add(compass, tag='compass')
Which hits this line
@ejeschke - you prompted me to fix that issue, which was caused by me having outdated code for the Compass class. However, I've often wondered if there's a way to hook into the viewer update so that the compass is always drawn on the bottom left of the view, even if the view is panned, zoomed etc?
@StuartLittlefair, that should be easy, but I found a bug in the Compass
type. Please wait a little while I fix it...
@StuartLittlefair, ok, could you install from master and give this a whirl? Add your compass with the parameters x
, y
and radius
specified between 0 and 1. coord
should be "percentage" and fontsize
should be constant (something like 12).
The percentages are percent of the window size, so something like x=0.85, y=0.85, radius=0.085 will give you a compass fixed in the lower right corner of the window. You can resize the window and the compass maintains its position relative to the window. Just experiment with the parameters to get something that makes sense for your app.
@ejeschke thanks - percentage compass works brilliantly!