Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

JGoose

macrumors member
Original poster
Feb 12, 2010
41
0
I have the following code to draw a zig-zag line. Works great, but I want to make each line segment a different width than all the others. I want each segment to be a little thinner than the last one. I can't figure out how to change one of them without changing all of them.

Code:
for (int arrayPointer = 0; arrayPointer != (arrayWithPoints.count); arrayPointer++) 
	{
		NSValue *theValue = [arrayWithPoints objectAtIndex: arrayPointer];
		CGPoint thePoint = [theValue CGPointValue];
			
		if (arrayPointer == 0) 
		{
			CGContextBeginPath(context);
			CGContextMoveToPoint(context, thePoint.x, thePoint.y);
		}
		else 
		{
			CGContextAddLineToPoint(context, thePoint.x, thePoint.y);
		}
	}
CGContextSetLineWidth(context, 20);

thx
 
It's late I'm tired, so, without much thought …

Code:
CGfloat     lineWidth   = 20;
CGPoint     point;
NSUInteger  count     = [arrayWithPoints count];
if ( count )
{
    CGfloat d   = (lineWidth / count);
    CGContextSetLineWidth(context, lineWidth);

    CGContextBeginPath(context);

    point = [[arrayWithPoints objectAtIndex:i] CGPointValue];
    CGContextMoveToPoint(context, point.x, point.y);

    for ( int index = 0; --count; index++ )
    {
        point = [[arrayWithPoints objectAtIndex:index] CGPointValue];
        CGContextAddLineToPoint(context, pt.x, pt.y);

        lineWidth   -= d;
        CGContextSetLineWidth(context, lineWidth);
    }
}
 
I've tied that and it ends up setting the whole line to the thinnest width.
 
For each line, move to the line's start point, then line to the end point, set the line width and stroke.
 
Have you considered that what you ask for might be impossible?

Does a CGPathRef have the ability to store line-width? If not, then you obviously can't record the line-width in a path.

If that's the case, then you will have to make your own alternative. For example, looking at your originally posted code, I see no particular reason to require a CGPathRef. You could just as easily make a class that contains a series of line widths alternating with points. Then to render it, you just walk the list, setting the line width then drawing to the next point.

The most obvious difference between your original code and lloyddean's code is that you didn't have the line-width being set in the loop, and he does. That seems to be a crucial part of getting what you originally described.

The whole thing seems like a straightforward matter of breaking the problem down into individually solvable parts. The parts must occur in the proper order, but I see nothing insurmountable or requiring deep magic.
 
Code:
int lineWidth = 23;

for (int arrayPointer = 0; arrayPointer < (arrayWithPoints.count); arrayPointer++) 
{
	NSValue *theValue = [arrayWithPoints objectAtIndex: arrayPointer];
	CGPoint thePoint = [theValue CGPointValue];
			
	if (arrayPointer != 0) 
	{
		CGContextBeginPath(context);
		CGContextMoveToPoint(context, lastPoint.x, lastPoint.y);
				
		CGContextAddLineToPoint(context, thePoint.x, thePoint.y);
		CGContextSetLineWidth(context, lineWidth);
	}
				
	lastPoint = thePoint;
	lineWidth -= 1;
								
	CGContextDrawPath(context, kCGPathFillStroke);
	}


I got this to work. It makes a different line for each "zig" and "zag." This works, but I also wanted to put a shadow on it. So I put a shadow on each line segment, but then it becomes obvious to the user that I used line segments because the shadow from one segment overlaps another segment.
 
You need to use CGContextBeginTransparencyLayer() and CGContextEndTransparencyLayer(). What that does is apply the shadow to everything drawn between the calls to those functions.

So set the shadow, then call CGContextBeginTransparencyLayer, then draw your lines, and then call CGContextEndTransparencyLayer(). I think that should do what you want.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.