Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411720 Posts in 69402 Topics- by 58450 Members - Latest Member: FezzikTheGiant

May 21, 2024, 11:14:03 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Drawing line with thickness without anti-aliasing
Pages: [1] 2
Print
Author Topic: Drawing line with thickness without anti-aliasing  (Read 9215 times)
Draknek
Level 6
*


"Alan Hazelden" for short


View Profile WWW
« on: June 20, 2010, 04:18:17 AM »

As the title says, I want to render a line with a given thickness, without anti-aliasing.

Some variant of Bresenham's seems like it should do the trick, but I have yet to find/think of one that seems particularly efficient (although efficiency isn't massively important for this application).

The only reference I've found so far is this StackOverflow question.

Has anyone done this/got any other references?

This is for AS3, so the first attempt I went with was to use the vector graphics line-drawing API. Unfortunately that has anti-aliasing, so isn't what I want. I read that you can disable anti-aliasing by setting stage.quality to low, but that just seems to give generally poor results (and is application-wide). Is there any other simple solution for AS3?
Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #1 on: June 20, 2010, 04:42:24 AM »

You could recompute bitmaps for many angles, and paste them together. Or you could draw aliased lines, and then use threshold to convert back to pure black and white.
Logged
raigan
Level 5
*****


View Profile
« Reply #2 on: June 20, 2010, 04:45:01 AM »

that just seems to give generally poor results

Could you describe "poor"? With quality=LOW, the results should be correct: an aliased thick line. If it looks like crap, that's because of the aliasing! Smiley
Logged
Draknek
Level 6
*


"Alan Hazelden" for short


View Profile WWW
« Reply #3 on: June 20, 2010, 05:28:58 AM »

Could you describe "poor"? With quality=LOW, the results should be correct: an aliased thick line. If it looks like crap, that's because of the aliasing! Smiley
Lines don't join up, circles aren't circular.

Examples:
quality = default (anti-aliasing on)
quality = low (anti-aliasing off)
Logged

increpare
Guest
« Reply #4 on: June 20, 2010, 05:31:15 AM »

neat!

(also, I wouldn't personally worry too much about these sorts of fidelity issues in a program like this).
Logged
BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #5 on: June 20, 2010, 06:39:51 AM »

Yeah, I cannot see a big difference both look ok. The flashing circle looks off center, but that is probably because you are a half-pixel out or something.
Logged
st33d
Guest
« Reply #6 on: June 20, 2010, 09:16:23 AM »

I posted a class that basically does Bresenham in AS3 here:

http://forums.tigsource.com/index.php?topic=10505.0

But of course it doesn't do thick lines.

The drawing API isn't accurate regardless of the stage quality (it wasn't accurate on diagonals when I tested it). You have to be comfortable with losing a pixel either way because it tries to draw the stroke inbetween pixel locations. Consider this when choosing your stroke width.
Logged
nikki
Level 10
*****


View Profile
« Reply #7 on: June 20, 2010, 10:26:55 AM »

when you implement a simple bresenham algorithm , how does that compute anti-alias by itself ?
It ought to be aliased until you implement the anti yourself...

or am i missing something here?
Logged
kiwi
Level 0
***


View Profile WWW
« Reply #8 on: June 20, 2010, 10:34:56 AM »

when you implement a simple bresenham algorithm , how does that compute anti-alias by itself ?
It ought to be aliased until you implement the anti yourself...

or am i missing something here?

Someone correct me if I'm wrong, but after reading the wikipedia article, I think that Bresenhams' algorithm is just a rasterization algorithm, it's not supposed to anti-alias
Logged

Draknek
Level 6
*


"Alan Hazelden" for short


View Profile WWW
« Reply #9 on: June 20, 2010, 12:02:23 PM »

