I want to draw two general triangles in 2D space in such way that they share one edge, using Quartz2D. I'm using this code for the drawing:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
Triangle *t1 = [triangles objectAtIndex:0];
Triangle *t2 = [triangles objectAtIndex:1];
[self fillTriangle:t1 inContext:context];
[self fillTriangle:t2 inContext:context];
}
- (void) fillTriangle:(Triangle *)t inContext:(CGContextRef)ctx
{
CGContextMoveToPoint(ctx, t.p1.p.x, t.p1.p.y);
CGContextAddLineToPoint(ctx, t.p2.p.x, t.p2.p.y);
CGContextAddLineToPoint(ctx, t.p3.p.x, t.p3.p.y);
CGContextAddLineToPoint(ctx, t.p1.p.x, t.p1.p.y);
CGContextSetFillColorWithColor(ctx, t.color.CGColor);
CGContextFillPath(ctx);
}
where Triangle
is a NSObject
subclass holding three points and a color.
The problem is that even when they share two points, there's a "space" between them when I fill them by this code, as shown in the image:
Question: Anyone knows how to get rid of the space so there's a seamless transition from one triangle to another with no line or whatever between them? I'd like to keep using Quartz2D but I'm glad for any help. Thanks!
EDIT: There were answers showing that the problem is caused by sub-pixel anti-aliasing, and adding the line
CGContextSetAllowsAntialiasing(ctx, NO);
to the fillTriangle
method solved that. But it's not the result I'd like to see - I don't like it being aliased, as shown in the second picture.
Question updated: do you know, how to solve both of the problems, that is, keeping the image clean with no ugly aliasing but no space between the triangles?
EDIT2: So, as was pointed in an answer, I could add the line stroke code, remove the antialiasing flag and the stroke would fill the space. Here's a last image to show what happened:
Notice the lines overlapping outside of the box. I was wondering what the cause might have been, and it disappeared when I set the width to 0.5f (since retina, that translates to 1px and that's probably what the responder thought), and that really solved the whole thing. Thanks to all help!
the problem is that you are drawing using antialiasing. disable it for your context via
CGContextSetShouldAntialias(context, NO);
and everything should be fine.
EDIT: in case of antialiasing is needed (your updated multicolor example), you could try to not only fill the triangles but also stroke their border in the same color with a line width of 1px:
CGContextSetLineWidth(ctx, 0.5f);
CGContextDrawPath(ctx, kCGPathFillStroke);
of course you should remove the CGContextSetShouldAntialias
line in that case. It's a simple solution but may not be the best performance wise, since the path has to be stroked and filled.