OO dilemma

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Prelates, Moderators General

OO dilemma

Postby Dingbats » Wed May 30, 2007 12:11 pm UTC

I'm relatively new to object-oriented programming, but I get the general concepts, and now I've stumbled upon a problem that I would guess is quite common.

I'm making a terminal image editor in Python. It doesn't have support for 'real' image formats, but instead I'm having each cell in the window represent one 'pixel', and each pixel can have a background color, a foreground color and a character that's displayed in it. So the images don't look like normal images, but kind of weird. And also, the x/y positions of the pixels aren't constant, they can be moved around, but still identified with their unique ID numbers (I need it to be this way because of another feature in the program that doesn't matter now anyway).

Anyway, the two classes that matter most are the Pixel class and the Canvas class. The Canvas contains a list with all the Pixel instances in it, and knows its own width and height (which can be changed).

Now to the problem. I need a method in the Pixel class to change the coordinates of the pixel. And in that method I want to check whether the given coordinates are within the bounds of the canvas or not, so I don't try to move a pixel outside the canvas and cause an error. But to do that, the Pixel class would have to know the width and height attributes of the Canvas class. The Canvas, in its turn, knows everything about the Pixel class. And that seems like bad design to me, that kind of circular reference (invented term). Should I do anything about it? Re-structure the whole thing?
User avatar
Dingbats
 
Posts: 921
Joined: Tue Mar 20, 2007 12:46 pm UTC
Location: Sweden

Postby evilbeanfiend » Wed May 30, 2007 12:55 pm UTC

im confused about why pixels can move, but anyway:

option 1) only allow pixels to be moved via the canvas, pixel is just told were it belongs canvas does the checking

option2) include a callback from the pixel to the canvas to allow checking (this is the circular one you referred to)

option 3) don't have a pixel class ... (im not sure i understand the problem so i dont really see why you need an object per pixel, pixels would appear to me to just be data)
in ur beanz makin u eveel
User avatar
evilbeanfiend
 
Posts: 2650
Joined: Tue Mar 13, 2007 7:05 am UTC
Location: the old world

Postby djn » Wed May 30, 2007 1:01 pm UTC

evilbeanfiend wrote:im confused about why pixels can move, but anyway:

option 1) only allow pixels to be moved via the canvas, pixel is just told were it belongs canvas does the checking


Going with this, it might be better (from a memory use perspective, if nothing else) to not store the position in the pixels at all, but instead having a two-dimensional array of pixels in the canvas (where the indexes in the array are the position). You'd need to move some code to the canvas, but that does sort of make sense. Of course, this requires that no two pixels on the same canvas ever have the same position. I'm not sure what you're doing, but it doesn't sound like that should be a problem.
User avatar
djn
 
Posts: 604
Joined: Mon May 07, 2007 1:33 pm UTC
Location: Horten, Norway

Postby evilbeanfiend » Wed May 30, 2007 1:06 pm UTC

djn wrote:
evilbeanfiend wrote:im confused about why pixels can move, but anyway:

option 1) only allow pixels to be moved via the canvas, pixel is just told were it belongs canvas does the checking


Going with this, it might be better (from a memory use perspective, if nothing else) to not store the position in the pixels at all, but instead having a two-dimensional array of pixels in the canvas (where the indexes in the array are the position). You'd need to move some code to the canvas, but that does sort of make sense. Of course, this requires that no two pixels on the same canvas ever have the same position. I'm not sure what you're doing, but it doesn't sound like that should be a problem.


yes that was my 3rd option, just have an array of data, not everything is an object.
in ur beanz makin u eveel
User avatar
evilbeanfiend
 
Posts: 2650
Joined: Tue Mar 13, 2007 7:05 am UTC
Location: the old world

Postby Dingbats » Wed May 30, 2007 1:12 pm UTC

