Skip to content
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

proc addArc runs indefinitely (at least 12 minutes) for large centre and radius values #403

Closed
kwhitefoot opened this issue Mar 22, 2022 · 3 comments

Comments

@kwhitefoot
Copy link

kwhitefoot commented Mar 22, 2022

This short program never completes. To be precise it runs for at least 12 minutes without completing on my HP Omen 17 inch laptop. It uses very little memory but consumes more than 99% CPU all the time. I extracted the path from a larger program that fails with out of memory in, as far as I can tell, the same area of code.

I instrumented paths.nim and got as far as seeing that the proc that doesn't return is the inner proc addArc inside proc commandsToShapes.

I presume that the path would produce little or nothing inside the boundaries of the image but I'm not sure how to determine that. Is there a short expression or algorithm that can determine whether or not a given path command will produce any visible result? I'm fairly certain that I have used Cairo with similar out of range values and not had to wait long for it to draw. I wasn't using Nim for that though, it was written in Gambas.
I can off course limit the values that my program uses but I would like to have at least a rule of thumb for what sort of limits to apply.

If the arguments to the A command are replaced with the absolute values then the program completes very rapidly.

import pixie, chroma

let
  image = newImage(200, 200)
image.fill(rgba(255, 255, 255, 255))

let  
  pathStr ="""
L -16370.0 -18156.0
A 4100 4100 0 1 0 -19670 -14134
Z
"""

let
  path = parsePath(pathStr)

var
  paint = newPaint(SolidPaint)
paint.color = color(255, 255, 255, 255)

strokePath(image,
           path,
           paint,
           mat3(),
           1,
           ButtCap,
           MiterJoin,
           defaultMiterLimit,
           @[])
@guzba
Copy link
Collaborator

guzba commented Mar 22, 2022

Pixie uses float32 for all float operations. An Arc that enormous at that position requires more precision (the position is the real issue, at -1967, -1413 things work). We can add an exception if we notice we will never be able to complete the process of turning the Arc into line segments.

@guzba
Copy link
Collaborator

guzba commented Mar 22, 2022

Closing this as an exception will now be thrown once you pull the latest Pixie head (not tagged in release yet). We may revisit and use float64 someday if it proves necessary but in this case drawing at a position 20,000 pixels from origin would imply an image 1.5 gigabytes in size (4 byte per pixel, 20,000 x 20,000 pixels).

@guzba guzba closed this as completed Mar 22, 2022
@kwhitefoot
Copy link
Author

Thanks! This is what love about open source, rapid service better than anything anyone could pay for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants