ui.Path(), Scene question regarding drawing circle segments
I thought it would be something I could easily accomplish but I was wrong.
Was hoping to write a simple program that does the following:
— Draw a dartboard on screen (circle split into 20 equal segments is all I need)
— This works out to be 20 segments that should be 18 degrees each (360/20)
— Set up each segment as a clickable button
— The button.Action will be to highlight the selected segment and place a number label on it
— For example:
— Tapping top center segment will highlight it and place number 1 in segment
— Then, if I tap a 2nd segment, it highlights it (same color as first is fine) and places number 2
— This continues for 3 total selections. However, more is fine.
I keep running into issues doing this.. It could be my lack of Geometry skills, or that I haven’t used Path() before, or maybe I’m just not cut out for programming ;)
What is the best way to go about doing this?
I’ve looked for code and tried reusing a few, but I end up with a weird pie chart that doesn’t ‘slice’ where I expect it to. Or I end up with some pretty cool drawings, from an abstract point of view!
Not true, my friend. Since ios13 (not sure), you need the word 'fullscreen'.
Try with and without to see the difference.
Édit: I like to put the hide_title_bar, True or not, so if you want to change, easier. But that's personal.
you need the word 'fullscreen'
iPad or iPhone or both?
@ccc I only use my iPad for Pythonista. I remember there was a topic about this problem...
But don't ask me more.
@ccc no parameter => "full_screen", not "fullscreen", different views.
Alright, I installed the version of stash mentioned in his repo.
Then conveniently used pip to grab the gestures library to make sure I didn’t mess anything up.
Now the dartboard works like a charm! Thanks again.
I’ll play around with it and see if I can clean it up without breaking it!
I really need to browse git for useful Pythonista modules.
In a week or so I will be back onto the DatePicker program and understanding objC usage in what you gave me there haha. Slowly but surely..
@Robert_Tompkins for the fun...rotated numbers
from objc_util import * . . . #ui.draw_string(str(self.n),rect=(x,y,20,10),font=('Menlo',10)) l = ui.Label() l.frame = (x,y,20,10) l.font = ('Menlo',10) l.text = str(self.n) self['iv'].add_subview(l) o = ObjCInstance(l) a = -a rot = CGAffineTransform(cos(a),-sin(a),sin(a),cos(a),0,0) o.transform = rot self['iv'].image = ctx.get_image()
@Robert_Tompkins just discovered that for up and bottom center slices, lines are hidden by filling.
Thus small correction
#path.add_arc(self.r, self.r, self.r, a, a-18*pi/180, False) path.add_arc(self.r, self.r, self.r, a-0.005, a-18*pi/180+0.005, False)
Ooo awesome. Thanks! I have been playing around with it trying to figure out a way to o’offwet’ the starting point so that the center of the slice on each vertical and horizontal axes line up. (Like on a dartboard).
Let me see if I can throw an image here to show you what I mean.
@Robert_Tompkins not sure that I understand correctly, but try these 3 modified lines
from gestures import * from math import pi,cos,sin,atan2 from objc_util import * import ui class MyView(ui.View): def __init__(self): self.background_color = 'white' iv = ui.ImageView(name='iv') self.r = 400 iv.frame = (10,10,self.r*2,self.r*2) iv.background_color = self.background_color self.add_subview(iv) tap(iv,self.tap_handler) with ui.ImageContext(self.r*2,self.r*2) as ctx: path = ui.Path.oval(0,0,self.r*2,self.r*2) ui.set_color('lightgray') path.fill() ui.set_color('black') for i in range(20): a = -i*18*pi/180+(9*pi/180) # modified x = self.r*(1+cos(a)) y = self.r*(1+sin(a)) path.move_to(self.r,self.r) path.line_to(x,y) path.stroke() iv.image = ctx.get_image() self.n = 0 def tap_handler(self,data): #print('tap_handler:',data.state,data.view) x,y = data.location if ((x-self.r)**2 + (y-self.r)**2) > self.r**2: # tap outside the circle, no action return dx = x - self.r dy = y - self.r a = atan2(-dy,dx)*180/pi + 9 # modified a = (a+360) % 360 s = int(a/18) # segment 0 to 19 self.n += 1 with ui.ImageContext(self.r*2,self.r*2) as ctx: self['iv'].image.draw(0,0,self.r*2,self.r*2) path = ui.Path() a = -s*18*pi/180+(9*pi/180) # modified x = self.r*(1+cos(a)) y = self.r*(1+sin(a)) path.move_to(self.r,self.r) path.line_to(x,y) #path.add_arc(self.r, self.r, self.r, a, a-18*pi/180, False) path.add_arc(self.r, self.r, self.r, a-0.005, a-18*pi/180+0.005, False) path.line_to(self.r,self.r) ui.set_color((1,1,0,1)) path.fill() a = a-9*pi/180 x = self.r*(1+0.5*cos(a)) y = self.r*(1+0.5*sin(a)) #ui.draw_string(str(self.n),rect=(x,y,20,10),font=('Menlo',10)) l = ui.Label() l.frame = (x,y,20,10) l.font = ('Menlo',10) l.text = str(self.n) self['iv'].add_subview(l) o = ObjCInstance(l) a = -a rot = CGAffineTransform(cos(a),-sin(a),sin(a),cos(a),0,0) o.transform = rot self['iv'].image = ctx.get_image() def main(): global main_view main_view = MyView() main_view.present('fullscreen',hide_title_bar=False) if __name__ == '__main__': main()
I assume he wants something like
To make an darts scoring game.
So a central red circle, a larger central green circle (really an annular region), then annular slices from your segments. Two bug divisions radially of what you have already drawn, but with smaller radial cuts at the outside and in the middle. The thin radial segments alternate colors red and green, and the larger segments alternate yellow and black. See the dimensions to get the relative ratios.
I think your code could be modified to draw each segment using a inner and oute radius -- two arcs at different radii, and the lines end at the inner and outer radius, instead of going to the center.
The tap handling would need to take into account the radius, and not just angle
Actually what you have right there is perfect!
@JonB, I don’t need the little things! However, I will probably create a new version of this code and turn it into that for practice! I could definitely use it.
Edit: On second thought, that sounds real complicated. I might quit Python attempting that at this point :)
^^ Dunno how to do inline images haha. I ran out of ideas, so that’s a link to what I have with your changes.
Dunno how to do inline images
Only put a ! just before the "[link text](link url)"
Type on quote (at right of reply) to see commands into a post
@JonB Sorry, but I only wanted to say that I was not sure to understand correctly the sentence
"a way to o’offwet’ the starting point so that the center of the slice on each vertical and horizontal axes line up."
But I know what is a dartboard.
No,I totally misread his post.