izzyb
izzyb

Reputation: 31

Pycairo scale distortion

I am struggling to draw a circle onto a rectangular png background. Whenever I try to draw a circle, it is stretched according to the scale of my image--making it an ellipse instead of a circle.

Here is the set up:

#set background image
surface = cairo.ImageSurface.create_from_png (image)
context = cairo.Context (surface)

WIDTH = cairo.ImageSurface.get_width(surface)
HEIGHT = cairo.ImageSurface.get_height(surface)
context.scale (WIDTH, HEIGHT)

And here is the circle drawing function, (x coord, y coord, radius, color value) and functions used for positioning:

def draw_node(cx,cy,r, rgb):
  context.arc(x_scale(cx), y_scale(cy), r, 0, 2 * math.pi)
  context.set_source_rgb(rgb[0]/255.0,rgb[1]/255.0,rgb[2]/255.0)
  context.fill()
  context.stroke()

def x_scale (x):
  width = 1000.0
  return (x + .5) / width

def y_scale (y):
  height = 1000.0 * HEIGHT / WIDTH
  return (y + .5) / height

I would particularly appreciate any advice on how to resolve the systemic scaling issue, but I would also appreciate advice on how to draw a circle within the confines of my existing setup.

Thank you very much.

Upvotes: 3

Views: 587

Answers (1)

hiro protagonist
hiro protagonist

Reputation: 46849

there is probably no way to avoid that context.arc will draw an ellipse when your scaling is not symmetric. with your x_scale (x) function you only scale the center of the circle to be where it should be.

as a workaround i'd suggest to scale both directions by the same amount; sacrifice therefore that x_max and y_max will both be equal to 1.

i'd change in your code:

context.scale(HEIGHT, HEIGHT)
print('surface = 1 x {:1.2f}'.format(WIDTH/HEIGHT))

def draw_node(cx,cy,r, rgb):
  context.arc(cx, cy, r, 0, 2 * math.pi)
  context.set_source_rgb(rgb[0]/255.0,rgb[1]/255.0,rgb[2]/255.0)
  context.fill()
  context.stroke()

and not do any scalings (or scale by 1000 if that's what you prefer).

Upvotes: 1

Related Questions