I havent got time to write example code but I can point you in the correct direction
A 3D bezier curve will happily handle all types of projectile paths, from perfect straight lines to loops to crazy intersecting spirals.
You can even join 2 or more curves together so you are only limited by your imagination.
They are very easy to setup and use and you can extract the xyz vector along the curve as T (time = 0 to 1 where 0 = curve start, 1 = curve end and 0.5 for example = mid curve).
You can even setup the Beziers before your main loop and simply translate and rotate the control points into position so that the curve starts at your guns xyz.
You can define complex paths with a simple set of 4 control points positioned in 3D space. The bezier will then bend and twist its way in 3d space from the start control point to the end control point, the 2nd and 3rd control points influence the shape of the curve (think magnets)
so if you write a projectile engine that uses beziers you can reuse it for any type of bullet, simply by changing the input curve parameters.
These forums have example code for beziers. If you get stuck give me a shout.
http://en.wikipedia.org/wiki/B%C3%A9zier_curve
EDIT - this is a function copied from my Delphi library. You specify the 4 control points (p0, p1, p2, p3) as XYZ (VECTOR) and the mu represents T (from 0 to 1). The function returns a vector which is the point along the curve at T. This function can easily be converted to DB.
type
VECTOR = packed record
x: float;
y: float;
z: float;
end;
function CubicBezier(p0: VECTOR; p1: VECTOR; p2: VECTOR; p3: VECTOR; mu: float): VECTOR;
var
a: VECTOR;
b: VECTOR;
c: VECTOR;
p: VECTOR;
begin
c.x := 3 * (p1.x - p0.x);
c.y := 3 * (p1.y - p0.y);
c.z := 3 * (p1.z - p0.z);
b.x := 3 * (p2.x - p1.x) - c.x;
b.y := 3 * (p2.y - p1.y) - c.y;
b.z := 3 * (p2.z - p1.z) - c.z;
a.x := p3.x - p0.x - c.x - b.x;
a.y := p3.y - p0.y - c.y - b.y;
a.z := p3.z - p0.z - c.z - b.z;
p.x := a.x * mu * mu * mu + b.x * mu * mu + c.x * mu + p0.x;
p.y := a.y * mu * mu * mu + b.y * mu * mu + c.y * mu + p0.y;
p.z := a.z * mu * mu * mu + b.z * mu * mu + c.z * mu + p0.z;
result := p;
end;