Greg Ewing | 2 Oct 02:53 2011
Picon
Picon

Re: Native PyGame method for automatically scaling inputs to a surface resolution?

Christopher Night wrote:
> If I have a 100x100 pixel window, 
> and I want to put a dot at a position (x,x), it seems to me like the dot 
> should appear in the window if 0 <= x < 100. You're saying it should 
> appear in the window if -0.5 <= x < 99.5.

You need to be more precise about what you mean by "a dot". On
a display surface made of pixels, to make anything appear at all,
you need to paint at least one pixel. So I'll take it that you
want to paint a 1x1 rectangle.

There are also a couple of other things we need to be clear
about. One is the precise relationship between coordinates and
pixels. Two obvious choices come to mind: we could take the
coordinates as labelling the centres of pixels, or the boundaries
between pixels.

I prefer to take the boundary approach, because it avoids a lot
of potential confusion. To draw a 1x1 rect centred at (x, y), we
need to paint the area between (x-0.5, y-0.5) and (x+0.5, y+0.5).
In order to cover exactly one pixel, the centre coordinates need
to be an integer plus 0.5, so that the boundaries are integers.
So if x = 0.5, the rect covers the range 0.0 to 1.0.

Now, suppose our arithmetic is a little inaccurate, and we
actually get x = 0.499. The boundaries then come out as -0.001
and 0.999. If we round these, we get 0.0 and 1.0 as before.
But if we floor, we get -1.0 and -0.0, and the pixel goes
off the screen.

(Continue reading)

Greg Ewing | 2 Oct 03:12 2011
Picon
Picon

Re: Native PyGame method for automatically scaling inputs to a surface resolution?

Christopher Night wrote:

> If you're going to say that lines are 1-dimensional and thus infinitely 
> smaller than pixels, and thus we're obliged to draw a thin rectangle 
> whenever we want a line, then (a) I probably would not use the tool if 
> it doesn't even support drawing lines,

There's no reason line drawing shouldn't be supported.
A line of some specified width can easily be converted
automatically into a filled polygon, and there can be
a default for the width if it's not specified.

Postscript has a notion of a "hairline": if you set
the width to 0, it draws the narrowest line that the
device can produce, whatever scaling is in effect. For
a PyGame surface that would be 1 pixel.

--

-- 
Greg

sam.hacking | 2 Oct 10:50 2011

Functions in config files

Hi,
 
In my GUI toolkit, I have config files that the program can parse and turn into a complete menu screen. Now, if I have a button in my menu, and I want that button to run a function when it is clicked, then I need some way of naming a function from the config file.
 
At the moment I am just parsing the function name and running it through eval() so it is translated into a real function. For example, a button may have it's function set to "exit", which evaluates into Python's exit() function when parsed.
 
This has always felt a bit awkward to me, and now it seems that this method doesn't work when a project is compiled with PyInstaller. So, I was wondering if there was a well known solution to this problem?
 
The first thing I've thought of is accessing it through a dictionary. So, if I instance a Menu class, and then give it a dictionary that uses a string as a key, and the approriate function as a value. Then I can just index this dictionary with the string parsed from the config file, in order to return a function.
 
If anybody can provide any feedback on this, or any better methods for achieving this, it would be greatly appreciated.
 
Thanks,
Sam Bull
Greg Ewing | 2 Oct 23:41 2011
Picon
Picon

Re: Native PyGame method for automatically scaling inputs to a surface resolution?

Christopher Night wrote:

> Not that it's the most important thing in the world, but I think that 
> OpenGL agrees with me. Here's a program that creates a scaled surface 
> extending from (0,0) to (1000, 1000), with a canvas size of 100x100 
> pixels (so the scale factor is 0.1). It then draws the following 
> horizontal lines:
> 
> Red line at y = -4 (will appear if we're rounding but not if we're 
> truncating)
> Blue line at y = 6 (will appear)
> White line a y = 500 (will appear)
> Red line at y = 996 (will appear if we're truncating but not if we're 
> rounding)
> Blue line at y = 1004 (will not appear)
> 
> When I run the script, I see a blue line at top and a red line at 
> bottom, which is the correct behavior if we're truncating. But feel free 
> to tell me if there's something wrong with this experiment.

I think what's happening here is that OpenGL is treating the
coordinates as pixel boundaries, and treating the line as extending
half a pixel either side of the zero-width line between its
endpoints.

In post-transform coordinates, y = 0.0 is a borderline case --
exactly half of each pixel is in the window. For y = -0.4, less than
half is in the window, so no pixels get drawn. Similarly for
y = 100.4. For y = 99.6, most of each pixel is in the window, so
the line appears.

So the same principle applies here -- work out where the boundaries
of the filled area are, and round them to the nearest pixel
boundaries.

