Cocos2D & ccDrawLine - drawing smooth lines

I have some problems when I try to draw lines with cocos2d! I store the points obtained from the touchMoved method in an NSMutableArray and pass this array to a CCNode subclass called Lines, which I use to draw strings from an array of points. The problem is that the line is not smooth when I scroll slowly, but when I scroll faster, the line is much smoother. See the pictures below:

Slow Swipe: Slow swipe

Quick whistle: Fast swipe

I tried to solve the problem with ccpDistance, which calculates the distance between the last saved point, and if it is not far enough, I do not save it. I also tried to draw small circles in each saved position, but this is also not very nice. Here is my code:

In my GameScene:

- (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event { CGPoint location = [touch locationInView:[touch view]]; location = [[CCDirector sharedDirector] convertToGL:location]; if (ccpDistance(lastPoint, location) > 10) { //SAVE THE POINT [linePoints addObject:[NSValue valueWithCGPoint:location]]; [line updatePoints:linePoints]; lastPoint = location; } } 

And my Line class:

 - (void) updatePoints:(NSMutableArray *)_point { points = _point; } - (void) draw { if ([points count] > 0) { ccGLEnable(GL_LINE_STRIP); ccDrawColor4B(209, 75, 75, 255); float lineWidth = 6.0 * CC_CONTENT_SCALE_FACTOR(); glLineWidth(lineWidth); int count = [points count]; for (int i = 0; i < (count - 1); i++){ CGPoint pos1 = [[points objectAtIndex:i] CGPointValue]; CGPoint pos2 = [[points objectAtIndex:i+1] CGPointValue]; ccDrawLine(pos1, pos2); ccDrawSolidCircle(pos2, 2.5, 20); } } } 

Also, is there something in my code that can be done better to improve performance? Right now I have no problem even with 1000+ points, but just in case ...

Any help would be greatly appreciated! Thanks in advance!

+4
source share
2 answers

Well, I found a website that very clearly explained how to make smooth lines, and it worked wonderfully! There is still anti-aliasing there, but maybe I will never do it, since it looks very good on mesh devices. Here's a website: Drawing smooth lines with Cocos2D

And here is the result: Smooth lines

In addition, for those who are interested in ready-made code, here it is:

Line.m

 - (void) drawCurPoint:(CGPoint)curPoint PrevPoint:(CGPoint)prevPoint { float lineWidth = 6.0; ccColor4F red = ccc4f(209.0/255.0, 75.0/255.0, 75.0/255.0, 1.0); //These lines will calculate 4 new points, depending on the width of the line and the saved points CGPoint dir = ccpSub(curPoint, prevPoint); CGPoint perpendicular = ccpNormalize(ccpPerp(dir)); CGPoint A = ccpAdd(prevPoint, ccpMult(perpendicular, lineWidth / 2)); CGPoint B = ccpSub(prevPoint, ccpMult(perpendicular, lineWidth / 2)); CGPoint C = ccpAdd(curPoint, ccpMult(perpendicular, lineWidth / 2)); CGPoint D = ccpSub(curPoint, ccpMult(perpendicular, lineWidth / 2)); CGPoint poly[4] = {A, C, D, B}; //Then draw the poly, and a circle at the curPoint to get smooth corners ccDrawSolidPoly(poly, 4, red); ccDrawSolidCircle(curPoint, lineWidth/2.0, 20); } - (void) draw { if ([points count] > 0) { ccGLEnable(GL_LINE_STRIP); ccColor4F red = ccc4f(209.0/255.0, 75.0/255.0, 75.0/255.0, 1.0); ccDrawColor4F(red.r, red.g, red.b, red.a); float lineWidth = 6.0 * CC_CONTENT_SCALE_FACTOR(); glLineWidth(lineWidth); int count = [points count]; for (int i = 0; i < (count - 1); i++){ CGPoint pos1 = [[points objectAtIndex:i] CGPointValue]; CGPoint pos2 = [[points objectAtIndex:i+1] CGPointValue]; [self drawCurPoint:pos2 PrevPoint:pos1]; } } } 

As for GameScene, nothing has changed there (see question for code)! Please note that you can change the line if (ccpDistance(lastPoint, location) > X) , where X is the minimum distance between two points before the game saves another. The lower the X, the smoother the line will be, but you will have more points in your array, which can affect performance!

Anyway, thank you guys for your suggestions and your help, it helped me get the right fit!

+4
source

I think you could smooth your line drawing with some averaging.

 - (void) updatePoints:(NSMutableArray *)_point { points = _point; int count = [points count]; for (int i = 3; i < (count - 4); i++) { CGPoint pos1 = [[points objectAtIndex:i - 2] CGPointValue]; CGPoint pos2 = [[points objectAtIndex:i - 1] CGPointValue]; CGPoint pos3 = [[points objectAtIndex:i] CGPointValue]; CGPoint pos4 = [[points objectAtIndex:i + 1] CGPointValue]; CGPoint pos5 = [[points objectAtIndex:i + 2] CGPointValue]; CGFloat xpos = (pos1.x + pos2.x + 2 * pos3.x + pos4.x + pos5.x)/6; ... (now calcuclate ypos similarly and store the point into an array) } } 
0
source

Source: https://habr.com/ru/post/1493883/


All Articles