help needed in plotting curved elements

We are working on plotting mesh (in hermes2d: http://hpfem.math.unr.edu/projects/hermes2d-new/) We created a python function to plot mesh but initially without curves. Later we also tried to work on curved elements but we are having some problems.

In the hermes2d examples curves are defined as [4, 7, 45] where 4,7 are vertices indices, and 45 is center angle.

But in matplotlib we do not see any function to plot curve with these data, we have to convert them into something more useful to those functions available in matplotlib. For ex:

  1. matplot.path porvides a way to plot curve with three points

http://matplotlib.sourceforge.net/api/path_api.html#module-matplotlib.path

p1 -> starting Point
p2 -> control point
p3 -> end point

iI we want to go this way we do have p1 & p3 but have to calclate p2
(control point)

  1. matplot.patch.arc provides a way to plot an arc

http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.patches

but it needs
-> center of circle
-> start angle
-> end angle
-> radius of circle
we have to calculate all these with data available to us

We didn’t find other ways of plotting curves using matplotlib…and in our view method 1 is the best way for us because currently we have implemented matplotlib.path to draw mesh without curves, and it will be easy to fill color this way.

We tried the method 1 but the result was a garbled mesh. I would appreciate if anybody could guide us how we can use the matplotlib functions to draw curved elements if we are given information as described above.

Thanks

Please describe what you did and why the result is wrong.

The method 1 with quadratic bezier curve should be most
straight-forward and easy thing to do. Calculating the control points
is also straight forward. While you may simply use
matplotlib.bezier.get_intersection, you'd better come up with some
optimized version since you need to calculate this for lots of
positions.

It is not clear how you're drawing path currently, but Line2D class is
not suitable for bezier lines. You may use PathPatch class. Or you can
create your own artist class (maybe this is what you meant by
"implemented"). A simple version of bezier artist can be found in
mpl_toolkits.axes_grid.axeslines.BezierPath (included in mpl 0.99).

If you haven't, please take a look at the tutorial below.

http://matplotlib.sourceforge.net/users/path_tutorial.html

-JJ

···

On Thu, Aug 20, 2009 at 2:01 AM, Sameer Regmi<regmisk@...287...> wrote:

We tried the method 1 but the result was a garbled mesh

Sameer Regmi wrote:

We are working on plotting mesh (in hermes2d: http://hpfem.math.unr.edu/projects/hermes2d-new/)

In the hermes2d examples curves are defined as [4, 7, 45] where 4,7 are vertices indices, and 45 is center angle.

1) matplot.path porvides a way to plot curve with three points
http://matplotlib.sourceforge.net/api/path_api.html#module-matplotlib.path

This is a Bezier spline -- it can not exactly form a piece of a circle (though it can get pretty close). You can probably find the math somewhere for how to approximate a circle, but...

2) matplot.patch.arc provides a way to plot an arc
http://matplotlib.sourceforge.net/api/artist_api.html#module-matplotlib.patches

but it needs
-> center of circle
-> start angle
-> end angle
-> radius of circle
   we have to calculate all these with data available to us

Since this actually plots s circle, I think it's a better bet. It should
be pretty straightforward coordinate geometry to find those parameters from the ones you have -- and you only have to write that once!

This page (or others like it) might help you get started:

HTH,

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@...259...

