Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Funcationality to draw an ellipse #61

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
galdam opened this issue Apr 4, 2025 · 1 comment
Open

Funcationality to draw an ellipse #61

galdam opened this issue Apr 4, 2025 · 1 comment

Comments

@galdam
Copy link

galdam commented Apr 4, 2025

Related to Issue #21
The functionality to draw a circle was added, but not an ellipse.
I've ported this code over from them micropythonframe buffer library and can raise an MR to include it here.

@galdam
Copy link
Author

galdam commented Apr 4, 2025

Here's the code if you want to try it:


    # MicroPython framebuffer ellipse.
    # Author: Damien P. George
    # License: MIT License (https://opensource.org/licenses/MIT)
    # Source: https://github.com/micropython/micropython/blob/master/extmod/modframebuf.c
    def ellipse(self, x, y, xr, yr, c, f=False, m=None):
        """
        Draw an ellipse at the given location. Radii xr and yr define the geometry; equal values cause a circle to be drawn.
        The c parameter defines the color.
        The optional f parameter can be set to True to fill the ellipse. Otherwise just a one pixel outline is drawn.
        The optional m parameter enables drawing to be restricted to certain quadrants of the ellipse.
        The LS four bits determine which quadrants are to be drawn, with bit 0 specifying Q1, b1 Q2, b2 Q3 and b3 Q4.
        Quadrants are numbered counterclockwise with Q1 being top right.

        x: x center
        y: y center
        xr: x radius
        yr: y radius
        c: color
        f: fill
        m: quadrants
        """
        ELLIPSE_MASK_FILL = 0x10
        ELLIPSE_MASK_ALL = 0x0f
        ELLIPSE_MASK_Q1 = 0x01
        ELLIPSE_MASK_Q2 = 0x02
        ELLIPSE_MASK_Q3 = 0x04
        ELLIPSE_MASK_Q4 = 0x08

        def draw_ellipse_points(fb, cx, cy, x_counter, y_counter, col, mask):
            if (mask & ELLIPSE_MASK_FILL):
                if (mask & ELLIPSE_MASK_Q1):
                    fb.fill_rect(cx, cy - y_counter, x_counter + 1, 1, col)
                if (mask & ELLIPSE_MASK_Q2):
                    fb.fill_rect(cx - x_counter, cy - y_counter, x_counter + 1, 1, col)
                if (mask & ELLIPSE_MASK_Q3):
                    fb.fill_rect(cx - x_counter, cy + y_counter, x_counter + 1, 1, col)
                if (mask & ELLIPSE_MASK_Q4):
                    fb.fill_rect(cx, cy + y_counter, x_counter + 1, 1, col)
            else:
                if mask & ELLIPSE_MASK_Q1:
                    fb.pixel(cx + x_counter, cy - y_counter, col)
                if mask & ELLIPSE_MASK_Q2:
                    fb.pixel(cx - x_counter, cy - y_counter, col)
                if mask & ELLIPSE_MASK_Q3:
                    fb.pixel(cx - x_counter, cy + y_counter, col)
                if mask & ELLIPSE_MASK_Q4:
                    fb.pixel(cx + x_counter, cy + y_counter, col)

        mask = ELLIPSE_MASK_FILL if f else 0
        if m is not None:
            mask |= m & ELLIPSE_MASK_ALL
        else:
            mask |= ELLIPSE_MASK_ALL

        if (xr == 0 & yr == 0):
            if mask & ELLIPSE_MASK_ALL:
                self.pixel(x, y, c)
            return

        two_asquare = 2 * xr * xr
        two_bsquare = 2 * yr * yr
        x_counter = xr
        y_counter = 0
        xchange = yr * yr * (1 - 2 * xr)
        ychange = xr * xr
        ellipse_error = 0
        stoppingx = two_bsquare * xr
        stoppingy = 0

        while (stoppingx >= stoppingy):  # 1st set of points,  y' > -1
            draw_ellipse_points(self, x, y, x_counter, y_counter, c, mask)
            y_counter += 1
            stoppingy += two_asquare
            ellipse_error += ychange
            ychange += two_asquare
            if ((2 * ellipse_error + xchange) > 0):
                x_counter -= 1
                stoppingx -= two_bsquare
                ellipse_error += xchange
                xchange += two_bsquare
        # 1st point set is done start the 2nd set of points
        x_counter = 0
        y_counter = yr
        xchange = yr * yr
        ychange = xr * xr * (1 - 2 * yr)
        ellipse_error = 0
        stoppingx = 0
        stoppingy = two_asquare * yr
        while (stoppingx <= stoppingy):  # // 2nd set of points, y' < -1
            draw_ellipse_points(self, x, y, x_counter, y_counter, c, mask)
            x_counter += 1
            stoppingx += two_bsquare
            ellipse_error += xchange
            xchange += two_bsquare
            if ((2 * ellipse_error + ychange) > 0):
                y_counter -= 1
                stoppingy -= two_asquare
                ellipse_error += ychange
                ychange += two_asquare

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant