1

I'm trying to create some graphics function for a ZX Spectrum (Z80) machine in assembler. I already have the basics except for the arc.

I know that there must be some way to draw an arc using the Bresenham's circle algorithm but I'm unable to find concrete info about it, there are sentences like "set the pixels only if they fall into the wanted interval" but I have no clue on how to determine if the pixels fall within it.

As data I have the circle's center and radius and the start and end points of the arc in the circle, I only miss how to determine if a pixel lies in the arc, if the algorithm were completely linear (start at 0º and sweep to 360º) it would be easy to do not draw until the start point is reached and then continue drawing until the last point is reached, but the Bresenham's algorithm is drawn in octants simultaneously so I have no idea on how to do it.

I'm not tied to anything so any other algorithm would be welcome, no need to be specifically for the spectrum, just any assembler algorithm to draw an arc will be enough, even if I need different info (like the three point arc algorithm).

Cheers.

  • 1
    @MartinMaly: They require no multiplies or divides, at least not in the loop. The symmetry is an extra bonus that you would either ditch, or would complicate it for an arc. – hippietrail Jun 9 at 6:00
  • 1
    @Wilson I am using the ROM function from assembler but it's painfully slow, the implementation in the Spectrum ROM uses the calculator stack to compute the arc using internally a lot of floating point operations and that's what i'm trying to avoid. – Gusman Jun 9 at 6:09
  • 1
    @Wilson: The Spectrum's Basic circle-drawing algorithm does not use Breseham's algorithm. They seem not to have been aware of it. The use a much slower method resulting in much more lumpy circles that I assume is based on the ROM's trig functions. – hippietrail Jun 9 at 7:01
  • 4
    @Gusman since this isn't retro-specific and it's already getting negative votes I'm going to suggest it get moved to computergraphics SE. Tweak your wording to ask for an integer or fixed-point solution. Note that two circles (or none) will satisfy crossing through two points with a given radius. – hippietrail Jun 9 at 7:18
  • 4
    I’m voting to close this question because it belongs on computergraphics.stackexchange.com – hippietrail Jun 9 at 7:19
1

There might be many options, but you need to calculate if you should draw a pixel or not. When you define an arc say from 10 to 100 degrees, you have two endpoints that lie on a circle. Based on radius and angle, you can calculate the X and Y coordinates of these two endpoints. You can imagine drawing a line between these two points, and if the circle pixel is above the line, the pixels get drawn, otherwise they are not. So whe you draw the circle with Breseham's you get X,Y coordinates and for the X you calculate the Y coordinate of the line and if Y of arc is >= Y of line then plot.

| improve this answer | |
  • I already have those points as stated on the question, and that method does not work, if I have start point at 0º and end point at 180º ({ x:0, y:Radius}, { x:0, y:-Radius}) that will create a virtual line from top to bottom, so it would draw the full circle instead of half. – Gusman Jun 9 at 5:59
  • Yes, special cases need to be handled, just like when drawing a line with Bresenham along Y or along X axis. Flip the coordinate axes when line has X1==X2, you need it anyway for all arcs. I just got confused as usually the coordinates for 0° is y=0 x=radius. – Justme Jun 9 at 6:13
  • Something tells me that this would fail in many cases but I'm going to test it – Gusman Jun 9 at 6:20
  • Yep, this doesn't works at all, check this image, it will explain better why this can't work. imgur.com/a/y4btej9 – Gusman Jun 9 at 6:29
  • Well obviously, because the straight line must go between points A and B. Everything that is below/left of the line between A and B is the arc. – Justme Jun 9 at 6:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.