evilbeanfiend wrote:
Going with this, it might be better (from a memory use perspective, if nothing else) to not store the position in the pixels at all, but instead having a two-dimensional array of pixels in the canvas (where the indexes in the array are the position). You'd need to move some code to the canvas, but that does sort of make sense. Of course, this requires that no two pixels on the same canvas ever have the same position. I'm not sure what you're doing, but it doesn't sound like that should be a problem.


yes that was my 3rd option, just have an array of data, not everything is an object.

Well, actually, that makes some sense. But I think it's still handy to have the pixels be objects, just that they don't know their positions, because I need somewhere to store the colors and the characters. If the pixels are objects, I can use pixels[x][y].color instead of pixels[x][y][3 (or whatever)] to refer to the color.

But I'll try to do it that way.

Thanks :)
User avatar
Dingbats
 
Posts: 921
Joined: Tue Mar 20, 2007 12:46 pm UTC
Location: Sweden

Postby evilbeanfiend » Wed May 30, 2007 1:24 pm UTC

how much data does each pixel have though - if its just the colour then pixels can be an int[][], if you are storing rgb seperately or colour and something else (what it would be i don't know) then yes make a an object (possibly a rbgcolour class rather than pixel?)
in ur beanz makin u eveel
User avatar
evilbeanfiend
 
Posts: 2650
Joined: Tue Mar 13, 2007 7:05 am UTC
Location: the old world

Postby Dingbats » Wed May 30, 2007 1:35 pm UTC

evilbeanfiend wrote:how much data does each pixel have though - if its just the colour then pixels can be an int[][], if you are storing rgb seperately or colour and something else (what it would be i don't know) then yes make a an object (possibly a rbgcolour class rather than pixel?)

Each pixel has:
-- An ID number, so the selections still recognize pixels after they've been moved.
-- A background color, there are only eight colors available.
-- A foreground color, same as above.
-- A character that's displayed in the foreground color.
-- A bool indicating whether the pixel should be visible or not, so you can just toggle them on and off without having to delete them entirely.

I think that's enough to make it necessary or at least easier to have a pixel class than not... I think, but I'm not that experienced in this stuff.
User avatar
Dingbats
 
Posts: 921
Joined: Tue Mar 20, 2007 12:46 pm UTC
Location: Sweden

Postby djn » Wed May 30, 2007 1:39 pm UTC

If you're working on cells (textmode-style) containing bgcolor/fgcolor/character, making them objects would sort of make sense. Partly because they contain enough different things that it'd make them simpler to work with, and partly because there would be much fewer of them.

The original approach was, IIRC, to have something like an array of 16-bit ints, using the first byte as the character and the second byte for formatting info. Don't quote me on that, though.

edit: Almost.
Wikipedia wrote:In color text mode, each screen character is actually represented by two bytes. The lower, or character byte is the actual character for the current character set, and the higher, or attribute byte is a bit field used to select various video attributes such as color, blinking, character set, and so forth. This byte-pair scheme is among the features that VGA inherited ultimately from CGA.


Some other variations uses two arrays: One for text, and one for formatting.
Last edited by djn on Wed May 30, 2007 1:42 pm UTC, edited 1 time in total.
User avatar
djn
 
Posts: 604
Joined: Mon May 07, 2007 1:33 pm UTC
Location: Horten, Norway

Postby evilbeanfiend » Wed May 30, 2007 1:40 pm UTC

ok i still don't get what moving a pixel actually means but your pixels aren't pixels in anyway i understand (foreground + background colour per pixel?) hence yes go for an area of pixels that dont know their location but do know the other attributes (assuming you need them). you seem to be part way between a bitmap graphics and vector graphics, are you sure you don't want one or the other?
in ur beanz makin u eveel
User avatar
evilbeanfiend
 
Posts: 2650
Joined: Tue Mar 13, 2007 7:05 am UTC
Location: the old world

Postby djn » Wed May 30, 2007 1:43 pm UTC

I think it would be clarifying if you renamed them "Cells" instead of "Pixels", since that's essentially what they are.

As for what approach is easier, that does of course depend on the language. In python, go for objects. It's not the fastest thing ever, but it'll do.
Last edited by djn on Wed May 30, 2007 1:50 pm UTC, edited 1 time in total.
User avatar
djn
 
Posts: 604
Joined: Mon May 07, 2007 1:33 pm UTC
Location: Horten, Norway

Postby Dingbats » Wed May 30, 2007 1:46 pm UTC

evilbeanfiend wrote:ok i still don't get what moving a pixel actually means

Uhm... well. When you select a number of pixels (like highlighting in MS Paint, for example), and then move the selection around, it's easier to change the position of the selected pixels than to have the positions static and change what pixels are selected and their colors. I don't know how to explain it so it makes sense, but it does makee sense in my head at least.

evilbeanfiend wrote:you seem to be part way between a bitmap graphics and vector graphics, are you sure you don't want one or the other?

Well, it is a bitmap editor, I think I just confused you with the pixel movement and all. :)

EDIT:
djn wrote:I think it would be clarifying if you renamed them "Cells" instead of "Pixels", since that's essentially what they are.

Yeah, thanks. I should have called them that so there wouldn't be so much confusion. :)
User avatar
Dingbats
 
Posts: 921
Joined: Tue Mar 20, 2007 12:46 pm UTC
Location: Sweden

Postby djn » Wed May 30, 2007 1:51 pm UTC

If the smallest unit you can change is the size of a character, it's not really a bitmap editor, though; It's more like an ANSI-art-editor. :)