somewhere like ... matplotlib.path.unit_circle (thanks to Michael D)

    @classmethod
    def unit_circle(cls):
        """
        (staticmethod) Returns a :class:`Path` of the unit circle.
        The circle is approximated using cubic Bezier curves. This
        uses 8 splines around the circle using the approach presented
        here:

          Lancaster, Don. `Approximating a Circle or an Ellipse Using Four
          Bezier Cubic Splines <http://www.tinaja.com/glib/ellipse4.pdf&gt;\`\_\.
        """
        if cls._unit_circle is None:
            MAGIC = 0.2652031
            SQRTHALF = np.sqrt(0.5)
            MAGIC45 = np.sqrt((MAGIC*MAGIC) / 2.0)

            vertices = np.array(
                [[0.0, -1.0],

                 [MAGIC, -1.0],
                 [SQRTHALF-MAGIC45, -SQRTHALF-MAGIC45],
                 [SQRTHALF, -SQRTHALF],

                 [SQRTHALF+MAGIC45, -SQRTHALF+MAGIC45],
                 [1.0, -MAGIC],
                 [1.0, 0.0],

                 [1.0, MAGIC],
                 [SQRTHALF+MAGIC45, SQRTHALF-MAGIC45],
                 [SQRTHALF, SQRTHALF],

                 [SQRTHALF-MAGIC45, SQRTHALF+MAGIC45],
                 [MAGIC, 1.0],
                 [0.0, 1.0],

                 [-MAGIC, 1.0],
                 [-SQRTHALF+MAGIC45, SQRTHALF+MAGIC45],
                 [-SQRTHALF, SQRTHALF],

                 [-SQRTHALF-MAGIC45, SQRTHALF-MAGIC45],
                 [-1.0, MAGIC],
                 [-1.0, 0.0],

                 [-1.0, -MAGIC],
                 [-SQRTHALF-MAGIC45, -SQRTHALF+MAGIC45],
                 [-SQRTHALF, -SQRTHALF],

                 [-SQRTHALF+MAGIC45, -SQRTHALF-MAGIC45],
                 [-MAGIC, -1.0],
                 [0.0, -1.0],

                 [0.0, -1.0]],
                np.float_)

            codes = cls.CURVE4 * np.ones(26)
            codes[0] = cls.MOVETO
            codes[-1] = cls.CLOSEPOLY

            cls._unit_circle = cls(vertices, codes)
        return cls._unit_circle

···

On Sun, Aug 23, 2009 at 7:45 PM, Chris Barker<Chris.Barker@...259...> wrote:

This is a Bezier spline -- it can not exactly form a piece of a circle
(though it can get pretty close). You can probably find the math
somewhere for how to approximate a circle, but...

Thank you Lee. Thank you Chris and John, the problem is solved.
Chris, we did the method 1) as this was easier for us.
Sameer

···

On Sun, Aug 23, 2009 at 5:53 PM, John Hunter <jdh2358@…287…> wrote:

On Sun, Aug 23, 2009 at 7:45 PM, Chris Barker<Chris.Barker@…259…> wrote:

This is a Bezier spline – it can not exactly form a piece of a circle

(though it can get pretty close). You can probably find the math

somewhere for how to approximate a circle, but…

somewhere like … matplotlib.path.unit_circle (thanks to Michael D)

@...2748...

def unit_circle(cls):

    """

    (staticmethod) Returns a :class:`Path` of the unit circle.

    The circle is approximated using cubic Bezier curves.  This

    uses 8 splines around the circle using the approach presented

    here:



      Lancaster, Don.  `Approximating a Circle or an Ellipse Using Four

      Bezier Cubic Splines <[http://www.tinaja.com/glib/ellipse4.pdf](http://www.tinaja.com/glib/ellipse4.pdf)>`_.

    """

    if cls._unit_circle is None:

        MAGIC = 0.2652031

        SQRTHALF = np.sqrt(0.5)

        MAGIC45 = np.sqrt((MAGIC*MAGIC) / 2.0)



        vertices = np.array(

            [[0.0, -1.0],



             [MAGIC, -1.0],

             [SQRTHALF-MAGIC45, -SQRTHALF-MAGIC45],

             [SQRTHALF, -SQRTHALF],



             [SQRTHALF+MAGIC45, -SQRTHALF+MAGIC45],

             [1.0, -MAGIC],

             [1.0, 0.0],



             [1.0, MAGIC],

             [SQRTHALF+MAGIC45, SQRTHALF-MAGIC45],

             [SQRTHALF, SQRTHALF],



             [SQRTHALF-MAGIC45, SQRTHALF+MAGIC45],

             [MAGIC, 1.0],

             [0.0, 1.0],



             [-MAGIC, 1.0],

             [-SQRTHALF+MAGIC45, SQRTHALF+MAGIC45],

             [-SQRTHALF, SQRTHALF],



             [-SQRTHALF-MAGIC45, SQRTHALF-MAGIC45],

             [-1.0, MAGIC],

             [-1.0, 0.0],



             [-1.0, -MAGIC],

             [-SQRTHALF-MAGIC45, -SQRTHALF+MAGIC45],

             [-SQRTHALF, -SQRTHALF],



             [-SQRTHALF+MAGIC45, -SQRTHALF-MAGIC45],

             [-MAGIC, -1.0],

             [0.0, -1.0],



             [0.0, -1.0]],

            np.float_)



        codes = cls.CURVE4 * np.ones(26)

        codes[0] = cls.MOVETO

        codes[-1] = cls.CLOSEPOLY



        cls._unit_circle = cls(vertices, codes)

    return cls._unit_circle