BBC BASIC for Windows
« Circular arcs and tangent peculiarity »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 10:18pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Circular arcs and tangent peculiarity  (Read 323 times)
Zaphod
Guest
xx Circular arcs and tangent peculiarity
« Thread started on: Jan 10th, 2017, 1:51pm »

I was recently trying to draw arcs with tangents using the BB4W graphics commands and had difficulty with offsets of one or two pixels. I naturally imagined that I was doing something wrong. But looking again and running some test programs I find that there is something strange going on.

I imagined that if I drew a box and put a circle in the middle then the circle would be tangential to the sides. That is not what happens!
What happens depends on the values you choose for your coordinates. Now just to be sure, I understand that BB4W graphics units are twice the pixel count so the numbers have to be even. Then since we are dealing with a mid point for the radius that implies that the bounding square has to be an odd number of pixels so that there is a definite pixel that is the mid point. See the first two circles where we have even pixel sided squares which is what we kind of gravitate towards when programming. How close you get depends on the numbers you choose which I am sure is due to integer arithmetic in the code.
So we make a square with an odd number of pixels, which should work, but the x and y coordinate behave differently and I had to change the y coordinate by 1 pixel to make it work.
See the various attempts and how some values get closer than others. The first two could never have worked as the sides are an even numbers of pixels,
Code:
      ORIGIN 100,100
      MOVE 0,0

      DRAW 0,500
      DRAW 500,500
      DRAW 500,0
      DRAW 0,0
      REM MOVE 250,250
      REM MOVE 0,250
      REM PLOT 165, 0, 252
      CIRCLE 250,250,250

      ORIGIN 700,100
      MOVE 0,0
      DRAW 0,496
      DRAW 496,496
      DRAW 496,0
      DRAW 0,0
      REM MOVE 248,248
      REM MOVE 0,248
      REM PLOT 165, 0, 250
      CIRCLE 248,248,248

      ORIGIN 1300,100
      MOVE 0,0
      DRAW 0,502
      DRAW 502,502
      DRAW 502,0
      DRAW 0,0
      REM MOVE 248,248
      REM MOVE 0,248
      REM PLOT 165, 0, 250
      CIRCLE 252,250,252
 


So you would think the third circle should work with x=252, y=252
But you can try that and see it is shifted too high.

In the end I decided that BB4W graphics were unsuited to the task I had in hand and used the GDI+ library which has no such issues.

If anyone knows how to ensure that tangents are actually tangential with BB4W arcs, always, I would be interested to hear because I can't fathom it. And I was not trying something as simple as bounding squares but in joining different curves seamlessly by having a common tangent. In that I failed.
User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: Circular arcs and tangent peculiarity
« Reply #1 on: Jan 10th, 2017, 4:57pm »

Hi Zaphod,

I wonder if it relates to the issue described in "pixel-perfect graphics", with relation to FILLED shapes: that the Windows polygon function is used, and includes the top left, but not the bottom right point of the vertices.

I note that the previous section says outline shapes are inclusive (i.e. the area covered by the lines is one greater than the specified width and height), but that that paragraph mentions triangles, rectangles and parallelograms, but not circles, ellipses or arcs.

That would explain why your bounding box is a little bigger than the circle that should fit exactly within it?

Try adding this:
Code:
      ORIGIN 100,600
      MOVE 250,250
      MOVE 502,250     :REM Set right-hand edge 1 pixel further right than expected, since it will be omitted?
      REM                   Arguably, it looks better ANOTHER pixel further right - not sure why - probably the coordinate of the arc never QUITE reaches the integer value
      PLOT 165,250,500
      MOVE 750,250
      MOVE 500,250
      PLOT 165,750,0
      GCOL 3,1
      LINE 500,0,500,500
      GCOL 0,0
      MOVE 250,750
      MOVE 0,750
      PLOT 165,252,-2  :REM Need to set this intersection point one pixel lower and one pixel further right
 

Don't know if that helps...

D
User IP Logged

hellomike
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 46
xx Re: Circular arcs and tangent peculiarity
« Reply #2 on: Jan 10th, 2017, 7:16pm »

Hi,

