Results 1 to 33 of 33

Thread: How to draw those smooth circles in Photoshop?

  1. #1

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755

    Question How to draw those smooth circles in Photoshop?

    Hi!

    Im working on a paint program with layers like in photoshop, and im having some problems drawing the really smooth circles that photoshop do.

    i've made a function for anti-aliasing if that's nessesary...

    when selecting a quite big size on the airbrush in photoshop you get a nice gradient circle...when i made a function like this, it doesnt fill all the pixels it should and it fills some of them twice.

    can you please help me with the code....



    here's some of the code i use:

    VB Code:
    1. For Radius = 0 to TempRadius
    2.     For Angle = 0 to Pi2 Step 1 / Radius
    3.         X = Cos(Angle) * Radius
    4.         Y = Sin(Angle) * Radius
    5.     Next
    6. Next

    this will not draw gradient thou...but it draws a filled circle...
    please help me fix this code.
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  2. #2

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    look at this image...
    the filled circle at the left is how i want it to look....(i can fix the gradient myself later on...)
    the circle at the right is how it looks...



    it's drawn with rgb(255,0,0) and 50% opacity....you can see that some pixels are drawn on top of each other...
    Attached Images Attached Images  
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Circle drawing works different. First you calculate the bounding square (or rectangle, for ellipses). The you go through it top down. For each line you calculate how many pixels to the left and right from the center you have to go and color them. You'll want to color each pixel seperatly to be ready for patterns and gradients.

    It works like this:
    Radius: 3
    Center: (3,3)
    Bounding Square: (0,0)->(6,6)
    Code:
      ##
     ####
    ######
    ######
     ####
      ##
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    When you get to patterns or gradients, you simply have to calculate the color for each pixel just before setting it.
    E.g. linear gradient from white to black, starting at 0,0 and ending at 6,6. Distance: sqrt(6*6+6*6)
    Pixel at 2,2. Distance to gradient start: sqrt(2*2+2*2). Distance to gradient end: sqrt(4*4+4*4). This means it is one third to black. Pixel result is one third end color (RGB 0,0,0) and two thirds start color (RGB 255,255,255), resulting in ~ RGB 170,170,170. Set pixel 2,2 to this color. Advance to next pixel to be colored and repeat.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  5. #5
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    If I may add: those computations are the reason why all serious drawing apps are written in C++: computations simply catch VB at its worst.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  6. #6

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    Originally posted by CornedBee
    If I may add: those computations are the reason why all serious drawing apps are written in C++: computations simply catch VB at its worst.
    Yes i know...that's why im making a dll in c++
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  7. #7

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    i changed to something like this:

    VB Code:
    1. for angle = 0 to 2*Pi step 1/radius
    2.     y=cos(angle)*radius
    3.     for x=sin(2*pi-angle) *radius to sin(angle)*radius
    4.         setpixel
    5.     next
    6. next


    it works pretty allright.

    now there's another program with the layers.
    they work, but they're really slow cus when adding a pixel to a layer i redim an 1d array and add the x, y, opacity, r, g, b values...
    the problem here is when painting above another pixel that pixel gets drawn 2 times or even more times if you draw alot...

    i want to make a loop that checks if 2 pixels are at the same x and y position and then mix them together (in the array) and then remove one of them.

    how should this be done?
    something like this:

    VB Code:
    1. for layer = 0 to layercount -1
    2.     for i = 0 to layers(layer).pixelcount-1
    3.         for j = 0 to layers(layer).pixelcount-1
    4.             if i<>j then
    5.                 if layers(layer).pixels(i).x = layers(layer).pixels(j).x _
    6.                 and layers(layer).pixels(i).y = layers(layer).pixels(j).y _
    7.                 then
    8.                     'fix pixels
    9.                 end if
    10.             end if
    11.         next
    12.     next
    13. next

    how should the code for "fixing" the pixels be?
    should i take the average of the 2 pixel colors?
    how about the opacity? average too?
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  8. #8

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    here's my program:


    do you think that its better to make a 2d array for the pixels?
    so i dont have to store the x and y...cus then i can "mix" the pixels when drawing them instead of making a huge loop-in-loop-in-loop to check all pixels...
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  9. #9

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    sorry...forgot to attach
    Attached Files Attached Files
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  10. #10
    So Unbanned DiGiTaIErRoR's Avatar
    Join Date
    Apr 1999
    Location
    /dev/null
    Posts
    4,111
    The anti-aliasing results in non-opaque results.

    Even at full opacity.

    It's also very slow....

  11. #11

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    yes i know that it's really slow...im working on the speedups...

    the reason why the aa is non-opaque is because i didnt get the pixels drawn correctly so there are some gaps between the lines.
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  12. #12
    Fanatic Member
    Join Date
    Jan 2003
    Posts
    1,004
    What happens if you use a smaller interval to fill the circle? I know its slower, but if this works, then it can be optimized upon...

    Better yet, can you draw filled triangles?
    Last edited by Darkwraith; Aug 14th, 2003 at 06:03 PM.
    "Can't" and "shouldn't" are two totally separate things.

    All questions should be answered. All answers should be true. That is why I post.

  13. #13
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Still I think scanline-by-scanline is a far better technique to draw circles. Much faster, much less wasted time.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  14. #14

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    i think i'll try that method...
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  15. #15
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    Hi

    Hi Cyborg,

    Hae Drawing circles will consume time... cuz that function has to compute.. I guess cornedbee has a point...

    we can figure out the pixcel locations easily and set the pixcel color..

    I will give a try and give you some code..

    I tried with drawing circles on picbox.. it was fine ...

    Regards,
    Pradeep
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  16. #16
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    Hi

    Hi Cyborg,

    All I had to do was change the DrawWidth.. This is easy..

    Paste this code.in a form and place a PictureBox as pic.

    VB Code:
    1. Dim lRed        As Long
    2. Dim lGreen      As Long
    3. Dim lBlue       As Long
    4.  
    5. Dim fRedStp     As Single
    6. Dim fGreenStp   As Single
    7. Dim fBlueStp    As Single
    8.    
    9. Private Sub Form_Load()
    10.     SetParams vbWhite, vbRed
    11.     pic.DrawWidth = 2
    12.     pic.AutoRedraw = True
    13. End Sub
    14.  
    15. Private Sub pic_Click()
    16. pic.Cls
    17. Dim i As Integer
    18.  
    19. For i = 0 To 100
    20. pic.ForeColor = BlendColors(i)
    21. pic.Refresh
    22. pic.Circle (pic.ScaleWidth \ 2, pic.ScaleHeight \ 2), i
    23. Next
    24. End Sub
    25. Private Sub SetParams(StartColor As ColorConstants, EndColor As ColorConstants)
    26.    
    27.     Dim divVal As Single
    28.    
    29.     divVal = Sqr((pic.ScaleHeight ^ 2) + (pic.ScaleWidth ^ 2)) / 2
    30.    
    31.     lRed = (StartColor And &HFF& )
    32.     lGreen = (StartColor And &HFF00& )  / &H100&
    33.     lBlue = (StartColor And &HFF0000)  / &H10000
    34.  
    35.     fRedStp = CSng((EndColor And &HFF& ) - lRed) / divVal
    36.     fGreenStp = CSng(((EndColor And &HFF00&) / &H100& ) - lGreen) / divVal
    37.     fBlueStp = CSng(((EndColor And &HFF0000 )  /  &H10000 ) - lBlue) / divVal
    38.  
    39. End Sub
    40.  
    41. Private Function BlendColors(i As Integer) As Long
    42.  
    43.     BlendColors = RGB(Abs((lRed + i * fRedStp)), Abs((lGreen + i * fGreenStp)), _
    44.     Abs((lBlue + i * fBlueStp)))
    45.  
    46. End Function
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  17. #17

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    i didnt look through your code but i think it would be easy if i just made a function that looks through the lines as a square and check if the distance from a point is closer than the radius.
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  18. #18
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    Hae Cyborg

    Hae..... The code is to draw a grad circle..

    But Look at this..

    Set the Picture Box DrawWidth to '2'.

    See the attached picture...

    Regards,
    Pradeep
    Attached Images Attached Images  
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  19. #19
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    Hi

    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  20. #20
    So Unbanned DiGiTaIErRoR's Avatar
    Join Date
    Apr 1999
    Location
    /dev/null
    Posts
    4,111
    I'd try the scanline method.

    Here's a function I wrote to accomplish this.

    VB Code:
    1. Sub DrawCircle(ByVal x As Long, ByVal y As Long, ByVal radius As Long)
    2. Dim dY As Long, dx As Long
    3. For dY = -radius To radius 'scan lines vertically
    4. For dx = -1 * Sqr(Abs(radius ^ 2 - dY ^ 2)) To Sqr(Abs(radius ^ 2 - dY ^ 2)) 'calculate left x and right x for given y
    5. PSet (x + dx, y + dY), vbRed 'draw at offset
    6. Next
    7. Next
    8. End Sub

    I have modified my function to do gradients:

    VB Code:
    1. Sub DrawCircle(ByVal X As Long, ByVal Y As Long, ByVal radius As Long)
    2. Dim dY As Long, dx As Long, dist As Single
    3. For dY = -radius To radius
    4. For dx = -1 * Sqr(Abs(radius ^ 2 - dY ^ 2)) To Sqr(Abs(radius ^ 2 - dY ^ 2))
    5. dist = Sqr(dx ^ 2 + dY ^ 2) 'compute distance
    6. PSet (X + dx, Y + dY), RGB(dist / radius * 255, 0, 0) 'color point based on dist and radius
    7. Next
    8. Next
    9. End Sub
    Last edited by DiGiTaIErRoR; Aug 20th, 2003 at 12:47 AM.

  21. #21
    So Unbanned DiGiTaIErRoR's Avatar
    Join Date
    Apr 1999
    Location
    /dev/null
    Posts
    4,111
    I've developed yet another method to smoothly gradient onto a background.

    VB Code:
    1. 'declares
    2. Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
    3. Private Declare Function SetPixelV Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long
    4.  
    5. '----
    6.  
    7. Sub DrawCircle(ByVal x As Long, ByVal y As Long, ByVal radius As Long, ByVal cR As Long, ByVal cG As Long, ByVal cB As Long)
    8. Dim dY As Long, dx As Long, dist As Long, iColor As Long, r As Long, g As Long, b As Long
    9. For dY = -radius To radius Step 1
    10. For dx = -1 * Sqr(Abs(radius ^ 2 - dY ^ 2)) To Sqr(Abs(radius ^ 2 - dY ^ 2)) Step 1
    11. iColor = GetPixel(hdc, x + dx, y + dY)
    12.     r = (iColor And &HFF&)
    13.     g = (iColor And &HFF00&) \ &H100&
    14.     b = (iColor And &HFF0000) \ &H10000
    15.  
    16. dist = Sqr((dx) ^ 2 + (dY) ^ 2)
    17. dr = dist / radius
    18. idr = 1 - dr
    19.  
    20. r = (r * dr) + (cR * idr)
    21. g = (g * dr) + (cG * idr)
    22. b = (b * dr) + (cB * idr)
    23.  
    24. SetPixelV hdc, x + dx, y + dY, RGB(r, g, b)
    25. Next
    26. Next
    27. End Sub

  22. #22
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    Hi

    CANT WE DRAW CIRCLES FROM RADIUS = 0 to MAX BY SETTING DrawWidth = 2 for the PICTURE BOX

    WHICH WOULD SOLVE....


    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  23. #23
    So Unbanned DiGiTaIErRoR's Avatar
    Join Date
    Apr 1999
    Location
    /dev/null
    Posts
    4,111

    Re: Hi

    Originally posted by pradeepkrao
    CANT WE DRAW CIRCLES FROM RADIUS = 0 to MAX BY SETTING DrawWidth = 2 for the PICTURE BOX

    WHICH WOULD SOLVE....


    My scanline sub offers blending onto the background, and can draw a circle of radius 50 in about 80 ms.

    Which is probably what he wanted in the first place.

  24. #24

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    here's a new version of my paint program...

    i've managed to make the drawing look good...did it like this

    VB Code:
    1. For tempx = -radius To radius
    2.     For tempy = -radius To radius
    3.         If getdistance(tempx,tempy,0,0) <= radius Then
    4.             'now the pixel is in the circle and can be drawn.
    5.             'for the gradient i used a sin curve from 0 to 1
    6.             'and multiplied it by the brightness.
    7.          End If
    8.     Next
    9. Next

    no other changes are made, so its still really slow....

    could you please help me find a way to make a 2d array that can be redimmed properly?
    Attached Files Attached Files
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  25. #25
    Fanatic Member pradeepkrao's Avatar
    Join Date
    Sep 2001
    Location
    New Jersey
    Posts
    534

    Hi DiGiTaIErRoR

    Hae Sorry .. I dint read the post fully....

    Cyborg sent me a pm anyway..
    Last edited by pradeepkrao; Aug 20th, 2003 at 03:14 AM.
    Learn by others experience as you cannot live long to experience them all.
    www.freewebs.com/pradeepkrao

    LOOK AT MY GAMES AT MY WEB SITE.

  26. #26
    So Unbanned DiGiTaIErRoR's Avatar
    Join Date
    Apr 1999
    Location
    /dev/null
    Posts
    4,111
    I'd suggest working with the entire 32bit DIB, then use AlphaBlend to blt each layer with the extra byte for the alpha mask.

  27. #27

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    i'll just make a 1d field instead
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  28. #28
    So Unbanned DiGiTaIErRoR's Avatar
    Join Date
    Apr 1999
    Location
    /dev/null
    Posts
    4,111
    Originally posted by cyborg
    i'll just make a 1d field instead
    AlphaBlend API is hardware accelerated. So it'll take some load off the cpu, freeing resources for your other computations.

    You may also want to look into GDI+.

    Perhaps DDraw.

    Atleast utilize some MMX or SSE extensions. You can do this fairly easily in C using ASM.

    I hear the intel site has the instruction documentation.

    Otherwise, google it.

  29. #29

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    well...does the alphablend api blend each pixel with different alpha value?...thats the whole point with this program
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  30. #30
    So Unbanned DiGiTaIErRoR's Avatar
    Join Date
    Apr 1999
    Location
    /dev/null
    Posts
    4,111

  31. #31

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    does it work with win98 and earlier versions?
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  32. #32
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I think it works with 98, but nothing earlier.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  33. #33
    So Unbanned DiGiTaIErRoR's Avatar
    Join Date
    Apr 1999
    Location
    /dev/null
    Posts
    4,111
    Originally posted by cyborg
    does it work with win98 and earlier versions?
    It works with 98... even though it's over 5 years old!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width