Loading ...
Sorry, an error occurred while loading the content.
 

corrupted symbols: analysis and solution

Expand Messages
  • Andrew Schulman
    Back in July, I reported a problem with corrupted symbols in scatterplots on this list (http://groups.yahoo.com/group/ploticus/message/1581). An example can
    Message 1 of 12 , Oct 2 10:38 PM
      Back in July, I reported a problem with corrupted symbols in scatterplots on
      this list (http://groups.yahoo.com/group/ploticus/message/1581). An
      example can be seen in, for example, the y=7 and y=7.4 rows at
      http://home.comcast.net/~andrex/bugz/ploticus.png (created by the script at
      http://home.comcast.net/~andrex/bugz/ploticus.plo). Those are rows of
      diamonds that got corrupted in the plot.

      Steve answered my query as follows:

      > Ploticus generates vector graphics, which must be rasterized to get them
      > into PNG/GIF. Then when PNG/GIF are rendered by the browser there may be
      > another round of rasterization that might not sync with the first round.

      OK. The remainder of the thread concerned using GD's new anti-aliasing
      facilities to mitigate the aliasing.

      I still have the corrupted symbols problem, and ploticus is so good in every
      other respect that I'd really like to see it get fixed. Here are my
      thoughts, please tell me what you think.

      First, this isn't a browser effect. It persists in any viewer at any
      magnification. So it's a ploticus and/or libgd problem.

      Second, the problem doesn't seem to be in GD. I don't know much about GD;
      all I've done is to browse the documentation online. But AFAICT, GD deals
      only in pixels. All calls to GD functions pass arguments in pixel units.
      Therefore, the pixelization or aliasing is happening in ploticus. In my
      mind this is good news, because it means the problem must be solvable in
      ploticus.

      Third, anti-aliasing isn't a solution. AA just amounts (as I understand
      it anyway; please correct me if I'm wrong in the context of GD) to blurring
      the plot lines in order to soften jagged edges. This is, IMO, undesirable
      in most cases, since it reduces the sharpness of the plot; and it doesn't
      solve the underlying problem. Aliasing in ploticus is often bad enough to
      make the interior color of a symbol spill outside the symbol boundary. You
      can see this, for example, in every diamond in the y=7 row in the plot
      cited above (expand the row and look at the lower right edge of each
      diamond). AA may partly obscure this effect, but it can't solve it. (It
      may be a good idea for shapes other than vertical, horizontal, and diagonal
      lines, however, since it can reduce jaggedness.)

      Here's how I see the problem and its solution. In order to draw, say,
      a diamond, ploticus uses the following algorithm:

      (0) Start with coordinates (x,y) of the diamond's center, and a radius r.

      (1) Compute offsets from the center to the vertices in a standard (r=1)
      diamond, e.g. (1,0), (0,1), (-1,0), and (0,-1).

      (2) Compute the vertex coordinates: e.g. for the right vertex they're
      (x,y) + r * (0,1) = (x, y+r).

      (3) Convert the vertex coordinates from plot units to pixel units.

      (4) Call GD to draw lines between the vertices.

      This algorithm is implemented in PLG_mark() in mark.c. But the conversion
      to pixel units happens at a lower level-- PLG_mark calls Emov() and Epath()
      to plot the points and lines, and these eventually call PLG_xsca() and
      PLG_ysca() in winscale.c, which multiply x and y by global scaling factors
      to convert to pixel units.

      The aliasing, or rounding error, occurs in step 3. And the problem with
      this algorithm is that the vertex coordinates are all computed in plot
      units, and then independently rasterized, so the rounding error on each
      coordinate can go in a separate direction. This is what causes the diamond
      shape to distort in a random way.

      The solution is simple in principle: convert the center coordinates and
      radius to pixel units _before_ computing the vertex coordinates. That is,
      remove step 3 and add

      (1.5) Convert x, y, and r from plot units to pixel units.

      The distortion problem will be solved, because the rounding error will
      happen just one time on r, and then be applied uniformly in finding all of
      the vertices. The shape will be a perfect diamond (or square or whatever).
      (This is "less accurate" for the individual vertices, since they can't
      independently find their closest pixels. But with plot symbols the
      accuracy of the vertices isn't the point; drawing a clean, recognizable
      shape is the point.)

      In practice this would take some work to implement, because as I said above,
      the conversion to pixel units currently happens at a low level in
      ploticus-- just before the GD plotting routines are called. This approach
      simplifies the higher-level code, which doesn't have to worry about any unit
      conversions. In order to perform the pixel conversion at a higher level,
      points will now have to implicitly carry units with them, and those units
      will have to be passed down through all of the drawing routines. So for
      example in PLG_mark(), the calls to Emov() and Epath will have to include a
      new "already in pixel units" flag, to tell the lower-level routines not to
      convert them again.

      Specifying the symbol radius in pixels would have the added benefit of
      providing a natural sequence of symbol sizes for users to choose from.

      If it would be useful, I could try to create a proof-of-concept patch. I'm
      not sure how long it would take, but the ploticus code seems to be pretty
      clearly laid out, so it might not be too bad.

      Andrew.
    • Stephen C. Grubb
      Andrew, thanks for giving this some thought. On first pass I d make these observations: - ploticus generates symbols using its standard line drawing and/or
      Message 2 of 12 , Oct 3 5:27 AM
        Andrew, thanks for giving this some thought. On first pass I'd make these
        observations:

        - ploticus generates symbols using its standard line drawing and/or
        polygon fill operations

        - the standard drawing operations basically have no information about
        what "device" the graphic is being rendered on, eg. where GD pixels are.
        Ploticus supports a number of output "devices", some raster and others
        vector.

        - it's likely that antialiasing wouldn't be an ideal solution for
        scatterplot symbols

        - a possible solution that comes to mind would be to implement an
        alternate way to render data point symbols that would work at the device
        pixel level.. this would be available in addition to the current method.
        This would avoid having to meddle with the current stable code and doesn't
        seem like it would be too hard. Perhaps it would be available only w/ GD,
        at least at first.

        - also note that ploticus has always supported the use of small png images
        as plot symbols.. see the description for "imgfile" here:
        http://ploticus.sourceforge.net/doc/symboldetails.html ... These would be
        immune from rounding effects but probably not ideal (I believe that there
        are issues when data points are overlapping or close together & png
        doesn't support transparency). I haven't tried this lately.


        ?

        Steve


        On Mon, 3 Oct 2005, Andrew Schulman wrote:

        > Back in July, I reported a problem with corrupted symbols in scatterplots on
        > this list (http://groups.yahoo.com/group/ploticus/message/1581). An
        > example can be seen in, for example, the y=7 and y=7.4 rows at
        > http://home.comcast.net/~andrex/bugz/ploticus.png (created by the script at
        > http://home.comcast.net/~andrex/bugz/ploticus.plo). Those are rows of
        > diamonds that got corrupted in the plot.
        >
        > Steve answered my query as follows:
        >
        > > Ploticus generates vector graphics, which must be rasterized to get them
        > > into PNG/GIF. Then when PNG/GIF are rendered by the browser there may be
        > > another round of rasterization that might not sync with the first round.
        >
        > OK. The remainder of the thread concerned using GD's new anti-aliasing
        > facilities to mitigate the aliasing.
        >
        > I still have the corrupted symbols problem, and ploticus is so good in every
        > other respect that I'd really like to see it get fixed. Here are my
        > thoughts, please tell me what you think.
        >
        > First, this isn't a browser effect. It persists in any viewer at any
        > magnification. So it's a ploticus and/or libgd problem.
        >
        > Second, the problem doesn't seem to be in GD. I don't know much about GD;
        > all I've done is to browse the documentation online. But AFAICT, GD deals
        > only in pixels. All calls to GD functions pass arguments in pixel units.
        > Therefore, the pixelization or aliasing is happening in ploticus. In my
        > mind this is good news, because it means the problem must be solvable in
        > ploticus.
        >
        > Third, anti-aliasing isn't a solution. AA just amounts (as I understand
        > it anyway; please correct me if I'm wrong in the context of GD) to blurring
        > the plot lines in order to soften jagged edges. This is, IMO, undesirable
        > in most cases, since it reduces the sharpness of the plot; and it doesn't
        > solve the underlying problem. Aliasing in ploticus is often bad enough to
        > make the interior color of a symbol spill outside the symbol boundary. You
        > can see this, for example, in every diamond in the y=7 row in the plot
        > cited above (expand the row and look at the lower right edge of each
        > diamond). AA may partly obscure this effect, but it can't solve it. (It
        > may be a good idea for shapes other than vertical, horizontal, and diagonal
        > lines, however, since it can reduce jaggedness.)
        >
        > Here's how I see the problem and its solution. In order to draw, say,
        > a diamond, ploticus uses the following algorithm:
        >
        > (0) Start with coordinates (x,y) of the diamond's center, and a radius r.
        >
        > (1) Compute offsets from the center to the vertices in a standard (r=1)
        > diamond, e.g. (1,0), (0,1), (-1,0), and (0,-1).
        >
        > (2) Compute the vertex coordinates: e.g. for the right vertex they're
        > (x,y) + r * (0,1) = (x, y+r).
        >
        > (3) Convert the vertex coordinates from plot units to pixel units.
        >
        > (4) Call GD to draw lines between the vertices.
        >
        > This algorithm is implemented in PLG_mark() in mark.c. But the conversion
        > to pixel units happens at a lower level-- PLG_mark calls Emov() and Epath()
        > to plot the points and lines, and these eventually call PLG_xsca() and
        > PLG_ysca() in winscale.c, which multiply x and y by global scaling factors
        > to convert to pixel units.
        >
        > The aliasing, or rounding error, occurs in step 3. And the problem with
        > this algorithm is that the vertex coordinates are all computed in plot
        > units, and then independently rasterized, so the rounding error on each
        > coordinate can go in a separate direction. This is what causes the diamond
        > shape to distort in a random way.
        >
        > The solution is simple in principle: convert the center coordinates and
        > radius to pixel units _before_ computing the vertex coordinates. That is,
        > remove step 3 and add
        >
        > (1.5) Convert x, y, and r from plot units to pixel units.
        >
        > The distortion problem will be solved, because the rounding error will
        > happen just one time on r, and then be applied uniformly in finding all of
        > the vertices. The shape will be a perfect diamond (or square or whatever).
        > (This is "less accurate" for the individual vertices, since they can't
        > independently find their closest pixels. But with plot symbols the
        > accuracy of the vertices isn't the point; drawing a clean, recognizable
        > shape is the point.)
        >
        > In practice this would take some work to implement, because as I said above,
        > the conversion to pixel units currently happens at a low level in
        > ploticus-- just before the GD plotting routines are called. This approach
        > simplifies the higher-level code, which doesn't have to worry about any unit
        > conversions. In order to perform the pixel conversion at a higher level,
        > points will now have to implicitly carry units with them, and those units
        > will have to be passed down through all of the drawing routines. So for
        > example in PLG_mark(), the calls to Emov() and Epath will have to include a
        > new "already in pixel units" flag, to tell the lower-level routines not to
        > convert them again.
        >
        > Specifying the symbol radius in pixels would have the added benefit of
        > providing a natural sequence of symbol sizes for users to choose from.
        >
        > If it would be useful, I could try to create a proof-of-concept patch. I'm
        > not sure how long it would take, but the ploticus code seems to be pretty
        > clearly laid out, so it might not be too bad.
        >
        > Andrew.
        >
        >
        >
        >
        >
        >
        > Yahoo! Groups Links
        >
        >
        >
        >
        >
        >
        >
        >


        Stephen C. Grubb x-6633
        Scientific Software Engineer, The Jackson Laboratory
        600 Main Street Bar Harbor, Maine 04609 USA
      • dagoldman
        Hi Andrew, Could you clarify what you mean by corrupted ? In other words, what difference in appearance do you want with the symbols on the y=7 and y=7.4
        Message 3 of 12 , Oct 3 8:48 AM
          Hi Andrew,

          Could you clarify what you mean by "corrupted"? In
          other words, what difference in appearance do you want
          with the symbols on the y=7 and y=7.4 rows? I apologize
          if this has already been explained.

          Thanks,
          Daniel

          --- In ploticus@yahoogroups.com, Andrew Schulman <andrex@a...> wrote:
          > Back in July, I reported a problem with corrupted symbols in
          scatterplots on
          > this list (http://groups.yahoo.com/group/ploticus/message/1581). An
          > example can be seen in, for example, the y=7 and y=7.4 rows at
          > http://home.comcast.net/~andrex/bugz/ploticus.png (created by the
          script at
          > http://home.comcast.net/~andrex/bugz/ploticus.plo). Those are rows
          of
          > diamonds that got corrupted in the plot.
          >
          > Steve answered my query as follows:
          >
          > > Ploticus generates vector graphics, which must be rasterized to
          get them
          > > into PNG/GIF. Then when PNG/GIF are rendered by the browser
          there may be
          > > another round of rasterization that might not sync with the first
          round.
          >
          > OK. The remainder of the thread concerned using GD's new anti-
          aliasing
          > facilities to mitigate the aliasing.
          >
          > I still have the corrupted symbols problem, and ploticus is so good
          in every
          > other respect that I'd really like to see it get fixed. Here are my
          > thoughts, please tell me what you think.
          >
          > First, this isn't a browser effect. It persists in any viewer at
          any
          > magnification. So it's a ploticus and/or libgd problem.
          >
          > Second, the problem doesn't seem to be in GD. I don't know much
          about GD;
          > all I've done is to browse the documentation online. But AFAICT,
          GD deals
          > only in pixels. All calls to GD functions pass arguments in pixel
          units.
          > Therefore, the pixelization or aliasing is happening in ploticus.
          In my
          > mind this is good news, because it means the problem must be
          solvable in
          > ploticus.
          >
          > Third, anti-aliasing isn't a solution. AA just amounts (as I
          understand
          > it anyway; please correct me if I'm wrong in the context of GD) to
          blurring
          > the plot lines in order to soften jagged edges. This is, IMO,
          undesirable
          > in most cases, since it reduces the sharpness of the plot; and it
          doesn't
          > solve the underlying problem. Aliasing in ploticus is often bad
          enough to
          > make the interior color of a symbol spill outside the symbol
          boundary. You
          > can see this, for example, in every diamond in the y=7 row in the
          plot
          > cited above (expand the row and look at the lower right edge of each
          > diamond). AA may partly obscure this effect, but it can't solve
          it. (It
          > may be a good idea for shapes other than vertical, horizontal, and
          diagonal
          > lines, however, since it can reduce jaggedness.)
          >
          > Here's how I see the problem and its solution. In order to draw,
          say,
          > a diamond, ploticus uses the following algorithm:
          >
          > (0) Start with coordinates (x,y) of the diamond's center, and a
          radius r.
          >
          > (1) Compute offsets from the center to the vertices in a standard
          (r=1)
          > diamond, e.g. (1,0), (0,1), (-1,0), and (0,-1).
          >
          > (2) Compute the vertex coordinates: e.g. for the right vertex
          they're
          > (x,y) + r * (0,1) = (x, y+r).
          >
          > (3) Convert the vertex coordinates from plot units to pixel units.
          >
          > (4) Call GD to draw lines between the vertices.
          >
          > This algorithm is implemented in PLG_mark() in mark.c. But the
          conversion
          > to pixel units happens at a lower level-- PLG_mark calls Emov() and
          Epath()
          > to plot the points and lines, and these eventually call PLG_xsca()
          and
          > PLG_ysca() in winscale.c, which multiply x and y by global scaling
          factors
          > to convert to pixel units.
          >
          > The aliasing, or rounding error, occurs in step 3. And the problem
          with
          > this algorithm is that the vertex coordinates are all computed in
          plot
          > units, and then independently rasterized, so the rounding error on
          each
          > coordinate can go in a separate direction. This is what causes the
          diamond
          > shape to distort in a random way.
          >
          > The solution is simple in principle: convert the center
          coordinates and
          > radius to pixel units _before_ computing the vertex coordinates.
          That is,
          > remove step 3 and add
          >
          > (1.5) Convert x, y, and r from plot units to pixel units.
          >
          > The distortion problem will be solved, because the rounding error
          will
          > happen just one time on r, and then be applied uniformly in finding
          all of
          > the vertices. The shape will be a perfect diamond (or square or
          whatever).
          > (This is "less accurate" for the individual vertices, since they
          can't
          > independently find their closest pixels. But with plot symbols the
          > accuracy of the vertices isn't the point; drawing a clean,
          recognizable
          > shape is the point.)
          >
          > In practice this would take some work to implement, because as I
          said above,
          > the conversion to pixel units currently happens at a low level in
          > ploticus-- just before the GD plotting routines are called. This
          approach
          > simplifies the higher-level code, which doesn't have to worry about
          any unit
          > conversions. In order to perform the pixel conversion at a higher
          level,
          > points will now have to implicitly carry units with them, and those
          units
          > will have to be passed down through all of the drawing routines.
          So for
          > example in PLG_mark(), the calls to Emov() and Epath will have to
          include a
          > new "already in pixel units" flag, to tell the lower-level routines
          not to
          > convert them again.
          >
          > Specifying the symbol radius in pixels would have the added benefit
          of
          > providing a natural sequence of symbol sizes for users to choose
          from.
          >
          > If it would be useful, I could try to create a proof-of-concept
          patch. I'm
          > not sure how long it would take, but the ploticus code seems to be
          pretty
          > clearly laid out, so it might not be too bad.
          >
          > Andrew.
        • Andrew Schulman
          ... No problem. Grab the figure at http://home.comcast.net/~andrex/bugz/ploticus.png , and use your favorite image editor to zoom in on it to about 4x. First
          Message 4 of 12 , Oct 3 10:09 AM
            > Could you clarify what you mean by "corrupted"? In
            > other words, what difference in appearance do you want
            > with the symbols on the y=7 and y=7.4 rows? I apologize
            > if this has already been explained.

            No problem. Grab the figure at
            http://home.comcast.net/~andrex/bugz/ploticus.png , and use your favorite
            image editor to zoom in on it to about 4x.

            First look at the diamonds on e.g. the y=6.9 and y=7.1 rows. These are
            perfectly shaped diamonds, with blue interiors and a 1-pixel wide border.

            Now compare the diamonds on the y=7.0 and y=7.2 rows. The black borders are
            misshapen, and some of the blue interior color has spilled outside of the
            diamonds.

            Back at 1x, the deformity may not be immediately obvious, but it does start to
            show up in other places, some more obvious than here. And now that I know
            it's there, I find it pretty distracting.

            There's another example right in the ploticus docs: at
            http://ploticus.sourceforge.net/doc/symboldetails.html, go to the
            "Illustration" table at the bottom, and look at the symbols in the circle,
            pentagon, and diamond rows. These are-- how shall I say it?-- embarassing.
            When I was first looking at ploticus, I saw that table and thought, gee,
            ploticus seems pretty good, but is that supposed to be a circle?

            It turns out that ploticus _is_ really good, which is why I'd like to see this
            one problem get corrected.

            A.
          • Andrew Schulman
            ... Right. ... OK ... I agree, this sounds like a promising approach and could start just w/ GD (which is all I care about at present :). Based on just my one
            Message 5 of 12 , Oct 3 10:27 AM
              > - ploticus generates symbols using its standard line drawing and/or
              > polygon fill operations
              >
              > - the standard drawing operations basically have no information about
              > what "device" the graphic is being rendered on, eg. where GD pixels are.
              > Ploticus supports a number of output "devices", some raster and others
              > vector.

              Right.

              > - it's likely that antialiasing wouldn't be an ideal solution for
              > scatterplot symbols

              OK

              > - a possible solution that comes to mind would be to implement an
              > alternate way to render data point symbols that would work at the device
              > pixel level.. this would be available in addition to the current method.
              > This would avoid having to meddle with the current stable code and doesn't
              > seem like it would be too hard. Perhaps it would be available only w/ GD,
              > at least at first.

              I agree, this sounds like a promising approach and could start just w/ GD
              (which is all I care about at present :). Based on just my one perusal of the
              ploticus code, it seems that most of the work could be done by adding an
              alternate set of definitions of the E* macros? I'll have to think about
              that...

              > - also note that ploticus has always supported the use of small png images
              > as plot symbols.. see the description for "imgfile" here:
              > http://ploticus.sourceforge.net/doc/symboldetails.html ... These would be
              > immune from rounding effects but probably not ideal (I believe that there
              > are issues when data points are overlapping or close together & png
              > doesn't support transparency). I haven't tried this lately.

              Right, OK. Possibly useful, although a separate PNG would have to be created
              for each symbol.
            • dagoldman
              You re right, a lot of them are corrupted, to use your term. I agree it would be good to fix, if not too painful to do. I m sure you noticed that every diamond
              Message 6 of 12 , Oct 3 10:22 PM
                You're right, a lot of them are corrupted, to use your term.
                I agree it would be good to fix, if not too painful to do.

                I'm sure you noticed that every diamond between the horizontal
                lines is perfect, all the diamonds on the horizontal lines are
                corrupted. Does your suggested correction, which it would take
                me a while to figure out, account for that observation?

                Daniel

                --- In ploticus@yahoogroups.com, Andrew Schulman <andrex@a...> wrote:
                > > Could you clarify what you mean by "corrupted"? In
                > > other words, what difference in appearance do you want
                > > with the symbols on the y=7 and y=7.4 rows? I apologize
                > > if this has already been explained.
                >
                > No problem. Grab the figure at
                > http://home.comcast.net/~andrex/bugz/ploticus.png , and use your
                favorite
                > image editor to zoom in on it to about 4x.
                >
                > First look at the diamonds on e.g. the y=6.9 and y=7.1 rows. These
                are
                > perfectly shaped diamonds, with blue interiors and a 1-pixel wide
                border.
                >
                > Now compare the diamonds on the y=7.0 and y=7.2 rows. The black
                borders are
                > misshapen, and some of the blue interior color has spilled outside
                of the
                > diamonds.
                >
                > Back at 1x, the deformity may not be immediately obvious, but it
                does start to
                > show up in other places, some more obvious than here. And now that
                I know
                > it's there, I find it pretty distracting.
                >
                > There's another example right in the ploticus docs: at
                > http://ploticus.sourceforge.net/doc/symboldetails.html, go to the
                > "Illustration" table at the bottom, and look at the symbols in the
                circle,
                > pentagon, and diamond rows. These are-- how shall I say it?--
                embarassing.
                > When I was first looking at ploticus, I saw that table and thought,
                gee,
                > ploticus seems pretty good, but is that supposed to be a circle?
                >
                > It turns out that ploticus _is_ really good, which is why I'd like
                to see this
                > one problem get corrected.
                >
                > A.
              • Andrew Schulman
                ... Yes, it does. My explanation for the source of the problem is that whether a symbol is drawn correctly depends on your luck with rounding errors as the
                Message 7 of 12 , Oct 4 12:11 AM
                  > I'm sure you noticed that every diamond between the horizontal
                  > lines is perfect, all the diamonds on the horizontal lines are
                  > corrupted. Does your suggested correction, which it would take
                  > me a while to figure out, account for that observation?

                  Yes, it does. My explanation for the source of the problem is that whether
                  a symbol is drawn correctly depends on your luck with rounding errors as
                  the symbol vertices are separately interpolated or rasterized onto the
                  pixel grid. It's not surprising that all of the symbols in a common y row
                  will come out looking the same way, since their vertices have the same y
                  coorindates. This means that the rounding errors (at least in the y
                  direction) will affect them all in the same way.

                  My proposed solution is to do the rounding to the pixel grid earlier in the
                  calculation, so that whatever the error, it's at least applied consistently
                  across the whole symbol. This will guarantee consistent shapes.

                  Now to make it work...
                • Stephen C. Grubb
                  Daniel, here s a tentative plan for a solution for the lop-sided data point symbols problem. grgd.c and x11.c (the two raster-type devices that ploticus
                  Message 8 of 12 , Oct 6 7:34 AM
                    Daniel,

                    here's a tentative plan for a solution for the lop-sided data point
                    symbols problem.

                    grgd.c and x11.c (the two raster-type devices that ploticus supports)
                    would each have a new function for rendering a pixel-based data point
                    symbol at a specific location.. they would share a low level function that
                    would render the data point symbol by using templates to color specific
                    pixels centered around a data point.

                    what I'll need to come up with are the templates. There will need to be a
                    template for the various data point shapes, each in several sizes. These
                    would be defined in a .h file as program data. For instance, for a small
                    square:

                    <pre>

                    ooooooo
                    o*****o
                    o*****o
                    o**x**o
                    o*****o
                    o*****o
                    ooooooo

                    </pre>

                    Each character will control one pixel. x indicates the exact center. Two
                    different characters (o and * in this case) are used in case we want a
                    solid colored symbol or an outlined symbol.

                    I can come up with the templates for squares, diamonds, and triangles
                    easily enough. Circles would take a little more effort.. not that big a
                    deal but if anyone can come up with good looking circle templates in
                    various sizes up to ~20 characters in diameter that would be a help.
                    Maybe there's some ascii art on the web somewhere that could be used...

                    should be able to get this into the next release. Exactly how this option
                    will be invoked by the user is still to be decided.. probably the more
                    automatic the better.


                    Steve


                    On Mon, 3 Oct 2005, Andrew Schulman wrote:

                    > Back in July, I reported a problem with corrupted symbols in scatterplots on
                    > this list (http://groups.yahoo.com/group/ploticus/message/1581). An
                    > example can be seen in, for example, the y=7 and y=7.4 rows at
                    > http://home.comcast.net/~andrex/bugz/ploticus.png (created by the script at
                    > http://home.comcast.net/~andrex/bugz/ploticus.plo). Those are rows of
                    > diamonds that got corrupted in the plot.
                    >


                    Stephen C. Grubb x-6633
                    Scientific Software Engineer, The Jackson Laboratory
                    600 Main Street Bar Harbor, Maine 04609 USA
                  • Andrew Schulman
                    ... Sounds good. ... It seems to me that the algorithm in mark.c is already pretty good for this: /* (1=up-tri 2=down-tri 3=diam 4=square 5=pent 6=circ
                    Message 9 of 12 , Oct 6 1:15 PM
                      > here's a tentative plan for a solution for the lop-sided data point
                      > symbols problem.
                      >
                      > grgd.c and x11.c (the two raster-type devices that ploticus supports)
                      > would each have a new function for rendering a pixel-based data point
                      > symbol at a specific location.. they would share a low level function that
                      > would render the data point symbol by using templates to color specific
                      > pixels centered around a data point.

                      Sounds good.

                      > what I'll need to come up with are the templates. There will need to be a
                      > template for the various data point shapes, each in several sizes. These
                      > would be defined in a .h file as program data. For instance, for a small
                      > square:
                      >
                      > <pre>
                      >
                      > ooooooo
                      > o*****o
                      > o*****o
                      > o**x**o
                      > o*****o
                      > o*****o
                      > ooooooo
                      >
                      > </pre>
                      >
                      > Each character will control one pixel. x indicates the exact center. Two
                      > different characters (o and * in this case) are used in case we want a
                      > solid colored symbol or an outlined symbol.
                      >
                      > I can come up with the templates for squares, diamonds, and triangles
                      > easily enough. Circles would take a little more effort.. not that big a
                      > deal but if anyone can come up with good looking circle templates in
                      > various sizes up to ~20 characters in diameter that would be a help.
                      > Maybe there's some ascii art on the web somewhere that could be used...

                      It seems to me that the algorithm in mark.c is already pretty good for this:

                      /* (1=up-tri 2=down-tri 3=diam 4=square 5=pent 6=circ 7=right-tri 8=left-tri
                      9=nice-circle) */
                      static int nc[] = { 3, 3, 4, 4, 5, 12, 3, 3, 20 }; /* number of
                      corners (constant) */
                      static int nt[] = { 90,270, 0, 45, 90, 90, 0, 180, 90 }; /* location
                      (in degrees) of first corner (constant) */
                      static double h[24][2]; /* the offsets */

                      [...]

                      theta = 360.0 / (double)nc[inc];
                      /* get offsets */
                      g = nt[inc];
                      for( i = 0; i < nc[inc]; i++ ) {
                      h[i][0] = r * cos( g * TORAD );
                      h[i][1] = r * sin( g * TORAD );
                      g += theta;
                      }

                      [...]

                      /* draw perimeter */
                      else {
                      Emov( x+h[0][0], y+h[0][1] );
                      for( i = 1; i < nc[inc]; i++ ) Elin( x+h[i][0], y+h[i][1] );
                      Elin( x+h[0][0], y+h[0][1] ); /* close to starting point.. */
                      Elin( x+h[1][0], y+h[1][1] ); /* and do one more so last corner is
                      done right.. */
                      }

                      If this is implemented with x, y, and r expressed in pixel units, the result
                      should be quite good. Rounding errors in h[][] will be symmetric around the
                      origin, so at least the shapes will be regular. There might still be some
                      jaggedness, for example in the circle, which could then be a good candidate
                      for antialiasing. That algorithm could be used to develop static symbol
                      templates as you suggest, or to create them on the fly as is done now.

                      > should be able to get this into the next release. Exactly how this option
                      > will be invoked by the user is still to be decided.. probably the more
                      > automatic the better.

                      Excellent! It seems to me that this option should just be the default for all
                      raster devices, or at least for GD to start. I can't think of any reason that
                      a user wouldn't want to use the method that plots regular symbols.
                    • dagoldman
                      I took the code snippets and expanded them into a program for making the templates Steve mentioned. It makes a whole bunch of templates. Don t worry about the
                      Message 10 of 12 , Oct 8 5:24 PM
                        I took the code snippets and expanded them into a
                        program for making the templates Steve mentioned.

                        It makes a whole bunch of templates. Don't worry about
                        the ones with gaps. The program loops multiple times with
                        a varying stringency factor (segDelta) for when to make
                        a segment point. The ones at the end don't have gaps
                        (segDelta = 0.51). I erred on the side of including
                        too many templates, to give more choices.

                        code - http://www.ehdp.com/out/pl/pl-temps.c
                        output - http://www.ehdp.com/out/pl/10-8-05.txt

                        I think the templates hard-coded into a header file,
                        as Steve suggested. The irregular ones might need
                        some hand editing, to take out some of the border
                        points to make look cleaner, or add some border
                        points to the ones with gaps.

                        Let me know if need something different.

                        Daniel

                        --- In ploticus@yahoogroups.com, Andrew Schulman <andrex@a...> wrote:
                        >
                        > > here's a tentative plan for a solution for the lop-sided data
                        point
                        > > symbols problem.
                        > >
                        > > grgd.c and x11.c (the two raster-type devices that ploticus
                        supports)
                        > > would each have a new function for rendering a pixel-based data
                        point
                        > > symbol at a specific location.. they would share a low level
                        function that
                        > > would render the data point symbol by using templates to color
                        specific
                        > > pixels centered around a data point.
                        >
                        > Sounds good.
                        >
                        > > what I'll need to come up with are the templates. There will
                        need to be a
                        > > template for the various data point shapes, each in several
                        sizes. These
                        > > would be defined in a .h file as program data. For instance, for
                        a small
                        > > square:
                        > >
                        > > <pre>
                        > >
                        > > ooooooo
                        > > o*****o
                        > > o*****o
                        > > o**x**o
                        > > o*****o
                        > > o*****o
                        > > ooooooo
                        > >
                        > > </pre>
                        > >
                        > > Each character will control one pixel. x indicates the exact
                        center. Two
                        > > different characters (o and * in this case) are used in case we
                        want a
                        > > solid colored symbol or an outlined symbol.
                        > >
                        > > I can come up with the templates for squares, diamonds, and
                        triangles
                        > > easily enough. Circles would take a little more effort.. not
                        that big a
                        > > deal but if anyone can come up with good looking circle templates
                        in
                        > > various sizes up to ~20 characters in diameter that would be a
                        help.
                        > > Maybe there's some ascii art on the web somewhere that could be
                        used...
                        >
                        > It seems to me that the algorithm in mark.c is already pretty good
                        for this:
                        >
                        > /* (1=up-tri 2=down-tri 3=diam 4=square 5=pent 6=circ 7=right-tri
                        8=left-tri
                        > 9=nice-circle) */
                        > static int nc[] = { 3, 3, 4, 4, 5, 12, 3, 3, 20 }; /*
                        number of
                        > corners (constant) */
                        > static int nt[] = { 90,270, 0, 45, 90, 90, 0, 180, 90 }; /*
                        location
                        > (in degrees) of first corner (constant) */
                        > static double h[24][2]; /* the offsets */
                        >
                        > [...]
                        >
                        > theta = 360.0 / (double)nc[inc];
                        > /* get offsets */
                        > g = nt[inc];
                        > for( i = 0; i < nc[inc]; i++ ) {
                        > h[i][0] = r * cos( g * TORAD );
                        > h[i][1] = r * sin( g * TORAD );
                        > g += theta;
                        > }
                        >
                        > [...]
                        >
                        > /* draw perimeter */
                        > else {
                        > Emov( x+h[0][0], y+h[0][1] );
                        > for( i = 1; i < nc[inc]; i++ ) Elin( x+h[i][0], y+h[i][1] );
                        > Elin( x+h[0][0], y+h[0][1] ); /* close to starting point.. */
                        > Elin( x+h[1][0], y+h[1][1] ); /* and do one more so last
                        corner is
                        > done right.. */
                        > }
                        >
                        > If this is implemented with x, y, and r expressed in pixel units,
                        the result
                        > should be quite good. Rounding errors in h[][] will be symmetric
                        around the
                        > origin, so at least the shapes will be regular. There might still
                        be some
                        > jaggedness, for example in the circle, which could then be a good
                        candidate
                        > for antialiasing. That algorithm could be used to develop static
                        symbol
                        > templates as you suggest, or to create them on the fly as is done
                        now.
                        >
                        > > should be able to get this into the next release. Exactly how
                        this option
                        > > will be invoked by the user is still to be decided.. probably the
                        more
                        > > automatic the better.
                        >
                        > Excellent! It seems to me that this option should just be the
                        default for all
                        > raster devices, or at least for GD to start. I can't think of any
                        reason that
                        > a user wouldn't want to use the method that plots regular symbols.
                        >
                      • Stephen C. Grubb
                        Daniel, thanks, this should be enough to get started with Steve ... Stephen C. Grubb x-6633 Scientific Software Engineer, The Jackson
                        Message 11 of 12 , Oct 10 6:55 AM
                          Daniel,
                          thanks, this should be enough to get started with

                          Steve

                          On Sun, 9 Oct 2005, dagoldman wrote:

                          > I took the code snippets and expanded them into a
                          > program for making the templates Steve mentioned.
                          >
                          > It makes a whole bunch of templates. Don't worry about
                          > the ones with gaps. The program loops multiple times with
                          > a varying stringency factor (segDelta) for when to make
                          > a segment point. The ones at the end don't have gaps
                          > (segDelta = 0.51). I erred on the side of including
                          > too many templates, to give more choices.
                          >
                          > code - http://www.ehdp.com/out/pl/pl-temps.c
                          > output - http://www.ehdp.com/out/pl/10-8-05.txt
                          >
                          > I think the templates hard-coded into a header file,
                          > as Steve suggested. The irregular ones might need
                          > some hand editing, to take out some of the border
                          > points to make look cleaner, or add some border
                          > points to the ones with gaps.
                          >
                          > Let me know if need something different.
                          >
                          > Daniel
                          >
                          > --- In ploticus@yahoogroups.com, Andrew Schulman <andrex@a...> wrote:
                          > >
                          > > > here's a tentative plan for a solution for the lop-sided data
                          > point
                          > > > symbols problem.
                          > > >
                          > > > grgd.c and x11.c (the two raster-type devices that ploticus
                          > supports)
                          > > > would each have a new function for rendering a pixel-based data
                          > point
                          > > > symbol at a specific location.. they would share a low level
                          > function that
                          > > > would render the data point symbol by using templates to color
                          > specific
                          > > > pixels centered around a data point.
                          > >
                          > > Sounds good.
                          > >
                          > > > what I'll need to come up with are the templates. There will
                          > need to be a
                          > > > template for the various data point shapes, each in several
                          > sizes. These
                          > > > would be defined in a .h file as program data. For instance, for
                          > a small
                          > > > square:
                          > > >
                          > > > <pre>
                          > > >
                          > > > ooooooo
                          > > > o*****o
                          > > > o*****o
                          > > > o**x**o
                          > > > o*****o
                          > > > o*****o
                          > > > ooooooo
                          > > >
                          > > > </pre>
                          > > >
                          > > > Each character will control one pixel. x indicates the exact
                          > center. Two
                          > > > different characters (o and * in this case) are used in case we
                          > want a
                          > > > solid colored symbol or an outlined symbol.
                          > > >
                          > > > I can come up with the templates for squares, diamonds, and
                          > triangles
                          > > > easily enough. Circles would take a little more effort.. not
                          > that big a
                          > > > deal but if anyone can come up with good looking circle templates
                          > in
                          > > > various sizes up to ~20 characters in diameter that would be a
                          > help.
                          > > > Maybe there's some ascii art on the web somewhere that could be
                          > used...
                          > >
                          > > It seems to me that the algorithm in mark.c is already pretty good
                          > for this:
                          > >
                          > > /* (1=up-tri 2=down-tri 3=diam 4=square 5=pent 6=circ 7=right-tri
                          > 8=left-tri
                          > > 9=nice-circle) */
                          > > static int nc[] = { 3, 3, 4, 4, 5, 12, 3, 3, 20 }; /*
                          > number of
                          > > corners (constant) */
                          > > static int nt[] = { 90,270, 0, 45, 90, 90, 0, 180, 90 }; /*
                          > location
                          > > (in degrees) of first corner (constant) */
                          > > static double h[24][2]; /* the offsets */
                          > >
                          > > [...]
                          > >
                          > > theta = 360.0 / (double)nc[inc];
                          > > /* get offsets */
                          > > g = nt[inc];
                          > > for( i = 0; i < nc[inc]; i++ ) {
                          > > h[i][0] = r * cos( g * TORAD );
                          > > h[i][1] = r * sin( g * TORAD );
                          > > g += theta;
                          > > }
                          > >
                          > > [...]
                          > >
                          > > /* draw perimeter */
                          > > else {
                          > > Emov( x+h[0][0], y+h[0][1] );
                          > > for( i = 1; i < nc[inc]; i++ ) Elin( x+h[i][0], y+h[i][1] );
                          > > Elin( x+h[0][0], y+h[0][1] ); /* close to starting point.. */
                          > > Elin( x+h[1][0], y+h[1][1] ); /* and do one more so last
                          > corner is
                          > > done right.. */
                          > > }
                          > >
                          > > If this is implemented with x, y, and r expressed in pixel units,
                          > the result
                          > > should be quite good. Rounding errors in h[][] will be symmetric
                          > around the
                          > > origin, so at least the shapes will be regular. There might still
                          > be some
                          > > jaggedness, for example in the circle, which could then be a good
                          > candidate
                          > > for antialiasing. That algorithm could be used to develop static
                          > symbol
                          > > templates as you suggest, or to create them on the fly as is done
                          > now.
                          > >
                          > > > should be able to get this into the next release. Exactly how
                          > this option
                          > > > will be invoked by the user is still to be decided.. probably the
                          > more
                          > > > automatic the better.
                          > >
                          > > Excellent! It seems to me that this option should just be the
                          > default for all
                          > > raster devices, or at least for GD to start. I can't think of any
                          > reason that
                          > > a user wouldn't want to use the method that plots regular symbols.
                          > >
                          >
                          >
                          >
                          >
                          >
                          >
                          >
                          >
                          > Yahoo! Groups Links
                          >
                          >
                          >
                          >
                          >
                          >
                          >
                          >
                          >


                          Stephen C. Grubb x-6633
                          Scientific Software Engineer, The Jackson Laboratory
                          600 Main Street Bar Harbor, Maine 04609 USA
                        • dagoldman
                          If you want me to fiddle further, let me know. By the way, Andrew was right that rounding errors were involved. There were tiny errors in the internal
                          Message 12 of 12 , Oct 10 11:19 AM
                            If you want me to fiddle further, let me know.

                            By the way, Andrew was right that rounding errors
                            were involved. There were tiny errors in the internal
                            representation of floating point numbers such as 0.5,
                            totally independent of gd or ploticus. For example:

                            0.49999999 x 3 rounds to 1
                            0.50000001 x 3 rounds to 2

                            The result was the irregularities we noticed.

                            I wrote some separate rounding functions to take care
                            of this. Both of the above get rounded to 0.5 exactly.
                            Maybe these kind of rounding problems might crop up
                            elsewhere in ploticus, in case useful.

                            Daniel

                            --- In ploticus@yahoogroups.com, "Stephen C. Grubb" <scg@j...> wrote:
                            >
                            >
                            > Daniel,
                            > thanks, this should be enough to get started with
                            >
                            > Steve
                            >
                            > On Sun, 9 Oct 2005, dagoldman wrote:
                            >
                            > > I took the code snippets and expanded them into a
                            > > program for making the templates Steve mentioned.
                            > >
                            > > It makes a whole bunch of templates. Don't worry about
                            > > the ones with gaps. The program loops multiple times with
                            > > a varying stringency factor (segDelta) for when to make
                            > > a segment point. The ones at the end don't have gaps
                            > > (segDelta = 0.51). I erred on the side of including
                            > > too many templates, to give more choices.
                            > >
                            > > code - http://www.ehdp.com/out/pl/pl-temps.c
                            > > output - http://www.ehdp.com/out/pl/10-8-05.txt
                            > >
                            > > I think the templates hard-coded into a header file,
                            > > as Steve suggested. The irregular ones might need
                            > > some hand editing, to take out some of the border
                            > > points to make look cleaner, or add some border
                            > > points to the ones with gaps.
                            > >
                            > > Let me know if need something different.
                            > >
                            > > Daniel
                            > >
                            > > --- In ploticus@yahoogroups.com, Andrew Schulman <andrex@a...>
                            wrote:
                            > > >
                            > > > > here's a tentative plan for a solution for the lop-sided data
                            > > point
                            > > > > symbols problem.
                            > > > >
                            > > > > grgd.c and x11.c (the two raster-type devices that ploticus
                            > > supports)
                            > > > > would each have a new function for rendering a pixel-based
                            data
                            > > point
                            > > > > symbol at a specific location.. they would share a low level
                            > > function that
                            > > > > would render the data point symbol by using templates to color
                            > > specific
                            > > > > pixels centered around a data point.
                            > > >
                            > > > Sounds good.
                            > > >
                            > > > > what I'll need to come up with are the templates. There will
                            > > need to be a
                            > > > > template for the various data point shapes, each in several
                            > > sizes. These
                            > > > > would be defined in a .h file as program data. For instance,
                            for
                            > > a small
                            > > > > square:
                            > > > >
                            > > > > <pre>
                            > > > >
                            > > > > ooooooo
                            > > > > o*****o
                            > > > > o*****o
                            > > > > o**x**o
                            > > > > o*****o
                            > > > > o*****o
                            > > > > ooooooo
                            > > > >
                            > > > > </pre>
                            > > > >
                            > > > > Each character will control one pixel. x indicates the exact
                            > > center. Two
                            > > > > different characters (o and * in this case) are used in case
                            we
                            > > want a
                            > > > > solid colored symbol or an outlined symbol.
                            > > > >
                            > > > > I can come up with the templates for squares, diamonds, and
                            > > triangles
                            > > > > easily enough. Circles would take a little more effort.. not
                            > > that big a
                            > > > > deal but if anyone can come up with good looking circle
                            templates
                            > > in
                            > > > > various sizes up to ~20 characters in diameter that would be a
                            > > help.
                            > > > > Maybe there's some ascii art on the web somewhere that could
                            be
                            > > used...
                            > > >
                            > > > It seems to me that the algorithm in mark.c is already pretty
                            good
                            > > for this:
                            > > >
                            > > > /* (1=up-tri 2=down-tri 3=diam 4=square 5=pent 6=circ 7=right-
                            tri
                            > > 8=left-tri
                            > > > 9=nice-circle) */
                            > > > static int nc[] = { 3, 3, 4, 4, 5, 12, 3, 3, 20 };
                            /*
                            > > number of
                            > > > corners (constant) */
                            > > > static int nt[] = { 90,270, 0, 45, 90, 90, 0, 180,
                            90 }; /*
                            > > location
                            > > > (in degrees) of first corner (constant) */
                            > > > static double h[24][2]; /* the offsets */
                            > > >
                            > > > [...]
                            > > >
                            > > > theta = 360.0 / (double)nc[inc];
                            > > > /* get offsets */
                            > > > g = nt[inc];
                            > > > for( i = 0; i < nc[inc]; i++ ) {
                            > > > h[i][0] = r * cos( g * TORAD );
                            > > > h[i][1] = r * sin( g * TORAD );
                            > > > g += theta;
                            > > > }
                            > > >
                            > > > [...]
                            > > >
                            > > > /* draw perimeter */
                            > > > else {
                            > > > Emov( x+h[0][0], y+h[0][1] );
                            > > > for( i = 1; i < nc[inc]; i++ ) Elin( x+h[i][0], y+h[i][1] );
                            > > > Elin( x+h[0][0], y+h[0][1] ); /* close to starting point.. */
                            > > > Elin( x+h[1][0], y+h[1][1] ); /* and do one more so last
                            > > corner is
                            > > > done right.. */
                            > > > }
                            > > >
                            > > > If this is implemented with x, y, and r expressed in pixel
                            units,
                            > > the result
                            > > > should be quite good. Rounding errors in h[][] will be
                            symmetric
                            > > around the
                            > > > origin, so at least the shapes will be regular. There might
                            still
                            > > be some
                            > > > jaggedness, for example in the circle, which could then be a
                            good
                            > > candidate
                            > > > for antialiasing. That algorithm could be used to develop
                            static
                            > > symbol
                            > > > templates as you suggest, or to create them on the fly as is
                            done
                            > > now.
                            > > >
                            > > > > should be able to get this into the next release. Exactly how
                            > > this option
                            > > > > will be invoked by the user is still to be decided.. probably
                            the
                            > > more
                            > > > > automatic the better.
                            > > >
                            > > > Excellent! It seems to me that this option should just be the
                            > > default for all
                            > > > raster devices, or at least for GD to start. I can't think of
                            any
                            > > reason that
                            > > > a user wouldn't want to use the method that plots regular
                            symbols.
                            > > >
                            > >
                            > >
                            > >
                            > >
                            > >
                            > >
                            > >
                            > >
                            > > Yahoo! Groups Links
                            > >
                            > >
                            > >
                            > >
                            > >
                            > >
                            > >
                            > >
                            > >
                            >
                            >
                            > Stephen C. Grubb x-6633
                            > Scientific Software Engineer, The Jackson Laboratory
                            > 600 Main Street Bar Harbor, Maine 04609 USA
                            >
                          Your message has been successfully submitted and would be delivered to recipients shortly.