Is that the same peculiarity, that I encounter within the next program?
Code:
      order%=2
      size=(2^order%-1)*4+2
      h%=1024/size:PRINT "h% = ";h%
      MOVE 400,200+h%
      PROCsierpinski(order%)
      END

      DEF PROCsierpinski(n%)
      PROCleft(n%)  :PLOT1,h%,h%
      PROCtop(n%)   :PLOT1,h%,-h%
      PROCright(n%) :PLOT1,-h%,-h%
      PROCbottom(n%):PLOT1,-h%,h%
      ENDPROC

      DEF PROCleft(n%)
      IF n%=0 ENDPROC
      PROCleft(n%-1)  :PLOT1,h%,h%
      PROCtop(n%-1)   :PLOT1,0,h%*2
      PROCbottom(n%-1):PLOT1,-h%,h%
      PROCleft(n%-1)
      ENDPROC

      DEF PROCtop(n%)
      IF n%=0 ENDPROC
      PROCtop(n%-1)  :PLOT1,h%,-h%
      PROCright(n%-1):PLOT1,h%*2,0
      PROCleft(n%-1) :PLOT1,h%,h%
      PROCtop(n%-1)
      ENDPROC

      DEF PROCright(n%)
      IF n%=0 ENDPROC
      PROCright(n%-1) :PLOT1,-h%,-h%
      PROCbottom(n%-1):PLOT1,0,-h%*2
      PROCtop(n%-1)   :PLOT1,h%,-h%
      PROCright(n%-1)
      ENDPROC

      DEF PROCbottom(n%)
      IF n%=0 ENDPROC
      PROCbottom(n%-1):PLOT1,-h%,h%
      PROCleft(n%-1)  :PLOT1,-h%*2,0
      PROCright(n%-1) :PLOT1,-h%,-h%
      PROCbottom(n%-1)
      ENDPROC
 

When h% is an odd number (e.g. when order%=2), the shape doesn't correctly close.
See bottom left corner.

When I run the same program within RISCOS (BASIC V 1.29), the shape does close correctly!

Thanks

Mike
User IP Logged

Zaphod
Guest
xx Re: Circular arcs and tangent peculiarity
« Reply #3 on: Jan 10th, 2017, 10:11pm »

Hi, Mike,

It is related but not the same I think. Your problem is the simple fact that h% must be an even number so that it plots to a pixel. You are getting 'rounding' down to the lower pixel. A BB4W graphic maps to pixel that is h% DIV 2. With odd values of h% all sorts of weird stuff happens!

DDRM. Your curved plot is typical what I have seen. Just that one or two pixel out sometimes. To make matters worse my radius and angles of arcs are user inputs so individual tweaks can't be applied. Some inputs looked quite ratty and others just fine. Since computers are logical it must be something that can be defined. It is something to play with on snowy days.
Thanks for your comments and I will look at that Pixel Perfect bit again. I just find it very strange that with PLOT 165 you give it the center and a point on the curve, and then it draws it and the point isn't on the curve by 1 pixel. It looks as if there is a similar effect though if you do this with circles:
Code:
      x%=500
      y%=500
      r%=204
      CIRCLE x%,y%,r%
      PRINT ~(TINT(x%,y%+r%))  :REM Top
      PRINT ~(TINT(x%,y%-r%))  :REM Bottom
      PRINT ~(TINT(x%-r%,y%))  :REM Left
      PRINT ~(TINT(x%+r%,y%))  :REM Right

 

Where 2 results are what you expect and 2 aren't if r% is divisible by 4, and none of the 4 points are plotted if r% not divisible by 4

So lets make it not divisible by 4 and see what points are plotted.
Code:
      x%=500
      y%=500
      r%=202
      CIRCLE x%,y%,r%
      PRINT ~(TINT(x%,y%+r%))  :REM Top
      PRINT ~(TINT(x%,y%-r%))  :REM Bottom
      PRINT ~(TINT(x%-r%,y%))  :REM Left
      PRINT ~(TINT(x%+r%,y%))  :REM Right
      PRINT "-1"
      PRINT ~(TINT(x%,y%+r%-2))  :REM Top
      PRINT ~(TINT(x%,y%-r%+2))  :REM Bottom
      PRINT ~(TINT(x%-r%+2,y%))  :REM Left
      PRINT ~(TINT(x%+r%-2,y%))  :REM Right
      PRINT "-2"
      PRINT ~(TINT(x%,y%+r%-4))  :REM Top
      PRINT ~(TINT(x%,y%-r%+4))  :REM Bottom
      PRINT ~(TINT(x%-r%+4,y%))  :REM Left
      PRINT ~(TINT(x%+r%-4,y%))  :REM Right
 


So the radius has to be divisible by 4 or you can be up to 2 pixels out, and smaller than you would think, whereas the RECTANGLE is shifted by 1 pixel according to the 'Pixel Perfect' topic. The search continues...
What fun?
UPDATE: It seems that with the radius divisible by 4 (BB4W Graphics units) the Top and Left side are where I would expect but the bottom and right are 1 pixel closer to the center. With a radius that is not divisible by 4 the circumference is an additional pixel closer to the center on the four quadrants. So top and left are -1, bottom and right are -2 pixels.
Now how do I use that information? Nah, GDI+ library still looks a better option.

Z
« Last Edit: Jan 10th, 2017, 10:53pm by Zaphod » User IP Logged

hellomike
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 46
xx Re: Circular arcs and tangent peculiarity
« Reply #4 on: Jan 14th, 2017, 9:21pm »

Thanks.

I guess BASIC V rounds rather than truncates.

Regards,

Mike
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls