HP Forums
Python graphic module: observations, assumptions, suggestions - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: HP Prime (/forum-5.html)
+--- Thread: Python graphic module: observations, assumptions, suggestions (/thread-17775.html)



Python graphic module: observations, assumptions, suggestions - Guenter Schink - 11-30-2021 08:50 PM

I've downloaded the last (inofficial?) update to see if something significant has changed in the Python environment. Well the <draw_filled_polygon()> function no longer lets the G2 reboot Smile Here are my findings. I don't pretend that they are correct, however...

I had a closer look at the various entries of the "graphic module"
  1. cyan, magenta, yellow, blue, red, green, black, and white are simply constants of which you can simply print what values they consist of. Caution: new values can be assigned easily.
  2. set_pixel(), draw_pixel: can't see any difference. 3 arguments --> (x, y, color) Various experiments with lists and tuples (a list of pixels perhaps), always raised syntax error
  3. draw_line: 5 arguments --> (x1,y1,x2,y2,color) no surprise
  4. draw_polygon(): 2 arguments. -->list (or tuple) of coordinates, color. No need to repeat the first co-ordinate, the polygon simply closes in on the first point. E.g. draw_polygon([(10,10),(100,100),(10,200)],red) gives you a nice triangle, not filled, red perimeter.
  5. draw_filled_polygon(): same as above. Observation: draw_filled_polygon([(0,80),(160,120),(0,80)],red) draws two triangles heading their tips to each other. the right hand triangle has a center line of the background color. This doesn't seem to occur when one of the "80" is changed to e.g. "81" or "79" - weird.
  6. draw_rectangle(): arguments --> (x, y, width, height, color) . Should draw the perimeter of an rectangle - instead it draws a filled rectangle like the next one.
  7. fill_rect(), draw_filled_rectangle(): can't see any difference. Arguments as above.
  8. draw_circle(), draw_filled_circle(): As the name suggests either unfilled or filled circle. 4 Arguments --> (x,y, radius,color) no surprise
  9. draw_arc(),draw_filled_arc(): As the name suggests either unfilled or filled arc: 6-8 arguments -->(x,y, x_radius, y_radius, angle_start, angle_end[, color[, unknown_int]] An angle of "0" denotes "east" the arc is painted clockwise. Observation ERROR: The draw_arc() doubles the angle values, while the draw_filled_arc() behaves as expected. The last argument "unknown_int" didn't show any effect with my various approaches. Color can be omitted, default is black - it's 0
  10. get_pixel() doesn't return anything reasonable: 2 or 3 arguments: When invoked with 2 arguments it returns the tuple (0,0,0) when invoked with 3 arguments it returns -16777216 that equals -0x1000000
  11. draw_string(): seems to be broken but does something at least. 3-6 arguments --> (x,y,text[,text_color[,bg-color[,unknown-string]]]: Observation: The "unknown_string" did nothing discernible. A background is always painted, but doesn't match the height of the text. If bg-color is omitted, my Prime selects cyan, why? If the text_color is omitted the color is black. The font is very large!
  12. clear() and clear_screen() can't see any difference: Arguments 0 or 1 --> () denotes cyan, (color) whatever color you've chosen.


To get around the wrong implementation of draw_rectangle() and draw_arc() I've written a small workaround. The objective is to code as if the functions worked properly, so once they are rectified there's only minimum change to the code. Only the alias import and the two definitions would have to be deleted.


Code:
from graphic import *
from graphic import draw_arc as d_arc 
# this allows to redefine draw_arc while preserving the ability of the original function

def draw_rectangle(x,y,width,height,color): 
     # this overwrites the function of graphics with the same name
      draw_polygon([(x,y),(x+width,y),(x+width,y+height),(x,y+height)],color)

def draw_arc(x,y,x_radius,y_radius,start,end,color):
       d_arc(x, y, x_radius, y_radius, start//2, end//2, color)
       # using the original function but correcting the angles

Hope this is of use for someone. Perhaps you have a different insight. Comments, corrections are very welcome of course.

Günter

edit: added some missing arguments


RE: Python graphic module: observations, assumptions, suggestions - toml_12953 - 11-30-2021 11:11 PM

(11-30-2021 08:50 PM)Guenter Schink Wrote:  I've downloaded the last (inofficial?) update to see if something significant has changed in the Python environment. Well the <draw_filled_polygon()> function no longer lets the G2 reboot Smile

Hope this is of use for someone. Perhaps you have a different insight. Comments, corrections are very welcome of course.

Günter

Do you know if there's a command in the graphic module to let the user set screen coordinates and use those rather than pixel coordinates? I also notice the parameters are pickier than those in the hpprime module. There, you can use real parameters. In graphics you have to manually convert to int first.


RE: Python graphic module: observations, assumptions, suggestions - Guenter Schink - 12-01-2021 07:55 PM

(11-30-2021 11:11 PM)toml_12953 Wrote:  Do you know if there's a command in the graphic module to let the user set screen coordinates and use those rather than pixel coordinates? I also notice the parameters are pickier than those in the hpprime module. There, you can use real parameters. In graphics you have to manually convert to int first.
a) screen coordinates? I don't think so, haven't seen anything that points at such possibilities
b) Integers? Yes that's the way it is. Annoying but manageable.

I believe the entire Python implementation was published prematurely. It's a really nice approach, what a pity that it's so buggy. When I play with Python, there is a steady flow of new bugs and oddities. So sad Sad

Having the hpprime module I think the graphic module is superfluous, the functions should be included in the hpprime module, with a streamlined structure of the function names and a help that clearly and correctly describes syntax and arguments.



Günter


RE: Python graphic module: observations, assumptions, suggestions - parisse - 12-02-2021 05:46 PM

The graphic module is the same as in KhiCAS for the TI Nspire CX/CX2, Numworks and Xcas MicroPython. It uses the drawing routines from the CAS, that were implemented because they were not available on other calculators. Some command names are synonyms of Numworks kandinsky module commands (this explains some redundancy). Some commands are not available or will not work on the Prime because I lacked time to do that properly with Cyrille. Some commands will not do anything, they are here so that you can run the same Python program on the HP Prime, TI Nspire CX/CX2 or Numworks and Xcas, something you won't be able to do with commands of the hpprime module.

A few comments:
1/ draw_rectangle is a synonym of fill_rectangle for some reasons explained above, you can use draw_polygon for an unfilled rectangle.
2/ if fill_arc has a 8th argument, then it is assumed you want to fill a segment of circle instead of an arc.

The source code of the graphic module of Xcas is available in the giac source code (giac-1.7.0/micropython-1.12/xcas/graphic.c and numworks, nspire, ports/javascript for the Numworks and emscripten JS ports), feel free to propose enhancements!


RE: Python graphic module: observations, assumptions, suggestions - Guenter Schink - 12-02-2021 09:14 PM

Merci Bernhard for these explanations.

That leaves just two real bugs in the graphics module. Firstly complete lack of documentation and secondly the draw_arc() function where the values of the angles are doubled. Interesting concept to provide a programming language with functions that are supposed to either work or not without telling ...

How much time I could have saved if something like your explanations was available beforehand. But I assume that's not your responsibility.

There was a Beta-testing period after Python was introduced, and I sincerely intended to thoroughly report my findings. But after a short while I gave up. As mentioned above "A steady flow of new bugs and oddities " and let's add: reboot, reboot, reboot ...

How comes that almost no programs for the Prime using Python are published yet Sad

Again, most probably not your business.

Günter


RE: Python graphic module: observations, assumptions, suggestions - parisse - 12-02-2021 09:31 PM

draw_arc seems to work correctly on the nspire, it seems therefore that it is a Prime-specific problem, that should make it easier to fix.


RE: Python graphic module: observations, assumptions, suggestions - parisse - 12-04-2021 07:35 PM

Can you confirm that this fails on the Prime:
Xcas session


RE: Python graphic module: observations, assumptions, suggestions - Guenter Schink - 12-04-2021 09:43 PM

As previously described, the filled arc draws o.k. filled black. The unfilled arc draws from 60° (2*30) to 180° (2*90)

[attachment=10146]

to ensure we are talking about the same, I cite the proposed code:
Code:
from graphic import *
draw_arc(100,100,52,52,30,90)
draw_filled_arc(100,100,49,49,30,90,12345)

Günter

Edit: added the proposed code snipped


RE: Python graphic module: observations, assumptions, suggestions - parisse - 12-05-2021 09:13 AM

Then both draw_arc and draw_filled_arc are wrong, cf. the Xcas session (or test the same code on the Nspire CX/CX2 and Numworks). Angles should be mesured in degrees counterclockwise (and 0 degree is oriented to the right). Moreover only the arc should be drawn.
There is something wrong in the C code that calls the Prime corresponding commands from the graphic MicroPython module : I guess Cyrille did call his own functions, unlike on Xcas/Nspire/Numworks where I call CAS graphic functions.


RE: Python graphic module: observations, assumptions, suggestions - parisse - 12-05-2021 10:41 AM

I've found where the bugs are. As I guessed, it is in the Prime-specific implementation: c_draw_arc and c_draw_filled_arc both calls a method FillArc, draw_arc with angles theta1*4096/M_PI, theta2*4096/M_PI and c_draw_filled_arc with theta1_deg*4096/360, theta2_deg*4096/360.
Arguments for the first FillArc should be -theta1*2048/M_PI and -theta2*2048/M_PI and for the second one arguments should be negated. And the angles should probably be exchanged, FillArc seems to work with some specific angle unit (4096=2*pi radians) and clockwise.


RE: Python graphic module: observations, assumptions, suggestions - Guenter Schink - 12-05-2021 10:44 PM

I really appreciate you spending your time on this issue. Because I believe to know how much Cyrille and Tim are constrained in their work , I can't rant as I usually would about that ppp of HP.

Günter