In principle, Non-uniform rational B-splines (NURBS) can be used to represent conic sections. The difficulty is finding the correct set of control points and knot weights. The following function does this.
UPDATE (2016-05-22):
Added a convenience function to draw a circle or circular arc in 3D specified by three points (see bottom of post)
EDIT :
Better handling of cases where end angle < start angle
ClearAll[splineCircle];
splineCircle[m_List, r_, angles_List: {0, 2 π}] :=
Module[{seg, ϕ, start, end, pts, w, k},
{start, end} = Mod[angles // N, 2 π];
If[ end <= start, end += 2 π];
seg = Quotient[end - start // N, π/2];
ϕ = Mod[end - start // N, π/2];
If[seg == 4, seg = 3; ϕ = π/2];
pts = r RotationMatrix[start ].# & /@
Join[Take[{{1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1,0}, {-1, -1}, {0, -1}}, 2 seg + 1],
RotationMatrix[seg π/2 ].# & /@ {{1, Tan[ϕ/2]}, {Cos[ ϕ], Sin[ ϕ]}}];
If[Length[m] == 2,
pts = m + # & /@ pts,
pts = m + # & /@ Transpose[Append[Transpose[pts], ConstantArray[0, Length[pts]]]]
];
w = Join[
Take[{1, 1/Sqrt[2], 1, 1/Sqrt[2], 1, 1/Sqrt[2], 1}, 2 seg + 1],
{Cos[ϕ/2 ], 1}
];
k = Join[{0, 0, 0}, Riffle[#, #] &@Range[seg + 1], {seg + 1}];
BSplineCurve[pts, SplineDegree -> 2, SplineKnots -> k, SplineWeights -> w]
] /; Length[m] == 2 || Length[m] == 3
This looks rather complex, and it is. However, the output (the only thing that ends up in the final graphics) is clean and simple:
splineCircle[{0, 0}, 1, {0, 3/2 π}]

Just a single BSplineCurve
with a few control points.
It can be used both in 2D and 3D Graphics (the dimensionality of the center point location is used to select this):
DynamicModule[{sc},
Manipulate[
Graphics[
{FaceForm[], EdgeForm[Black],
Rectangle[{-1, -1}, {1, 1}], Circle[],
{Thickness[0.02], Blue,
sc = splineCircle[m, r, {start Degree, end Degree}]
},
Green, Line[sc[[1]]], Red, PointSize[0.02], Point[sc[[1]]]
}
],
{{m, {0, 0}}, {-1, -1}, {1, 1}},
{{r, 1}, 0.5, 2},
{{start, 45}, 0, 360},
{{end, 180}, 0, 360}
]
]

Manipulate[
Graphics3D[{FaceForm[], EdgeForm[Black],
Cuboid[{-1, -1, -1}, {1, 1, 1}], Blue,
sc = splineCircle[{x, y, z}, r, {start Degree, end Degree}], Green,
Line[sc[[1]]], Red, PointSize[0.02], Point[sc[[1]]]},
Boxed -> False],
{{x, 0}, -1, 1},
{{y, 0}, -1, 1},
{{z, 0}, -1, 1},
{{r, 1}, 0.5, 2},
{{start, 45}, 0, 360},
{{end, 180}, 0, 360}
]

With Tube
and various transformation functions:
Graphics3D[
Table[
{
Hue@Random[],
GeometricTransformation[
Tube[splineCircle[{0, 0, 0}, RandomReal[{0.5, 4}],
RandomReal[{π/2, 2 π}, 2]], RandomReal[{0.2, 1}]],
TranslationTransform[RandomReal[{-10, 10}, 3]].RotationTransform[
RandomReal[{0, 2 π}], {0, 0, 1}].RotationTransform[
RandomReal[{0, 2 π}], {0, 1, 0}]]
},
{50}
], Boxed -> False
]

Additional uses
I used this code to make the partial disk with annular hole asked for in this question.
Specification of a circle or circular arc using three points
[The use of Circumsphere
here was a tip by J.M.. Though it doesn't yield an arc, it can be used to obtain the parameters of an arc]
[UPDATE 2020-02-08: CircleThrough
, introduced in v12, can be used instead of Circumsphere
as well]
Options[circleFromPoints] = {arc -> False};
circleFromPoints[m : {q1_, q2_, q3_}, OptionsPattern[]] :=
Module[{c, r, ϕ1, ϕ2, p1, p2, p3, h,
rot = RotationMatrix[{{0, 0, 1}, Cross[#1 - #2, #3 - #2]}] &},
{p1, p2, p3} = {q1, q2, q3}.rot[q1, q2, q3];
h = p1[[3]];
{p1, p2, p3} = {p1, p2, p3}[[All, ;; 2]];
{c, r} = List @@ Circumsphere[{p1, p2, p3}];
ϕ1 = ArcTan @@ (p3 - c);
ϕ2 = ArcTan @@ (p1 - c);
c = Append[c, h];
If[OptionValue[arc] // TrueQ,
MapAt[Function[{p}, rot[q1, q2, q3].p] /@ # &, splineCircle[c, r, {ϕ1, ϕ2}], {1}],
MapAt[Function[{p}, rot[q1, q2, q3].p] /@ # &, splineCircle[c, r], {1}]
]
] /; MatrixQ[m, NumericQ] && Dimensions[m] == {3, 3}
Example of usage:
{q1, q2, q3} = RandomReal[{-10, 10}, {3, 3}];
Graphics3D[
{
Red,
PointSize[0.02],
Point[{q1, q2, q3}],
Black,
Text["1", q1, {0, -1}],
Text["2", q2, {0, -1}],
Text["3", q3, {0, -1}],
Green,
Tube@circleFromPoints[{q1, q2, q3}, arc -> True
}
]

Similarly, one can define a 2D version:
circleFromPoints[m : {q1_List, q2_List, q3_List}, OptionsPattern[]] :=
Module[{c, r, ϕ1, ϕ2, ϕ3},
{c, r} = List @@ Circumsphere[{q1, q2, q3}];
If[OptionValue[arc] // TrueQ,
ϕ1 = ArcTan @@ (q1 - c);
ϕ2 = ArcTan @@ (q2 - c);
ϕ3 = ArcTan @@ (q3 - c);
{ϕ1, ϕ3} = Sort[{ϕ1, ϕ3}];
splineCircle[c, r,
If[ϕ1 <= ϕ2 <= ϕ3, {ϕ1, ϕ3}, {ϕ3, ϕ1 + 2 π}]],
splineCircle[c, r]
]
] /; MatrixQ[m, NumericQ] && Dimensions[m] == {3, 2}
Demo:
Manipulate[
c = Circumsphere[{q1, q2, q3}][[1]];
Graphics[
{
Black,
Line[{{q1, c}, {q2, c}, {q3, c}}],
Point[c],
Text["1", q1, {0, -1}],
Text["2", q2, {0, -1}],
Text["3", q3, {0, -1}],
Green,
Thickness[thickness], Arrowheads[10 thickness],
sp@circleFromPoints[{q1, q2, q3}, arc -> a]
}, PlotRange -> {{-3, 3}, {-3, 3}}
],
{{q1, {0, 0}}, Locator},
{{q2, {0, 1}}, Locator},
{{q3, {1, 0}}, Locator},
{{a, False, "Draw arc"}, {False, True}},
{{sp, Identity, "Graphics type"}, {Identity, Arrow}},
{{thickness, 0.01}, 0, 0.05}
]

For versions without Circumsphere
(i.e, before v10.0) one could use the following function to get the circle center (c
in the code above, r
would then be the EuclideanDistance
between c and p1):
getCenter[{{p1x_, p1y_}, {p2x_, p2y_}, {p3x_, p3y_}}] :=
{(1/2)*(p1x + p2x + ((-p1y + p2y)*
((p1x - p3x)*(p2x - p3x) + (p1y - p3y)*(p2y - p3y)))/
(p1y*(p2x - p3x) + p2y*p3x - p2x*p3y + p1x*(-p2y + p3y))),
(1/2)*(p1y + p2y + ((p1x - p2x)*
((p1x - p3x)*(p2x - p3x) + (p1y - p3y)*(p2y - p3y)))/
(p1y*(p2x - p3x) + p2y*p3x - p2x*p3y + p1x*(-p2y + p3y)))}
BSplineCurve[]
. $\endgroup$ParametricPlot
withGeometricTransformation
, see example. And, you can also replaceLine
withTube
and it works. $\endgroup$