Backdooring Instantaneous Radius of Curvature & Functions

I'm a novice coder who seeks help w/ creating a function and possible clean up of code.

Brief history: I'm currently working on a project that requires the use of a C++ DLL to talk to a PLC machine running in a real time production environment. My background is mathematics, not coding. I'm struggling to make this work!

Currently the parameters for this machine require evaluating data by instantaneous radius of curvature standards. (Recall that the smaller the radius of curvature, the more curvy or less straight a curve becomes. This is not difficult to find by way of calculus, but I'm nowhere near ready to code derivatives and second derivatives! My current curve needs to be adjusted to fit the minimum radius parameters. I've found a way of backdooring this calculus requirement with a little geometry and iterating along the curve, looking at three adjacent points each time. (Points are close enough to be considered instantaneous)

Currently this code works. I had to do some strange internal error handling because it was coming up with strange results when I got close to infinity, 1/0 or something close to it. Maybe this could be a corrected suggestion instead of my if, else stmts.

Please help, comment, or suggest on the following three points of concern:
1) Need to reuse this method of finding the radius several more times than currently using it, so need it to be a function instead of part of the main body of code! Not sure how the variables inside of the function need to be set up to conserve memory

2) Recently read an article warning against function use in DLLs because of inability to handle errors. (An error would stop production Not a good thing! Should I be worried about this?) This DLL called is an exported function---Does this mean I can't call a function within a function? I know nothing

The second point is that the goto has you jumping out of the FINDRADIUS function, apparently never to come back, and so FINDRADIUS will never return a value. If you have called FINDRADIUS in some code like

Code:

r = FINDRADIUS(parameters happen to fit straight log;

the value of r will be undefined, and control of the program may have gone somewhere totally undesired.

Better to make a function out of whatever code you have following the Straight_Log label, and then have FINDRADIUS return the result of that function.

With the yDiff1 and yDiff2 given above, you will have m2 = -(z3-z2)/(-0.00007). Not only that, but the code to take care of tiny yDiff2 will get skipped over. If that's ok, then nevermind. But it would still be clearer to write your if/else if to test for BOTH yDiff1 and yDiff2 together:

Rather than having magic numbers like 0.00015, 0.0002, 20000 littered all over the place, better to make consts out of them. That way, if you ever want to change the values, you'll only have to do it in one place.

m1 and m2 could both be zero if the z's are all equal, and all of the checks you've done so far have only been about the y's. And even if m1 and m2 are not both zero, they might still be equal, so your Zradius formula could end up dividing by zero.

Now a mathematics question: in your coordinate system, is y the horizontal axis, & z the vertical? In the (y,z) coordinate system, I thought delta_z/delta_y is the slope of the line connecting (y1,z1) & (y2,z2), and -delta_y/delta_z is the slope of the line perpendicular to that? Anyway, just check to be sure the numerators & denominators aren't switched in your formula.

If the right way to do this is by calculating derivatives (e.g., if y = f(x), then radius(x) = (1+(f')^2)^(3/2) / f'' = exp(1.5 * log(1+sqr(f')))/f''), then there are some pre-packaged routines for calculating derivatives. Check out the numerical recipes in C site: http://www.nr.com, or http://www.library.cornell.edu/nr/cbookcpdf.html (e.g. chapter 5.7). There might be something that will work for you.

(Addressing your suggestions)
1.)(a) you will not get rescued by your "goto Straight_Log"

The boat comes to rescue me in the if statement following the "goto Straight_Log" if statement. However, it sails away laughing. It only saves me most of the time. (epiphany came after reading part (c) of your suggestions)

(b) goto has you jumping out of the FINDRADIUS function, apparently never to come back

I've tried to modify an existing routine and somehow forgot that line. Thanks!

I will make changes to incorporate the Straight_Log function

(c) Referring to if yDiff2 and yDiff1 are BOTH tiny

You're correct that this if, then situation will not catch an error.

Hypothetically speaking the yDiff1=0.00015 will be acceptable, but the yDiff2=-0.00007 could give me problems. I ran some tests and with both yDiffs so close to zero the intersecting lines intersect in some far off distance of no importance to my analysis. Now abs(yDiff1-yDiff2)=0.00021 and 0.00021>.0002, which causes the code to miss the Straight_Log parameters. But the very next if (absYDiff1<=.00015) would catch the small yDiff1, throw (+ or -)20,000 into the slope, m1, and then find the slope for m2---------------I'm seeing your point (light bulbs ? ? ?)

You are sooo right, this will not be caught by goto statement, but will be caught by the first if yDiff1<=0.00015. It will pick 20,000 for the first slope, but calculate the slope as if everything were fine and dandy for the second slope. I can catch that with a nested if, (right again)

(d) make consts out of them

Will do.

2) m1 and m2 could both be zero if the z's are all equal