Of course, you can fake by using a character set where the upper 128 represent different combinations of blocks, letting you draw with sub-character precision.
Something like the ZX Spectrum had, or even better the ABC80. Sadly, I can't find any documentation on the ABC80 character set online.

edit: Hah.
Basically, it only used the lower 127 characters for text. Printing a special character (151, I think) turned on graphics mode for the rest of that line or until the stop-graphics char (135?) : The characters were replaced with the given blocks. Note that capital letters are the same, probably for the convenience.

Yeah, I have one of these. :)
(Got it from my grandfather when they retired them from where he worked; I was 9 at the time and it was 1992.)
Last edited by djn on Wed May 30, 2007 2:08 pm UTC, edited 1 time in total.
User avatar
djn
 
Posts: 604
Joined: Mon May 07, 2007 1:33 pm UTC
Location: Horten, Norway

Postby evilbeanfiend » Wed May 30, 2007 2:02 pm UTC

Dingbats wrote:
evilbeanfiend wrote:ok i still don't get what moving a pixel actually means

Uhm... well. When you select a number of pixels (like highlighting in MS Paint, for example), and then move the selection around, it's easier to change the position of the selected pixels than to have the positions static and change what pixels are selected and their colors. I don't know how to explain it so it makes sense, but it does makee sense in my head at least.


most bitmap editors would do it the way you do want to i think.

evilbeanfiend wrote:you seem to be part way between a bitmap graphics and vector graphics, are you sure you don't want one or the other?

Well, it is a bitmap editor, I think I just confused you with the pixel movement and all. :)


yes but it sounds like you are representing each pixel in the bitmap as a tiny vector rectangle i.e. i think you are conflating two ideas and not gaining anything from it.
in ur beanz makin u eveel
User avatar
evilbeanfiend
 
Posts: 2650
Joined: Tue Mar 13, 2007 7:05 am UTC
Location: the old world

Postby djn » Wed May 30, 2007 2:11 pm UTC

It's better to have redrawing be a loop through positions and not through cells/pixels, though, so you do want to move things around in memory when, well, moving them.

evilbeanfiend wrote:yes but it sounds like you are representing each pixel in the bitmap as a tiny vector rectangle i.e. i think you are conflating two ideas and not gaining anything from it.


Depends. Since each cell holds a character, think of VGA text modes or ANSI terminals, not bitmaps.
User avatar
djn
 
Posts: 604
Joined: Mon May 07, 2007 1:33 pm UTC
Location: Horten, Norway