And again, the reason it seems like it's truncating is that it's
applying a half-pixel offset from the coordinates you provide to
find the edges of the line, and then rounding those. (At least
that's what's happening conceptually -- the actual arithmetic
it's performing might be different.)

--

-- 
Greg

Mac Ryan | 2 Oct 23:51 2011
Picon

Re: Native PyGame method for automatically scaling inputs to a surface resolution?

On Sun, 02 Oct 2011 14:12:21 +1300
Greg Ewing <greg.ewing@...> wrote:

> > If you're going to say that lines are 1-dimensional and thus
> > infinitely smaller than pixels, and thus we're obliged to draw a
> > thin rectangle whenever we want a line, then (a) I probably would
> > not use the tool if it doesn't even support drawing lines,  
> 
> There's no reason line drawing shouldn't be supported.
> A line of some specified width can easily be converted
> automatically into a filled polygon, and there can be
> a default for the width if it's not specified.

Which is indeed another way to say their thickness would be
automatically set to 1/scale... or did I get you wrong?

/mac

Chris Pezley | 3 Oct 00:04 2011
Picon

Segfault using surface.fill()

I did a little google-fu and found an old entry which describes my
problem, but nobody answered:
http://www.mail-archive.com/pygame-users-eePT7DaMpNY@public.gmane.org/msg09485.html

What I'm trying to do is basically the following:

#taken from the Mouse class
       self.posx, self.posy = mouse.get_pos()
       self.posx = int(self.posx/16)
       self.posy = int(self.posy/16)
       self.pos = self.posx*16, self.posy*16
       self.rect = self.pos, (16,16)

#this is the part from the program
       windowinfo = pygame.display.Info()
       size = width, height = windowinfo.current_w/2,
windowinfo.current_h/2
       screen = pygame.display.set_mode(size)
       screen.fill([20,20,20], Mouse.rect, BLEND_RGB_ADD)

The only time the segfault happens is when I move the cursor to the
bottom of the window. The left, top and right sides do not cause this
problem.

Any insight?

Thanks,
Chris

Mac Ryan | 3 Oct 00:09 2011
Picon

Re: Native PyGame method for automatically scaling inputs to a surface resolution?

On Sun, 02 Oct 2011 13:53:02 +1300
Greg Ewing <greg.ewing@...> wrote:

> Now, suppose our arithmetic is a little inaccurate, and we
> actually get x = 0.499. The boundaries then come out as -0.001
> and 0.999. If we round these, we get 0.0 and 1.0 as before.
> But if we floor, we get -1.0 and -0.0, and the pixel goes
> off the screen.
> ...
> This may be the reason we're misunderstanding each other --
> you're thinking of (0, 0) as being the *centre* of the top
> left pixel in the window, whereas I'm thinking of it as the
> *top left corner* of that pixel.

Although I was not the recipient of the original answer: Very
interesting! that's actually the first time I understand why using
the upper-left coordinate system may make sense under certain
conditions. :)

Yet, while I followed the math through, I am unsure about how bad small
inaccuracies might turn out. Those inaccuracies would essentially be
the fruit of scaling down a very large physical model to screen
resolution, so I truly wouldn't care if I would expected my
sprite to be 1px to the left or what it appears, as far as the
model performs accurately. For game interface elements (where visual
alignment might be more relevant) I probably wouldn't use scaled
surfaces anyway.

But again... interesting to debate. Could be another parameter for the
surface (coord_system=PIXEL_CENTRE | PIXEL_BOUNDARIES)!! :P

/mac

Lenard Lindstrom | 3 Oct 00:58 2011
Picon

Re: Segfault using surface.fill()

Hi,
 
This may have been fixed in Pygame 1.9.2 (commit 902b98865c6c). I will check.
 
Lenard Lindstrom
 
On Oct 2, 2011, Chris Pezley <chrispezley <at> gmail.com> wrote:
Greg Ewing | 3 Oct 06:52 2011
Picon
Picon

Re: Native PyGame method for automatically scaling inputs to a surface resolution?

Mac Ryan wrote:

> Those inaccuracies would essentially be
> the fruit of scaling down a very large physical model to screen
> resolution, so I truly wouldn't care if I would expected my
> sprite to be 1px to the left or what it appears, as far as the
> model performs accurately.

Possibly you wouldn't care. However, if any transformation
feature were to be added, the theory behind it ought to be
properly thought out, I believe.

 > Could be another parameter for the
> surface (coord_system=PIXEL_CENTRE | PIXEL_BOUNDARIES)!! :P

I don't think that would be strictly necessary, because you
would be able to get the same effect by adjusting the translation
by 0.5 pixels.

Also, providing too many options could just lead to confusion.
Surfaces already have a bewildering collection of options --
let's not add any more if we don't have to!

--

-- 
Greg

Mac Ryan | 3 Oct 12:00 2011
Picon

Re: Native PyGame method for automatically scaling inputs to a surface resolution?

On Mon, 03 Oct 2011 17:52:13 +1300
Greg Ewing <greg.ewing@...> wrote:

> > Could be another parameter for the
> > surface (coord_system=PIXEL_CENTRE | PIXEL_BOUNDARIES)!! :P  
> 
> I don't think that would be strictly necessary, because you
> would be able to get the same effect by adjusting the translation
> by 0.5 pixels.
> 
> Also, providing too many options could just lead to confusion.
> Surfaces already have a bewildering collection of options --
> let's not add any more if we don't have to!

Ah, the ambiguities of written langauge! ;) The ":P" was meant to
indicate it was a joke! :)

Anyhow I agree with you that the theory should be well thought out.

So far this is a summary of how I would try to implement the feature:

1. Scaling option... optional. Defaults to 1 and in that case the
   scaling procedure is bypassed at once instantiating a class that
   doesn't have it.
2. Scaling only happens one-way, returned rectangles are in pixels (so
   no floating point coords).
3. Pixels and hairlines are supported without having to specify their
   size by defaulting the unspecified size to 1/scale.

I'm still undecided on whether the positioning should use pixel
boundaries or pixel centres: I think there are good reasons to go for
both. Namely I think "centres" is a more appropriate way to describe
position of objects in a modelled space (nobody says "the car is in the
far end left corner of the garage", as intuitively we consider the
geometrical centre of objects as their most significative one for
positional reference). OTOH, boundaries are way more consistent with
how PyGame operates on standard surfaces.

Again: it might well be that when I will have a crack at it it will
prove beyond my capacities, but before even try to start working on it
(which I shall repeat won't be immediately), I would like to know I'm
moving towards a sensible direction...

/mac


Gmane