In this situation the z's will never be zero. This is in a scanning environment with everything based upon movement. As the data is scanned it is set up to take a measurement around every three inches. Even if production stops, the scanners will wait untill movement resumes to take a measurement to ensure that no z's are the same. (ie: the measurements taken will only be recorded as the z increases incrementally b/c it's motion based scaning)

even if m1 and m2 are not both zero, they might still be equal, so your Zradius formula could end up dividing by zero

I probably need a check for this!

Theoretically if the m1 and m2 are equal this should have been caught by the straight log scenario. The m1 and m2 being equal should only occur if the data is straight or, mathematically, has a constant slope along the interval. In this scenario, since the delta z's can never be zero, it would indicate that the yDiff1=yDiff2 (approximately). Again, theoretically, this should have been caught by the first If statement, if (abs(yDiff1-yDiff2)<=0.0002). But your right too many theoretical webs weave trouble or potential trouble!

3) I'll check it out!

Problem

with this is that the DLL currently fitting data through process of polynomial regression doesn't provide coefficients of the equation. So f' and f'' had to be skirted for now. I recently found one that yields coeff's and am considering making some changes in the near future to make things somewhat more readable to an outside coder. I might just write my own if I get brave.

Have you ever messed around with a Vadermonde Matrix?

Have a great day! Hope you get to read my response so you'll know how much I appreciate your time!

I could be wrong but I believe there is a faster way using spherical coordinates.

Any 2D sphere can be setup as:

x=sin(beta)*sin(alpha)
y=sin(beta)*cos(alpha)
z=cos(beta)

Why would spherical coordinates be used in a 2d plane with z being the horizontal axis and y being the vertical axis in this case?

Do you mean cylindrical? (or am I just confused)

Originally Posted by Bubba

You can find the radius if you know two points on the curve. Find the point at which the line through point 1 intersects the line through point 2. Now you know the center.

The code above does use 2 points. In fact the two points used are the midpoints of the three adjacent points (z1,y1) (z2,y2) (z3,y3). Why in the world would I use this??? Good question. I am changing the coordinates of the center point based upon my instantaneous radius of curvature parameters. If it passes the curvature requirements, I'll move on. If it fails , I'm flagging the center data point as being unacceptable. If it's flagged then I plan on moving (z2,y2) vertically, flattening the curve until the curvature is acceptable. I have a method in mind that will get the right answer but I'm affraid that the overhead required to do so will be unacceptable

Originally Posted by Bubba

Also you can create a right triangle out of two known points on the curve and thus using simple trigonometry can then find the angles you need and/or the radius.

I'm sort of confused as to why all the other math is involved. I'm working with radius and curves in my game and I'm not sure what you are getting at.

I think that I'm going to look at this from your triangle perspective a little more. Maybe I can restrict the angle (opposite the height when increasing or equal to the height when decreasing) of the right triangle. (I will always view this from Left to Right) but I'm going to need to relate that to a circle or radius.

You are sooo right, this will not be caught by goto statement, but will be caught by the first if yDiff1<=0.00015. It will pick 20,000 for the first slope, but calculate the slope as if everything were fine and dandy for the second slope. I can catch that with a nested if, (right again)

Rather than nested ifs, I think it will read easier to test yDiff1 and yDiff2 together. In other words, I think

Then what you really need to do is look into NURBS or non uniform rational b-splines or bezier curves. They are essentially controlled by control points some distance away from the curve. As you move the control points the curve changes. Very complex curves can be created with only a few control points.

I'm not sure how your particular device is retrieving coordinates to compute instantaneous radius of curvature so I'm quite lost as to the process involved. But I do understand curves and beziers....but NURBS get a little complex.

You can also use spherical linear interpolation, but to use that you must dump the euler angles and move to quaternions. There is an excellent article about quaternions on this board.

But much of what you are doing can be accomplished with linear and bilinear interpolation.

The last two functions are taken from 3D Math Primer for Graphics and Game Development by Fletcher Dunn and Ian Parberry. For an explanation of how it works or how to implement your own, consult their book or buy a book about 3D mathematics.

SQUAD is quaterion spline interpolation and SLERP is spherical linear interpolation. Given the correct control points any curve can be generated using these. There is also math to learn for finding control points on a curve and/or creating control points that two points on a curve would share.

Video games uses these formulas and one like it to smoothly interpolate around objects at any angle and orientation. Very difficult with euler angles.

You may also want to look into the equations for closest point on a 2D line to some point in space, intersection of two lines, etc.

Then what you really need to do is look into NURBS or non uniform rational b-splines or bezier curves. They are essentially controlled by control points some distance away from the curve. As you move the control points the curve changes. Very complex curves can be created with only a few control points.

I'm not sure how your particular device is retrieving coordinates to compute instantaneous radius of curvature so I'm quite lost as to the process involved. But I do understand curves and beziers....but NURBS get a little complex.

I'm currently reading several articles about the Bezier curves and am working on thier implementation. However, I don't fully understand them. In fact, it's a little scary to me. The articles that I've collected are not getting the job done. Maybe it's just me .

Thanks for recommending a specific book. I plan on ordering it & checking out quaternion board discussion. If you have found any other manuals that "break it down" clearly, please drop some titles my way when you have some time.