これは古い質問ですが、私は最近同じことに取り組んでいました。あなたがやろうとしているのは、あなたが言ったように、ガウスの円の問題です。これは、ここで説明されているようなものです。
私もその背後にある深刻な数学を理解するのは難しいですが、奇妙なエイリアンのシンボルを使用しない場合、多かれ少なかれそれは次のようになります。
1 + 4 * sum(i=0, r^2/4, r^2/(4*i+1) - r^2/(4*i+3))
これは少なくともJavaでは次のとおりです。
int sum = 0;
for(int i = 0; i <= (radius*radius)/4; i++)
sum += (radius*radius)/(4*i+1) - (radius*radius)/(4*i+3);
sum = sum * 4 + 1;
なぜ、どのようにこれが機能するのかわかりません。正直に言うと、パフォーマンスがOではなくO(r ^ 2/4)であることを意味するため、1行ではなくループを使用してこれを取得する必要があります。 (1)。
数学の魔法使いはループよりもうまくいくようには見えないので、私はそれをO(r + 1)のパフォーマンスに下げることができるかどうかを確認することにしました。したがって、上記は使用せず、以下を使用してください。O(r ^ 2/4)はひどく、平方根を使用しているにもかかわらず遅くなります。
int sum = 0;
for(int x = 0; x <= radius; x++)
sum += Math.sqrt(radius * radius - x * x);
sum = sum * 4 + 1;
このコードが行うことは、直交する線に沿って中心から端までループし、各点で線から端までの距離を垂直方向に追加することです。最後に、クォーター内のポイント数が含まれるため、結果が4倍になり、中心ポイントもあるため1が追加されます。wolframの方程式も4を掛けて1を足すので、似たようなことをしているように感じますが、IDKはなぜr^2/4をループするのですか。
正直なところ、これらは優れた解決策ではありませんが、最高の解決策のようです。これを定期的に実行する関数を呼び出している場合は、新しい半径が表示されたら、毎回完全な計算を行うのではなく、結果をルックアップテーブルに保存します。
それはあなたの質問の一部ではありませんが、誰かに関係があるかもしれないので、とにかくそれを追加します。私は個人的に、次のように定義されたセルを持つ円内のすべての点を見つけることに取り組んでいました。
(centreX - cellX)^2 + (centreY - cellY)^2 <= radius^2 + radius
余分な+半径がこれをピタゴラスの定理と正確に一致させないので、これはすべてを強打から外します。ただし、この余分なビットにより、直交するエッジに小さなにきびがないため、円はグリッド上で視覚的にはるかに魅力的に見えます。はい、私の形はまだ円ですが、半径としてrの代わりにsqrt(r ^ 2 + r)を使用していることがわかりました。これは明らかに機能しますが、方法を尋ねないでください。とにかく、それは私にとって、私のコードは少し異なり、次のように見えることを意味します:
int sum = 0;
int compactR = ((radius * radius) + radius) //Small performance boost I suppose
for(int j = 0; j <= compactR / 4; j++)
sum += compactR / (4 * j + 1) - compactR / (4 * j + 3);
sum = sum * 4 + 1;