Skip to content
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

Edges of the curve are drawn at an angle #650

Open
a7951396 opened this issue Oct 27, 2022 · 9 comments
Open

Edges of the curve are drawn at an angle #650

a7951396 opened this issue Oct 27, 2022 · 9 comments

Comments

@a7951396
Copy link

a7951396 commented Oct 27, 2022

I entered the data from the svg file for the bezier curve, but the edges of the curve are drawn at an angle, uneven. But in the browser the svg file is drawn with straight ends. And the cairo library also draws straight. But gdi/gdi+ also draws unevenly. Is everything smooth in adobe illustrator too. What could be the problem?
`

    nvgBeginPath(vg);
    float x = 168.f;
    float y = 37.f;
    nvgMoveTo(vg, 168.f, 37.f);
    nvgBezierTo(vg, 0 + x, 35.4f + y, 39.4f + x, 64 + y, 88 + x, 64 + y);
    nvgStrokeColor(vg, nvgRGBA(0, 0, 0, 255));
    nvgStrokeWidth(vg, 32); 
    nvgStroke(vg);`

svg code:
<?xml version="1.0" encoding="utf-8"?> <svg version="1.2" baseProfile="tiny" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 510 512" overflow="visible" xml:space="preserve"> <path fill="none" stroke="#000000" stroke-width="32" stroke-miterlimit="10" d="M168,37c0,35.4,39.4,64,88,64"/> </svg>
2022-10-27_19-29-24

And this is what the curve looks like in the browser:
2022-09-12_23-35-32

@mulle-nat
Copy link
Contributor

Maybe nanovg is correct and the browser isn't ? 🤔 I don't know. If one were to extend the curve a little I assume flatness could be achievable. Maybe the browser isn't even using bezier for curves but something else. I am sure this isn't helping much, but since noone answered so far...

@a7951396
Copy link
Author

I drew this curve in illustrator and all the edges are straight

@mulle-nat
Copy link
Contributor

So maybe complain to Adobe ?

I drew this in nanovg and all the lines are straight:
image

static void   drawStuff( CALayer *layer, CGContext *context)
{
   struct NVGcontext    *vg;

   vg = CGContextGetNVGContext( context);
   nvgBeginPath(vg);

   nvgRect( vg, 100, 100, 300, 300);
   nvgStrokeColor(vg, nvgRGBA(0, 0, 128, 64));
   nvgStrokeWidth(vg, 1);
   nvgStroke(vg);

   nvgBeginPath(vg);
   nvgMoveTo(vg, 100, 100);
   nvgArcTo(vg, 100, 400,
                400, 400,
                300);
   nvgStrokeColor(vg, nvgRGBA(0, 0, 0, 255));
   nvgStrokeWidth(vg, 32);
   nvgMiterLimit( vg, 20);
   nvgStroke(vg);


   nvgBeginPath(vg);
   nvgRect( vg, 450, 100, 300, 300);
   nvgStrokeColor(vg, nvgRGBA(0, 0, 128, 64));
   nvgStrokeWidth(vg, 1);
   nvgStroke(vg);

   nvgBeginPath(vg);
   nvgMoveTo( vg, 750, 100);
   nvgBezierTo( vg, 750, 100 - (0.552 * -300), 450 - (0.552 * -300), 400, 450,400);
   nvgStrokeColor(vg, nvgRGBA(0, 0, 0, 255));
   nvgStrokeWidth(vg, 32);
   nvgMiterLimit( vg, 20);
   nvgStroke(vg);
}

@a7951396
Copy link
Author

draw in adobe

@a7951396
Copy link
Author

I plan to draw in a vector graphics editor and then parse the data from the svg file and draw in opengl

@a7951396
Copy link
Author

I tried using Corel Draw, the edges are also uneven.
2022-10-29_11-03-30

@memononen
Copy link
Owner

I think the problem is that the end cap is aligned to the tessellated line, not the tangent of the curve. I've had to deal with this issue in other projects too when you have really wide lines.

Imagine that the curve above would be approximated with just 4 points, and the end caps were drawn perpendicular to the first and last segment.

The solution is to specifically handle the direction of the first and last edge when drawing open shapes.

@a7951396
Copy link
Author

I’m not sure that I understood something, since I don’t have enough experience in computer graphics, that’s why I’m looking for a ready-made library

@kobalicek
Copy link

Nanovg rendering is incorrect in this case. The caps must be straight, see this Blend2D rendered sample:

image

After applying the x/y translation the input path becomes:

  moveTo(168, 37);
  cubicTo(168, 72.4, 207.4, 101, 256, 101);

The X of moveTo and first cubicTo control point are the same, which means they form a vertical line, which must be used to calculate the angle of start cap. This means that the start cap must be strictly horizontal. The same happens at the end - the last control point and the cubic end point share the same Y coordinate.

If you want to play with that you can drop the following code to Blend2D fiddle ( https://fiddle.blend2d.com ):

BLImage render(const BLContextCreateInfo& cci) {
  BLImage img(500, 140, BL_FORMAT_PRGB32);
  BLContext ctx(img, cci);

  ctx.setFillStyle(BLRgba32(0xFFFFFFFFu));
  ctx.fillAll();

  BLPath p;
  float x = 168.f;
  float y = 37.f;
  p.moveTo(168.f, 37.f);
  p.cubicTo(0 + x, 35.4f + y, 39.4f + x, 64 + y, 88 + x, 64 + y);
  ctx.setStrokeWidth(32);
  ctx.setStrokeStyle(BLRgba32(0xFF000000));
  ctx.strokePath(p);

  return img;
}

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

4 participants