Postby evilbeanfiend » Wed May 30, 2007 2:19 pm UTC

aaa so its really a teletext editor?

edit: anyway i think u resolved your original dilemma and ive just been slow to pick up on the character part of what you wrote. case closed?
in ur beanz makin u eveel
User avatar
evilbeanfiend
 
Posts: 2650
Joined: Tue Mar 13, 2007 7:05 am UTC
Location: the old world

Postby Dingbats » Wed May 30, 2007 2:35 pm UTC

djn wrote:Depends. Since each cell holds a character, think of VGA text modes or ANSI terminals, not bitmaps.

Exactly. I made a way more primitve version of this in C a few years ago, and it looked like this:

Image

The red cells in that picture would have red as their foreground color, black as their background color and a smiley face as their character, if I had done it in the way I'm doing it now.

EDIT:
evilbeanfiend wrote:edit: anyway i think u resolved your original dilemma and ive just been slow to pick up on the character part of what you wrote. case closed?

I would say so :)
User avatar
Dingbats
 
Posts: 921
Joined: Tue Mar 20, 2007 12:46 pm UTC
Location: Sweden

Postby evilbeanfiend » Wed May 30, 2007 3:03 pm UTC

yes that looks pretty much like teletext.

iirc teletext was just an array of strings so each char was either the character to print XOR a non printable char that changed the background or foreground colour (run-length encoded). that meant you couldnt have 'rainbow' text without it being double spaced. so yours should be more versatile than teletext.
in ur beanz makin u eveel
User avatar
evilbeanfiend
 
Posts: 2650
Joined: Tue Mar 13, 2007 7:05 am UTC
Location: the old world

Postby pete » Wed May 30, 2007 4:27 pm UTC

The array idea would still work by the way. Text is normally stored in video memory as 2 bytes per cell/character, starting at b800:0000 (8 bits character, 4 bits background colour, 4 bits foreground). I did something similar in DOS a while back, and copied memory blocks to get non-destructive dragging.

Not trying to change your mind or anything, just mentioning it.
User avatar
pete
 
Posts: 126
Joined: Thu Apr 19, 2007 2:32 pm UTC

Postby Dingbats » Wed May 30, 2007 5:11 pm UTC

pete wrote:The array idea would still work by the way. Text is normally stored in video memory as 2 bytes per cell/character, starting at b800:0000 (8 bits character, 4 bits background colour, 4 bits foreground). I did something similar in DOS a while back, and copied memory blocks to get non-destructive dragging.

Is that as portable as using an external library though? Not that it matters in this case, because I only do this for learning, but still.
User avatar
Dingbats
 
Posts: 921
Joined: Tue Mar 20, 2007 12:46 pm UTC
Location: Sweden

Postby djn » Wed May 30, 2007 5:18 pm UTC

Dingbats wrote:
pete wrote:The array idea would still work by the way. Text is normally stored in video memory as 2 bytes per cell/character, starting at b800:0000 (8 bits character, 4 bits background colour, 4 bits foreground). I did something similar in DOS a while back, and copied memory blocks to get non-destructive dragging.

Is that as portable as using an external library though? Not that it matters in this case, because I only do this for learning, but still.


No, it's not.
What you can try, which is somewhere in the middle, is to store the values and formatting in two numpy-arrays, and copy the relevant slices around. That should be fairly fast.
Of course, a NumPy-array only stores ints or floats, so you'll have to encode it somehow.
User avatar
djn
 
Posts: 604
Joined: Mon May 07, 2007 1:33 pm UTC
Location: Horten, Norway

Postby pete » Wed May 30, 2007 5:36 pm UTC

djn wrote:No, it's not.


Agreed. I didn't mean you should do what I did, I meant you should be able to accomplish the same idea with arrays.

Edit: forgot plurals.
User avatar
pete
 
Posts: 126
Joined: Thu Apr 19, 2007 2:32 pm UTC


Return to Coding

Who is online

Users browsing this forum: No registered users and 2 guests