You can get the curve in polynomial implicit form as below.
poly =
GroebnerBasis[{x^2 - ct, y^2 - st, ct^2 + st^2 - 1}, {x, y}, {ct,
st}][[1]]
(* Out[290]= -1 + x^4 + y^4 *)
To get the area, integrate the characteristic function for the interior of the region. That that's where the polynomial is nonpositive (just notice that it is negative at the origin, say).
area = Integrate[Boole[poly <= 0], {x, -2, 2}, {y, -2, 2}]
(* Out[292]= (2 Gamma[1/4] Gamma[5/4])/Sqrt[π] *)
N[area]
(* Out[293]= 3.7081493546 *)
There are other ways to do this if you cannot find an implicit form, but this seems most direct in this case.
--- edit ---
If you can just solve separately for x
and y
in terms of the parameter t
then you can set up a region function. I do this below for the positive quadrant, and take advantage of symmetry to get the full area in approximate form.
reg = Function[{x, y},
If[And @@ {0 <= x <= 1, 0 <= y <= 1, y <= Sqrt[Sin[ArcCos[x^2]]]},
1, 0]];
approxarea = 4*NIntegrate[reg[x, y], {x, 0, 1}, {y, 0, 1}]
(* Out[321]= 3.70814937167 *)
One can actually recover the exact area from this by using Integrate
instead of NIntegrate
. But this seems like a viable approach in situations where the exact value might not be readily computed.
--- end edit ---
--- edit 2 ---
Here is a Monte Carlo method that does not rely on solving for anything. We extract the line segments, augment with a diagonal, and do some magic.
segs = Cases[curveplot, _Line, Infinity][[1, 1]];
segs = {Join[segs, N[Table[{j, 1 - j}, {j, 0, 1, 1/100}]]]};
I added an extra level of List
due to requirements of some further code. First let's reform a line to take a look at this region.
Graphics[Apply[Line, segs]]

Now we create an in-out function, generate a bunch of random points in the unit square of the first quadrant, take a Monte-Carlo approximation of this area. Then multiply by 4 and add 2. Why? because that's what one always does-- it's like selecting "c" when we don't know the multiple choice answer. (Okay, we multiply by 4 to account for all quadrants, and add 2 because we have in effect excised a square of side length $\sqrt{2}$ from the full region.)
To create the in-out function I use code directly from here.
nbins = 100;
Timing[{{xmin, xmax}, {ymin, ymax}, segmentbins} =
polyToSegmentList[{segs[[1]]}, nbins];]
(* Out[414]= {0.040000, Null} *)
len = 100000;
pts = RandomReal[1, {len, 2}];
Timing[
inout = Map[pointInPolygon[#, segmentbins, xmin, xmax, ymin, ymax] &,
pts];]
approxarea = 4.*Length[Cases[inout, True]]/len + 2.
(* Out[419]= {2.750000, Null} *)
(* Out[420]= 3.7092 *)
I would imagine one could do a bit better by integrating just the unit square in the first quadrant with Method -> "QuasiMonteCarlo"
, sowing the points via the EvaluationMonitor
option, and using those instead of the random set above. This will give a low-discrepancy sequence. Or generate such a set directly; bit offhand I don't know how to do that.
-- end edit 2 ---