Question

I am trying to plot mathematical functions and use the CoreGraphics framework. I am calculating a path by manually calculating the y-coordinate of a user defined mathematical function.

To draw the function I have included a simplified version of the code:

CGContextBeginPath(context);
CGContextMoveToPoint(context, coordinateSystemOriginX, coordinateSystemOriginY);

//Add all points
CGContextAddLineToPoint(context, newPoint.x,newPoint.y);

CGContextSetLineWidth(context, 2);
CGContextSetStrokeColorWithColor(context, [[UIColor redColor] CGColor]);
CGContextStrokePath(context); //Connect them

This is working fine but sadly the user might input a discontinous function like

 y = 10/x //undefined value for x=0

but the graph is drawn at x=0 and the points are connected. See the image:

enter image description here

How can I evaluate undefined points so I am able to draw the graph correctly? I know there IS a solution as there are many plotting websites that draw the graph correctly.

A tip or any type of help would be greatly appreciated. Your are also free to include some magic piece of code ;) Thanks!

 NSArray*undefinedPoints = [self someMagicFunction:(id)mathematicalExpression];
 //returns 0 for mathematicalExpression = 10/x and 1 for 10/(x-1)

BTW I am using the ANExpressionParser class to parse the user input. (http://mac.softpedia.com/progDownload/ANExpressionParser-Download-86833.html)

Was it helpful?

Solution

I assume you are advancing your x value at a fixed delta, possibly dependent on the resolution and zoom level.

If you are lucky enough to actually divide by zero you'll produce +Inf or -Inf and can check for that, and skip over that value when building your curve (splitting your curve into multiple parts), which solves your problem in that case.

More generally and more often, you won't actually divide by zero but instead will divide by a very small number, producing a result which is a very large number. You should be able to compare that value with the bounds of your viewport. If this value is outside the bounds of your viewport, you can decide to end that curve, and once a new value appears (for a new value of x) that is once again within your viewport you can begin a new curve, thus solving your problem in that case as well.

If you are advancing your x value per-pixel then the above should be a solution.

If you are advancing your x value more coarsely than per-pixel, then you will also have to deal with clipping the line segment, and with avoiding false positives with respect to detecting discontinuity.


Also check to see if your particular library can produce for you a list of analytically determined discontinuities. With such a list ahead of time, you can split your curve into sections separated by those discontinuities.


See also Division by Zero in Computer Arithmetic, Asymptotes, and Discontinuity.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top