Lucas
What version of LabVIEW are you using? Do you have any data you could share? If you are using LabVIEW 8.0 or later, then there is a VI that could be a real help. Take a look at Extract Multiple Tones.vi. This is similar to the Extract Single Tone.vi, except it will find more than one tone. It is also a diffent algorithm that the single tone extraction. The DC offset in your signal will appear in the "multiple tone info" output as a very low frequency tone (milli-Hz to micro-Hz). Even if you continue to use the Nonlinear Curve Fit.vi, this could give you a very good initial guess, particularly for the frequency.
You also mentioned using a numerical root finder to find the zero crossings. Given your model (A*sin(wx+p)+b) it seems that you should be able to solve explicitly for x.
a*Sin(wx+p)+b = 0
Sin(wx+p) = -b/a
wx+p = InvSin(-b/a)
x=(InvSin(-b/a)-p)/w
This will give one level crossing (level of zero), and adding full periods will give every other crossing, but the alternate crossings are not half-periods from the crossing x, unless the offset in the model is zero.
You could view the set of crossings as all x that satisfy:
a*Sin(wx+p+kPi) = 0 where k is an integer,
expanding in Sin and Cos:
a*[Sin(wx+p)*Cos(kPi) + Cos(wx+p)*Sin(kPi)] = 0
Sin(kPi)=0, so
aCos(kPi)Sin(wx+p)=0
let A=aCos(kPi)
solving for x as before gives:
x=(InvSin(-b/A)-p)/w
Using this approach and the Extract Multiple Tones.vi seems to give very good results for the zero crossings on some simple data I tried here (Sine + Gaussian Noise).
The use of local polynomial models will work but if you can involve the entire dataset in solving for a model then there is more "averaging" of the noise in the data and the results should be more robust. If your data does not match the model well, or the model changes over the course of the data (non-stationary), then Lynn's approach is better.
Hope this helps.
-Jim