(also, I wouldn't personally worry too much about these sorts of fidelity issues in a program like this).
Yeah, I would just stick with anti-aliasing if I didn't want to add a flood fill tool next. The main thing wrong with the quality=low option is that some lines with small brush sizes go shaky and look ugly. But probably you're right that it's not amazingly important.

when you implement a simple bresenham algorithm , how does that compute anti-alias by itself ?
It ought to be aliased until you implement the anti yourself...

or am i missing something here?
The problem is that I can't just use Bresenham's algorithm because that gives one-pixel wide lines and I need my lines to have thickness.
Logged

agj
Level 10
*****



View Profile WWW
« Reply #10 on: June 20, 2010, 12:49:42 PM »


Haha, I'm loving this idea.
Logged

nikki
Level 10
*****


View Profile
« Reply #11 on: June 20, 2010, 01:18:46 PM »

Quote
The problem is that I can't just use Bresenham's algorithm because that gives one-pixel wide lines and I need my lines to have thickness.

ahh yes, the thickness.
i had a similar thing a while ago, i just plotted bresenham lines, and made an extra line or two around it to thicken it, the problem then is that the thickness appears different when the line is at different angles because you sometimes plot the lines over each other, the trick then is to make the startingpoint of the second  (or more) line rotate , depending on the angle the first line is in.

am i clear ? 

btw, how thick are we talking about?, and how long? by average max and min ??

oh and btw, this thing i made wasn't in as3 so it might not even be possible, but then again i'm sure you can plot pixels ? right

Logged
Glaiel-Gamer
Guest
« Reply #12 on: June 20, 2010, 03:15:32 PM »

first plot a line perpendicular to the line you want, at the desired thickness, store the result as an array of offsets

like
perps:

[(-2, -1), (-1, -1), (0, 0), (1, 1), (2, 1)]

now when you plot the bresenham line, every time you set a pixel, set all the offsets too

i.e. if you're gonna plot (34, 121), with the same offsets as above, you'd plot

(34, 121) + (-2, -1)
(34, 121) + (-1, -1)
(34, 121) + (0, 0)
(34, 121) + (1, 1)
(34, 121) + (2, 1)
Logged
Glaiel-Gamer
Guest
« Reply #13 on: June 20, 2010, 03:17:22 PM »

although, I might add, your problem has to do with joins and not the lines themselves, and rolling your own would give exactly the same problem, probably worse, than flash in low quality
Logged
LemonScented
Level 7
**



View Profile
« Reply #14 on: June 20, 2010, 05:04:26 PM »

I'm probably missing the point completely, but for lines with thickness, isn't it more useful to just think of them as rectangles? So it'd go something like:

1 - Define the line you want with the two endpoints, X and Y. Work out the length, L from the distance between them, and the angle A from one to the other.

2 - Work out an angle that's perpendicular to A. Draw lines at that perpendicular angle (using whichever line drawing algorithm you happen to like) such that the centre points of those lines run through X and Y, respectively.

3 - Connect the endpoints of the lines you drew in step 2, so you have a rectangle.

4 - Flood fill the rectangle (you're about to implement that anyway, yes?)

Is that at all helpful, or have I completely misunderstood you?
Logged

Glaiel-Gamer
Guest
« Reply #15 on: June 20, 2010, 06:23:45 PM »

for flood fill, flash has that built in

http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/display/BitmapData.html#floodFill()
and you should definitely use that instead of rolling your own, bitmapdata is implemented in flash player, not actionscript so it is way faster than doing it yourself
Logged
Draknek
Level 6
*


"Alan Hazelden" for short


View Profile WWW
« Reply #16 on: June 21, 2010, 02:26:21 AM »

although, I might add, your problem has to do with joins and not the lines themselves, and rolling your own would give exactly the same problem, probably worse, than flash in low quality
I thought that at first, but the start/endpoints of the lines I'm telling Flash to draw are the same so there really shouldn't be any visible joins. With the 1-pixel brush I've confirmed that Flash's drawing in low quality mode is worse than Bresenham's algorithm.

I'm probably missing the point completely, but for lines with thickness, isn't it more useful to just think of them as rectangles?
You're right that I could use flood fill to do that but only if the line is wide enough so that the middle section is connected. Something like this would cause problems:
Pixel 30Pixel 0FPixel 0FPixel 30Pixel 30Pixel 30Pixel 30Pixel 30
Pixel 0FPixel 30Pixel 30Pixel 0FPixel 0FPixel 30Pixel 30Pixel 30
Pixel 30Pixel 0FPixel 0FPixel 30Pixel 30Pixel 0FPixel 0FPixel 30
Pixel 30Pixel 30Pixel 30Pixel 0FPixel 0FPixel 30Pixel 30Pixel 0F
Pixel 30Pixel 30Pixel 30Pixel 30Pixel 30Pixel 0FPixel 0FPixel 30

for flood fill, flash has that built in
Yeah, that's really the only reason I decided to add that feature, because I knew I could get it for free.
Logged

muku
Level 10
*****


View Profile
« Reply #17 on: June 21, 2010, 03:08:26 AM »

Is there anything in particular wrong with this algorithm which was already linked from Stack Overflow? It seems to do exactly what you want. I found that one too when I was searching for this kind of stuff a while back.
Logged
Pishtaco
Level 10
*****


View Profile WWW
« Reply #18 on: June 21, 2010, 04:24:04 AM »

Could you draw the anti-aliased line on a temporary bitmap, and then use the "threshold" function to clean up the edges?
Logged

Draknek
Level 6
*


"Alan Hazelden" for short


View Profile WWW
« Reply #19 on: June 21, 2010, 08:46:26 AM »

In the end I went with rendering a circle at every step of Bresenham's algorithm. Seemed like the fastest solution to implement, and I decided that I didn't really care about efficiency after all.

Hoping to release this properly in a few hours.

Is there anything in particular wrong with this algorithm which was already linked from Stack Overflow? It seems to do exactly what you want. I found that one too when I was searching for this kind of stuff a while back.
It was partially because I didn't want to read through 9 pages of low-quality scans and partially because I wasn't convinced that you need two nested loops to do it. Glaiel Gamer's suggestion of pre-caching the perpendicular offsets seems a sensible modification to get rid of one of them though (although obviously you can't do that with changing thickness which the linked algorithm can handle).

Could you draw the anti-aliased line on a temporary bitmap, and then use the "threshold" function to clean up the edges?
Probably. I'd be a bit wary of using that on a 1-pixel thick line, but anything much larger than that should be fine and 1-pixel thick lines could be special-cased to use Bresenham's algorithm.
Logged

Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic