Skip to main content
1 of 3
Level River St
  • 26.7k
  • 4
  • 37
  • 105

#BBC Basic, (currently half of) 5 polygons#

OK so I have a bug, but I thought I'd post what I have to show interest.

The program does a pre-construction (per the first image) before asking for any user input. This is sufficient to define at least 2 points on the main circle which correspond to adjacent vertices of a 3,4,6,8 or 12 sided figure. The points are stored in a set of 99-element arrays, in which elements 0-59 are set aside for the circumference (this is mainly for clarity, the octagon and 16-gon do not fit perfectly into 60 points so some flexibility is needed for them.)

The user inputs the number of sides required, and for the time being, a number corresponding to the position in the array of the first of the two points (this will be automated.)

The program then loops through the process of drawing a circle centred on the second point that passes throug the first, and calculating the new intersection in order to walk its way round the main circle. The construction circles are drawn in blue, and the required polygon is drawn in red. Some unneccesary blue construction lines are drawn as well by default, but they can be suppressed. These lines actually form a star with a polygon at the centre, so alternatively they could be considered the required output (OP's opinion on that please.)

There are of course 2 intersections between any given pair of overlapping circles, and in order for the loop to work correctly, the function which calculates the intersections must return these in a consistent order (supposed to be anticlockwise intersection then clockwise intersection as viewed from the centre of the first named circle.) There is a bug in the code that calculates the order of these two points inside the function, therefore only half the polygon is displayed. My first attempt to fix this produced a division by zero error, so I will review it again later this weekend.

Once the bug is fixed, it should be reasonably simple to add the preconstructions required for the shapes with numbers of sides divisible by 5 (only 2 more circles and 2 more points are required.)

enter image description here

  z=999                             :REM width of display (in positive and negative direction)
  DIM m(99),c(99),p(99),q(99),r(99) :REM array declaration for lines and points
  REM lines have a gradient m and y-intercept c. Points have coordinates (p,q) and may be associated with a circle of radius r.

  ORIGIN 500,500
  p(60)=0:q(60)=0                   :REM P60=centre of main circle
  p(15)=240:q(15)=70                :REM P15=intersection main circle & horiz line
  t=FNr(60,15)                      :REM draw main circle, set radius, SQR(240^2+70^2)=250 units (125 pixels)
  t=FNl(1,60,15)                    :REM L1=horizontal through main circle
  t=FNc(15,45,1,60,-1)              :REM define P45 as other intersection of main cir and horiz line. overwrite P15 with itself.
  t=FNr(15,45):t=FNr(45,15)         :REM draw 2 large circles to prepare to bisect L1
  t=FNc(61,62,2,45,15)              :REM bisect L1, forming line L2 and two new points
  t=FNc(0,30,2,60,-1)               :REM define points P0 and P30 on the crossings of L2 and main circle
  t=FNr(30,60):t=FNc(20,40,3,60,30) :REM draw circles at P30, and line L3 through intersections with main circle, to define 2 more points
  t=FNr(15,60):t=FNc(5,25,4,60,15)  :REM draw circles at P15, and line L4 through intersections with main circle, to define 2 more points
  t=FNx(63,3,4):t=FNl(5,63,60)      :REM draw L5 at 45 degrees
  t=FNc(53,64,5,60,-1)              :REM define where L5 cuts the main circle


  INPUT d,g
  FORf=0TOd
    GCOL12
    h=(g+60DIVd)MOD60
    t=FNr(h,g)
    t=FNc(99,(h+60DIVd)MOD60,99,60,h)
    GCOL9
    LINEp(g),q(g),p(h),q(h)
    g=h
  NEXT



  END

  REM line through a and b
  DEFFNl(n,a,b)
  m(n)=(q(a)-q(b))/(p(a)-p(b))
  c(n)=q(a)-m(n)*p(a)
  LINE -z,c(n)-m(n)*z,z,c(n)+m(n)*z
  =n

  REM radius of circle at point a passing through point b
  DEFFNr(a,b)
  r(a)=SQR((p(a)-p(b))^2+(q(a)-q(b))^2)
  CIRCLEp(a),q(a),r(a)
  =a

  REM intersection of 2 lines: ma*x+ca=mb*x+cb so (ma-mb)x=cb-ca
  DEFFNx(n,a,b)
  p(n)=(c(b)-c(a))/(m(a)-m(b))
  q(n)=m(a)*p(n)+c(a)
  =n

  REM intersection of 2 circles a&b (if b>-1.) The first step is calculating the line through the intersections
  DEFFNc(i,j,n,a,b)
  IF b>-1 c(n)=((r(a)^2-r(b)^2)-(p(a)^2-p(b)^2)-(q(a)^2-q(b)^2))/2/(q(b)-q(a)):m(n)=(p(a)-p(b))/(q(b)-q(a)):LINE -z,c(n)-m(n)*z,z,c(n)+m(n)*z

  REM intersection of line and circle (if b < 0 the first part of the function is ignored.)
  REM inspiration from http://math.stackexchange.com/a/256123/137034
  REM (mx+ c-q)^2+(x-p)^2=r^2
  REM (m^2+1)x^2 + 2*(m*(c-q)-p)x + (c-q)^2+p^2-r^2=0
  REM quadratic formula for ux^2+vx+w=0 is x=-v/2u +/- SQR(v^2-4*u*w)/2u or x= v/2u +/- SQR((v/2u)^2 - w/u)

  u=m(n)^2+1
  v=-(m(n)*(c(n)-q(a))-p(a))/u               :REM here v corresponds to v/2u in the formula above
  w=SQR(v^2-((c(n)-q(a))^2+p(a)^2-r(a)^2)/u)


  s=SGN(m(n)+c(n)*p(a)-q(a))                 :REM BUG HERE!
  p(i)=v+s*w:q(i)=m(n)*p(i)+c(n)
  p(j)=v-s*w:q(j)=m(n)*p(j)+c(n)
  =n
Level River St
  • 26.7k
  • 4
  • 37
  • 105