|
-
Apr 2nd, 2001, 10:59 AM
#1
Thread Starter
New Member
Can anyone show me an example of how you might draw a circle, using something like the Circle Method, but while using BitBlt? Mind you, I'm not talking about Blitting a bitmap of a circle; I need to draw the circle from scratch, changing its radius, height, width, and center based on other criteria, which changes from moment to moment.
Suggestions? better yet, examples!!!
-
Apr 2nd, 2001, 11:37 AM
#2
You can't. BitBlt moves IMAGE bits from one DC to another. If you dont have a picture, you can Blit it.
Z.
-
Apr 2nd, 2001, 11:41 AM
#3
Thread Starter
New Member
"If I don't have a picture, I can blt it"...do you mean I CAN'T Blt it?
-
Apr 2nd, 2001, 11:46 AM
#4
BitBlt requires image data in the source that it can move to a destination. You can't Blit arbitrary radius, location data. For example:
I have a picture of a frog, and i want to put that frog picture on top of a pond picture. Sure, I can Blit that. But, if i dont have a frog picture, but you want to draw a circle onto the pond, you require an image of that circle before you can Blit it. Otherwise, BitBlt has nothing to put on top of the pond.
BitBlt moves images, in various ways, depending on how you tell it to draw. Nothing more.
Z.
-
Apr 2nd, 2001, 11:51 AM
#5
Thread Starter
New Member
Thanks for the clarification!
Hehe, now, how would you handle this if you had to do it? Different circles to be drawn on a form, can't use a "set" bitmap...using the Circle method on the form itself causes waaaay too much screen flickering, so I was hoping to use "something" like BitBlt to get around the flickering issue.
-
Apr 2nd, 2001, 12:00 PM
#6
Frenzied Member
BitBlt is a Windows GDI function. If that's fast enough for you then there is a Windows GDI function for drawing a circle to a DC too. Well actually, not just circles but ellipses in general. Take a look.
Bear in mind that it will draw it using the currently selected-in pen and brush for the DC. You can make it do different colours of outline and fill by selecting in different pens and brushes.
Harry.
"From one thing, know ten thousand things."
-
Apr 2nd, 2001, 12:06 PM
#7
Thread Starter
New Member
Thanks again...any suggestions for drawing an Arc, rather than a full circle?
-
Apr 2nd, 2001, 01:18 PM
#8
transcendental analytic
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Apr 2nd, 2001, 05:52 PM
#9
Frenzied Member
Here's a function to draw a circle using only a bit of math and the SetPixel API (similar to VB's PSet):
(It wasn't copied from the Net - nice what you can do with your dad's books when you're really desperate for a function, heh? )
Code:
Private Sub DrawACircle(OrigX As Long, OrigY As Long, R As Long, hDc As Long, Color As Long)
Dim X As Long 'X Counter
Dim Y As Long 'Y Counter
'OrigX - X coordinates of the center
'OrigY - Y coordinates of the center
'R - The circle's radius
'Loop trough all the pixels of the circle...
For X = OrigX - R To OrigX + R
For Y = OrigY - R To OrigY + R
'Check if it's inside the circle...
If ((X - OrigX) * (X - OrigX)) + ((Y - OrigY) * (Y - OrigY)) <= (R * R) Then
SetPixel hDc, X, Y, Color
End If
Next Y
Next X
End Sub
Hope it helps you! If you need only the border or only the outside, it's possible too - just tell me
-
Apr 2nd, 2001, 07:56 PM
#10
Good Ol' Platypus
For plotting the X, Y coordinates of a circle:
Code:
X = Int(CenterX + Cos(Degrees) * Radius)
Y = Int(CenterY + Sin(Degrees) * Radius)
Degrees is a value between 0 and 359. Radius is a pixel radius value. CenterX and CenterY are pixel center points in the X and Y axes for the circle. X and Y are the positions of the circle.
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation. 
(Just a heads-up)
-
Apr 3rd, 2001, 07:40 AM
#11
Frenzied Member
That's all very well but unless he's getting direct access to the video memory through something like DirectX, it's going to be slower plotting the pixels himself than it would be to use the Ellipse or Arc function. It's already flickering, he needs it as fast as possible.
Windows GDI may be slow (compared to APIs like DirectX and OpenGL) but it's a lot better than doing your own home-grown versions using VB's maths and the trig functions..... eww
Harry.
"From one thing, know ten thousand things."
-
Apr 3rd, 2001, 08:50 AM
#12
transcendental analytic
yeah eww
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Apr 3rd, 2001, 03:16 PM
#13
Sas, That code you posted wont work. Sin and Cos work in Radians.
-
Apr 3rd, 2001, 03:42 PM
#14
Good Ol' Platypus
Very strange, because it worked for me. And it posted a full circle, with 360 points. Probably another example of VB's whacked math. (to convert to radians, divide the number by 114.64, (I think) that this will work)
All contents of the above post that aren't somebody elses are mine, not the property of some media corporation. 
(Just a heads-up)
-
Apr 4th, 2001, 06:48 AM
#15
transcendental analytic
nope multiply with 1.74532925E-02 (somehow i got to remember that one)
you must have a weird version of vb then sas, what does this give you
?sin(3.14159265358979)
should be:
3.23108510433268E-15
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Apr 4th, 2001, 12:07 PM
#16
transcendental analytic
If you really want to do fast graphics processing algoritms, you should use DMA and preferably in C++, to fill a circle you could trap the edge's 1/8'th of the circle with a staircase algoritm and then loop from middle to edge in the 8 symetric directions and then fill the middle square
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Apr 4th, 2001, 06:11 PM
#17
Frenzied Member
I feel like I know everything too when I talk like that 
Could you please explain that... in more detail?
-
Apr 4th, 2001, 07:43 PM
#18
Frenzied Member
I'm not sure but I think Kedaman is saying that you can conceptually split the circle up into 8 45 degree (or pi/4 radians) sectors, and use the symmetry of the circle to speed up the calculations. Think of it this way - once you've drawn a semicircle, to draw the rest you just copy a mirror image. Well you can extend that to more axes.
I believe there are extensions of the Bresenham algorithm to draw circles, which is what I would use if I wanted to do fancy effects. I'd do it in C++ with DirectX or OpenGL too. SetPixel kind of sucks if you're going to use it a lot. Each call to SetPixel has to lock the video memory, find the correct location in memory depending on the colour depth of the current display mode, get the old colour, set the new colour, unlock the video memory and return a colour value. Not exactly ideal for performance. I guess the compiler could optimise it a lot, but I'm not sure if it would.
Anyway that code does a solid fill, not an outline.
Harry.
"From one thing, know ten thousand things."
-
Apr 5th, 2001, 05:16 AM
#19
transcendental analytic
Outline and solid fill. both would be quite optimal (i think)
imagine a square inside the circle, you can calculate the corner offset using one Squareroot, now you have 4 secants, which can be further splitted up into 8, all kaidoscopically symetric (heh just poped up in my head)
now the cords of these are 45'degree of the circle as Harry said Not much aritmetics to do now.
Code:
|\
| \
|y \ <- this is curved
| |
_x_|
for filled circles, you just need to store the edge distance to the middle, for each pixel in X axis, starting at the square result we've got from earlier to full circle radius. Y is successively increasing in a nested loop inside the X loop, and exits as soon as point enter circle, using pythagoras, the the value is stored, and X incremented (Y preserves) and it goes on until you've got all edge points into an array.
to draw the filled circle:
loop trough X or responding axis for each 8 mirror, in responding direction, and nested: loop Y from the middle to the value stored in the array, and plot each pixel. No aritmetics done in this process, so if you have several circles with same radius you could use the same array too. And lastly, fill the square in the middle with two nested loops.
to draw outline circle:
loop trough X and Y in the same way excep Y value is preserved, just as in the edge finding algoritm.
Well, this is straith from my head, and it might be that someone else invented this earlier or even got a better solution, i guess Harry knows
Use  
writing software in C++ is like driving rivets into steel beam with a toothpick.
writing haskell makes your life easier:
reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.
-
Apr 5th, 2001, 10:41 AM
#20
Frenzied Member
Hehe, ok.
Maybe you could do it this way:
You'd draw it using some algorythm (mine or Bresenham's ) , but only a quarter of it. It would be stored into an array, instead of drawn. Then, just draw it according to the array! It would be very easy to flip it to the other 4 quarters. Like this:
Code:
Dim Arr(0 to Width/2, 0 to Width/2) As Boolean
For x = 0 to Width/2
For y = 0 to Height/2
If [formulae-to-see-if-inside-the-circle] Then
Arr(x,y)=True
SetPixelV x,y,vbWhite
End If
If Arr(Width/2-x,y)=True Then SetPixelV x+Width/2,y,vbWhite
If Arr(x,Height/2-y)=True Then SetPixelV x,y+Height/2,vbWhite
If Arr(Width/2-x,Height/2-y)=True Then SetPixelV x+Width/2,y+Height/2,vbWhite
Next y
Next x
-
Apr 6th, 2001, 02:36 PM
#21
Fanatic Member
Here's a nice link to many gfx algorithms:
http://exaflop.org/docs/cgafaq/ind.html
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|