下面考虑质数螺旋
曾经以1开始绘制螺旋图,但是计算质数坐标的时候就出现困难。所以我们用0开始,并把它放在螺旋的中心。
观察如下图像,

最中心的数字0,不算大小。圈数为
,对应的数的个数,也就是面积为,

这些圈的最小值是0,最大值是,

相邻两项的差为,

这是一个二阶等差数列,对应的数值的和为,

这些数值,并不关心旋转的起点。仔细观察我们发现这些质数构成的线都几乎都是对角线,相当于旋转了45°的结果,既然如此,我们把起点旋转45°,看看能不能把斜线变成横竖的直线。

这是旋转45°之后的表格的样子。不难发现,中心行或者列上都是偶数,除了2是质数之外,不可能再有别的质数。所以就算是旋转45°之后,斜角上的数会落在横向和纵向的连线上,也不可能发生在中间的横轴或者纵轴上。而所有可能的连线都在这些轴的平行线上。

按照这个模式,用程序实现巨大范围内的质数螺旋效果,如上图所示。可见斜线已经被纠正为横线和竖线。质数的存在密度确实是中间更高。这个图像缩小之后,出现明显的十字图案,

这个图像的2D-FFT如下图中间部分所示,

其中最中心有一个亮点,其它位置上确实都是0,这通常说明图像极其简单,无任何结构或者纹理。但是实际上是有清晰的横纹和纵纹的,出现这种结果,说明指数在这个前提下的分布规律至少是可以不显露模式的。这也是质数的规律难于掌握的体现。
如果四个象限的坐标各自同时翻转(x横向翻转,y同时纵向翻转),则可以得到如下图像,

将图像缩小一定的比例之后,出现非常明显的圈层图案,

对四个象限,各自都上下左右翻转,这个做法本质上就是掉转计数的方向。因为是二维平面上的排列,所以才有四个象限,也就是2的平方。我们把这个维数降维到一维,其实就是观察一个象限里面的情况,在一个象限中,上下和左右同时翻转,对应的就是一维情况中的前后翻转,比如第一个质数被放在最后,最后一个质数被放在最前。一维情况下的闭合,就是出现周期性,二维情况下的闭合,需要把四个象限拼合在一起,而单个象限中就会出现拐角的形态,以使得两个维数可以互通为一个维数。这些情况,在这个图片中都显现了出来。另外单个象限中拐角图案不止一个,说明拐角构成的闭环不止一个,说明图片中含有的周期也不止一个。而这些周期,必然可以回归到它的一维形态,因为这些数,本来就是“卷起来的”,所以这些圈也不可能彼此孤立,而是首尾相接,构成整体上的离散螺线。这些情况也在这个图片中体现出来了。回到最初,我们是把自然数,从0开始,一直绕着0环绕,构成了整个图像,并且把其中的质数都标成白色。现在,我们通过把四个象限各自翻转,进而把整个周期都翻转过来,发现那些被标成白色的质数,聚会在一起,反而出现了螺旋的形态。只是原来的螺旋是一个数一个数构成的螺旋,现在的螺旋是一大堆质数形成一个微小线段,再由这些微小线段构成螺旋。这就相当于,原来的一个自然数,由现在的一大堆数值要大的多的质数拟合而成。而这些拟合成的不再是分立的自然数,而是连续的实数,因为这些用于拟合数量的质数,并不精确的构成整数。
所以这时候,同样的点,实际上是相对于整个图片存在的,相当于构成那个自然数的,是若干质数之和。而最开始的自然数螺旋,单个点就是单个质数本身。
相对于整个图片说的就是单位1,而单位1又分为质数基于的单位1和基于质数的单位1,也就是类似于
和
。由这一点去理解,就可以认识到质数和自身的倒数的等价性,这种等价性至多含有一个不为1的比例常数,

将这个比例常数
吸收到
和
的比例之中,或者将
和
的比例吸收到
里面即可得到,


那么,为什么不是,

或者说,为什么质数不是像
那样的虚数单位,这可以从我们用同时反转横向和纵向的做法中看出来。所以质数对应的是它所在周期的-1,而质数的平方根才是它所在周期的虚数单位。从,


中可以导出,

从
和
的实际值来说,显然一个是单位1的巨大倍数也就是
和单位1本身也就是
,也就是,

但是由于最终的关系体现为,

而,

导致结果必然体现出,

也就是数值上的,

这就是一种由于观测导致的必然的假象。这也是为什么,不能通过向外探查而了解真相的原因。向外探查了解真相就相当于要反向绕地球一圈才能到达一步就可以去到的地方。如果引入虚数单位,我们显然还是得把基本的当作1,把数量更大的当作虚数单位,

但是虚数单位和自身负倒数相等的关系同样会使得
和
之间的大小失去确定性,

就像狭义相对论分不清到底哪个才是主动引发运动的惯性系一样,在以测量为标准的系统中,

和
到底谁大谁小,是没法知道的。这是一切混淆得以成立的原因,也是为什么必须得自己成为才能真正理解的原因。在物理世界中,一切皆可互相颠倒,人却浑然不知,也是这个原因:观察者观测所观之物,必然导致这个结果。而如何才能纠正这种潜在的错误,唯一的方法就从自身的经验去验证。这也是实践是检验真理的唯一标准的一种脚注。也是做人做事必须摸着自己的良心来办,才能说人话办人事,而不是成为“人类的叛徒“的原因。因为你自己就是,你就错不了,你错了你自己会先知道,而如果抄别人的,拿来主义,最后你自己都不知道你干的是什么。所以那些真正实践的人,才是真理的真正掌握者,但这真理无法言说,说出来之后,听的人就成了被动观测者,可是观测者角色本身就有倒置世界而产生错误的严重问题,所以如果观测者不理解这一点,那么他会把所有的事情都理解反了,而如果继续按照这种认知来做出选择,他一定会走上反人类的道路。这也是普鲁士教育造成大规模的认知缺陷的根本原因。一个更为严峻的问题就是精神病的治疗问题,精神科医生普遍没有精神病的经历,和感冒发烧大家都有经历完全不同。医生没有病人的经历,就成了纯粹的观察者,但只要是观察者,观察到的和实际的情况就是相反的,如果他不能从人本的角度出发意识到病人也是人,他就会做出为了治病而治病,甚至为了治病而要命的判断和选择,这一点不是谁的错,而是任何人都做不到。就算是他能自认为感同身受的去体谅,因为没有精神病的经验,仍然会把事情干错。而病人本身又没有相关的医学知识,再被错误的对待,结果就会活在没人知道为什么的身心地狱之中。那种把书本上的知识当作前人的经验而不基于自己的经验的做法,是根本上行不通,甚至是要命的。这也是为什么优级主义看上去很美好,但实际上始终在作恶的原因。都是一个原因,就是观察者不合格,没有处理好观察和对观察的理解的转换过程,也没有处理好理解和传播的转换过程,而后者则是传播者不合格的体现。
虚数单位是怎么来的?虚数单位就是计数能力的极限的体现,也就是说,观察者受到的限制的在数学上的体现。所以观察者不合格是必然的,因为只要有观察者,观察者的上限不是定值,总有更大的数值,也总有更小的数值。所以观察者总有一天会不合格,也就是说,观察者自身的能力极限对应的环绕特性会把

看成,

也就是把世界看成颠倒的样子,并顺着这个结论,做出完全相反的选择。
如何超越?只有一个选项,就是认识到
和
的存在,以及二者大小的相对性。用人话来说,就是意识到有不同的人,人有强有弱,但是总有更强和更弱,于是这种比较就是没有确定结果的,没有确定结果就没有追求的价值,追求错误的东西,就只能徒增烦恼,甚至伤害他人。而一旦认定确定结果,就有可能完全看反,因为观察者总是不合格,也永远不可能合格,因为观察者是相对于非观察者才能成立的概念。可是这只是概念,谁都是观察者,谁都不是观察者。所以讨论一个并不能稳定成立的概念,并追求结果可以合格,完全就是妄想。
结论也很简单,有些东西学得了,有些东西学不了。成就一个人的是自己的经验,而获得经验的最基本要求,是不伤害别人,其次是避免阻止他人获得经验。无论何种原因和何种方式。但这一样太难,看着你的亲友挚爱去送死,一个人怎么才能狠心做到。这就是一环扣有一环的逻辑锁。而当你看到这一点,你也就明白了这个问题的解。但是这句话是无用的,你仍然活在自己的经验造成的观念里。
所以忘了这些,凭着你自己的良心生活,走那条难但是不退转的路,也许就是最终唯一的答案。
现代社会的高度发达,是基于分工的,分工创造了丰裕,也创造了大量的价值。
但分工有一个严重的弊端,就是你可能不得不把非常重要的东西交到别人手里,比如财富,比如自由,更比如生命。这些东西交给别人,正常来说需要极大的信任,但是这个信任也是有条件的,最基本的条件,就是不能背叛,还有就是不能脱离人本。当你把自己的生命交给一个你认为可信的人,而他在背后为了自己的利益而不顾你的死活,这个社会就没法运行下去。天堂就一夜之间变成了地狱。而信任是双向的,双向的信任基于最基本的互相理解,互相理解则基于共同的生活,可是分工本来就意味着不同的生活。在不同的生活里面失去基本的互相理解,进而轻易的就会失去信任关系,这又是一个逻辑上的死结。假定信任关系存在,又被愚弄和背叛,而信任关系不存在,则又失去了繁荣的基础,这又是一个死结。
既有分工的繁荣,又不会失去信任,信任又不被欺诈利用,所有这些条件都是现代社会可以安全稳定高效运行的基础。实际上的要求更多,这几点完全不能涵盖其全部,但都可以归结为认知问题。然而认知又天生就有观察者效应造成相反效果的极大的概率。
所以这是世界上最难的问题之一,不是解决不了或者解决得了,而是问不出来,甚至是想不起问。
但是,但是,你如果按照你本心的善良去做,而不是按照利益去做,你就根本不需要问。
这就是所谓一步就能走到的,却要绕过整个地球才能到达的问题。
以及走那么远到底值得不值得的问题。
我不想再替你回答,你自己能理解,自己就能办好,于是,被动观察者的帽子,就不用给你戴了。
把这个破事,总结一下,起个名字,就叫“认知基本定理”:在观测过程中,观察者所得的观测信息,总是和所观之物的实际情况相反(包括但不限于倒数和相反数)。若要得到正确的认识,最佳的方法就是成为所观之物本身。
应用到社会生活中:你想要帮助一个或者一群人,你首先要成为他们的一份子,了解他们真实的生活,然后再跳出来,找到问题的解答,然后再跳回去验证解答的正确性(当然不是慷他人之慨),然后再跳出来,反反复复,若干次迭代之后,自会有所成效。
所以反过来再看,比如比尔盖茨去非洲扶贫,为什么会越扶越贫,殖民者总是认为给殖民地带来了文明,却在实际上剥夺了殖民地自身发展而不依赖外界的基本条件。就像为什么一个人要自己站稳,环境不是给他结果,而是给他站稳的条件,为什么授人以鱼不如授人以渔,都是这个原因,你不是他,你办不了他的事,你是他,你就和他一样救不了自己。所以你是他,你也不是他,你真正愿意去感同身受,而且真的知道自己在干什么,才不会落得帮人的人把人坑死的下场 。所以你看,不是没有救世主,也不是没有神仙皇帝,有啥都没用,不会干,把事情干反了,违背规律,就是这个结果。这也从侧面验证了,一个好的环境,一个以人为本的环境,才是解脱苦难的唯一出路。
以下为最新完整的程序代码
1using System.Drawing.Imaging; 2using System.Numerics; 3 4namespace PrimeCross; 5 6public partial class FormMain : Form 7{ 8 public static Bitmap GetBitmap(int[,] pixels) 9 { 10 var width = pixels.GetLength(0); 11 var height = pixels.GetLength(1); 12 var bitmap = new Bitmap(width, height); 13 using var g = Graphics.FromImage(bitmap); 14 for (int y = 0; y < height; y++) 15 { 16 for (int x = 0; x < width; x++) 17 { 18 bitmap.SetPixel(x, y, Color.FromArgb( 19 pixels[x, y] | unchecked((int)0xff000000))); 20 } 21 } 22 return bitmap; 23 } 24 public static int[,] GetPixels(Bitmap bitmap) 25 { 26 int width = bitmap.Width; 27 int height = bitmap.Height; 28 var pixels = new int[width, height]; 29 var rect = new Rectangle(0, 0, width, height); 30 31 var data = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat); 32 int bytesPerPixel = Image.GetPixelFormatSize(bitmap.PixelFormat) / 8; 33 int bytes = Math.Abs(data.Stride) * height; 34 var rgbValues = new byte[bytes]; 35 36 System.Runtime.InteropServices.Marshal.Copy(data.Scan0, rgbValues, 0, bytes); 37 38 for (var y = 0; y < height; y++) 39 { 40 for (var x = 0; x < width; x++) 41 { 42 var i = y * data.Stride + x * bytesPerPixel; 43 pixels[x, y] 44 = (rgbValues[i + 1] << 0) 45 | (rgbValues[i + 1] << 8) 46 | (rgbValues[i + 2] << 16) 47 | (rgbValues[i + 3] << 24) 48 ; 49 } 50 } 51 52 bitmap.UnlockBits(data); 53 54 return pixels; 55 } 56 public static void FFT(Complex[] t, Complex[] f, int r) 57 { 58 long count = 1L << r; 59 int i, j, k, p, bsize; 60 61 var W = new Complex[1L << (r - 1)]; 62 var X1 = new Complex[count]; 63 var X2 = new Complex[count]; 64 for (i = 0; i < W.Length; i++) 65 { 66 var angle = i * Math.PI * 2.0 / count; 67 W[i] = new(Math.Cos(angle), -Math.Sin(angle)); 68 } 69 70 t.CopyTo(X1, 0); 71 72 for (k = 0; k < r; k++) 73 { 74 for (j = 0; j < 1 << k; j++) 75 { 76 bsize = 1 << (r - k); 77 for (i = 0; i < (bsize >> 1); i++) 78 { 79 p = j * bsize; 80 X2[i + p] 81 = X1[i + p] + X1[i + p + (bsize >> 1)] 82 ; 83 X2[i + p + (bsize >> 1)] 84 = (X1[i + p] - X1[i + p + (bsize >> 1)]) 85 * W[i * (1 << k)] 86 ; 87 } 88 } 89 (X1, X2) = (X2, X1); 90 } 91 92 for (j = 0; j < count; j++) 93 { 94 p = 0; 95 for (i = 0; i < r; i++) 96 { 97 if ((j & (1 << i)) != 0) 98 { 99 p += 1 << (r - i - 1); 100 } 101 } 102 f[j] = X1[p]; 103 } 104 } 105 public static Bitmap Fourier(Bitmap bitmap) 106 { 107 int width = bitmap.Width; 108 int height = bitmap.Height; 109 if (width == 0 || height == 0) 110 return bitmap; 111 long lw = 1; 112 long lh = 1; 113 int wp = 0; 114 int hp = 0; 115 long i, j; 116 long n, m; 117 double kt; 118 var data = GetPixels(bitmap); 119 const int _31 = (sizeof(int) << 3) - 1; 120 lw = 1 << (wp = _31 - int.LeadingZeroCount(width)); 121 lh = 1 << (hp = _31 - int.LeadingZeroCount(height)); 122 var t = new Complex[lw * lh]; 123 var f = new Complex[lw * lh]; 124 var tw = new Complex[lw]; 125 var th = new Complex[lw]; 126 for (i = 0; i < lh; i++) 127 { 128 for (j = 0; j < lw; j++) 129 { 130 t[i * lw + j] = new(data[j, i] == 0 ? 0 : 0xffffff, 0.0); 131 } 132 } 133 for (i = 0; i < lh; i++) 134 { 135 Array.Copy(t, i * lw, tw, 0, lw); 136 Array.Copy(f, i * lw, th, 0, lw); 137 FFT(tw, th, wp); 138 Array.Copy(th, 0, f, i * lw, lw); 139 } 140 141 for (i = 0; i < lh; i++) 142 { 143 for (j = 0; j < lw; j++) 144 { 145 t[j * lh + i] = f[i * lw + j]; 146 } 147 } 148 149 var ow = new Complex[lh]; 150 var oh = new Complex[lh]; 151 for (i = 0; i < lw; i++) 152 { 153 Array.Copy(t, i * lh, ow, 0, lh); 154 Array.Copy(f, i * lh, oh, 0, lh); 155 FFT(ow, oh, hp); 156 oh.CopyTo(f, i * lh); 157 } 158 159 160 var max = f.Max(c => (c.Magnitude)); 161 162 for (i = 0; i < lh; i++) 163 { 164 for (j = 0; j < lw; j++) 165 { 166 var val = f[j * lh + i].Magnitude; 167 kt = (val / max) * 255.0; 168 n = ((height - lh) >> 1) + (i < (lh >> 1) ? i + (lh >> 1) : i - (lh >> 1)); 169 m = ((width - lw) >> 1) + (j < (lw >> 1) ? j + (lw >> 1) : j - (lw >> 1)); 170 data[m, n] = Color.FromArgb( 171 (byte)kt, 172 (byte)kt, 173 (byte)kt) 174 .ToArgb(); 175 } 176 } 177 178 return GetBitmap(data); 179 } 180 public FormMain() 181 { 182 InitializeComponent(); 183 } 184 private enum Direction : int 185 { 186 Down = 0, 187 Right, 188 Up, 189 Left 190 } 191 192 private static Direction Turn(Direction d, bool left = true) => left 193 ? (Direction)(((int)d + 1) % 4) 194 : (d == Direction.Down) ? Direction.Left : ((Direction)((int)d) - 1) 195 ; 196 private static Point LeftOf(Point p, Direction d) => d switch 197 { 198 Direction.Down => new(p.X + 1, p.Y), 199 Direction.Right => new(p.X, p.Y - 1), 200 Direction.Up => new(p.X - 1, p.Y), 201 Direction.Left => new(p.X, p.Y + 1), 202 _ => p, 203 }; 204 private static Point RightOf(Point p, Direction d) => d switch 205 { 206 Direction.Down => new(p.X - 1, p.Y), 207 Direction.Right => new(p.X, p.Y + 1), 208 Direction.Up => new(p.X + 1, p.Y), 209 Direction.Left => new(p.X, p.Y - 1), 210 _ => p, 211 }; 212 213 private static Point ForwardOf(Point p, Direction d) => d switch 214 { 215 Direction.Down => new(p.X, p.Y + 1), 216 Direction.Right => new(p.X + 1, p.Y), 217 Direction.Up => new(p.X, p.Y - 1), 218 Direction.Left => new(p.X - 1, p.Y), 219 _ => p, 220 }; 221 private static bool IsPrime(long n) 222 { 223 switch (n) 224 { 225 case < 2: 226 return false; 227 case 2: 228 return true; 229 } 230 if (n % 2 == 0) return false; 231 for (long i = 3; i <= Math.Sqrt(n); i += 2) 232 if (n % i == 0) return false; 233 return true; 234 } 235 const int Black = 0x000000; 236 const int White = 0xffffff; 237 const int Red = 0x0000ff; 238 bool flip = false; 239 bool inverse = false; 240 bool rotate = false; 241 int length = 0; 242 (int, long, bool)[,]? primes = null; 243 private static (int, long, bool)[,] BuildPrimesMap(int length) 244 { 245 var map = new (int, long, bool)[length, length]; 246 var center = new Point(length >> 1, length >> 1); 247 var direction = Direction.Up; 248 long n = 0; 249 map[center.X, center.Y] = (White, n++, false); 250 var p = new Point(center.X + 1, center.Y + 1); 251 map[p.X, p.Y] = (Red, n++, false); 252 p.Y--; 253 map[p.X, p.Y] = (White, n++, true); 254 while (n <= length * length) 255 { 256 n++; 257 p = ForwardOf(p, direction); 258 if (p.X < 0 || p.X >= length - 1 259 || p.Y < 0 || p.Y >= length - 1) 260 break; 261 var b = IsPrime(n); 262 map[p.X, p.Y] = (b ? White : Red, n, b); 263 264 var l = LeftOf(p, direction); 265 if (l.X < 0 || l.X >= length - 1 266 || l.Y < 0 || l.Y >= length - 1) 267 break; 268 var lc = map[l.X, l.Y]; 269 if (lc.Item1 == Black) 270 { 271 direction = Turn(direction); 272 } 273 else 274 { 275 var pt = ForwardOf(p, direction); 276 if (pt.X < 0 || pt.X >= length - 1 277 || pt.Y < 0 || pt.Y >= length - 1) 278 continue; 279 var px = map[pt.X, pt.Y]; 280 if (px.Item1 != Black) 281 { 282 var rp = RightOf(p, direction); 283 if (rp.X < 0 || rp.X >= length - 1 284 || rp.Y < 0 || rp.Y >= length - 1) 285 break; 286 p = rp; 287 } 288 } 289 } 290 return map; 291 } 292 293 private static Point FlipProject(Size size, Point p, bool flip = false, bool rotate = false) 294 { 295 var cp = new Point(size.Width >> 1, size.Height >> 1); 296 if (!flip) 297 { 298 return rotate ? new(p.Y, p.X) : p; 299 } 300 else 301 { 302 int x = p.X, y = p.Y; 303 x = x < cp.X ? cp.X - x : size.Width + (cp.X - x) - 1; 304 y = y < cp.Y ? cp.Y - y : size.Height + (cp.Y - y) - 1; 305 return rotate ? new(y, x) : new(x, y); 306 } 307 } 308 private void GeneratePrimesMap(bool flip = false, bool inverse = false, bool rotate = false) 309 { 310 this.primes = BuildPrimesMap( 311 this.length = Math.Max( 312 PrimesPictureBox.Width, 313 PrimesPictureBox.Height) 314 ); 315 316 var bitmap = new Bitmap(PrimesPictureBox.Width, PrimesPictureBox.Height); 317 var size = new Size(PrimesPictureBox.Width, PrimesPictureBox.Height); 318 for (int y = 0; y < size.Height; y++) 319 { 320 for (int x = 0; x < size.Width; x++) 321 { 322 var px = x + ((this.length - PrimesPictureBox.Width) >> 1); 323 var py = y + ((this.length - PrimesPictureBox.Height) >> 1); 324 var c = this.primes[px, py]; 325 var fp = FlipProject(size, new Point(x, y), flip, rotate); 326 bitmap.SetPixel(fp.X, fp.Y, 327 ((!inverse) ? c.Item3 : !c.Item3) ? Color.White : Color.Black); 328 } 329 } 330 331 this.PrimesPictureBox.Image?.Dispose(); 332 this.PrimesPictureBox.Image = bitmap; 333 } 334 private void Reset() 335 { 336 this.GeneratePrimesMap(this.flip = false, this.inverse = false, this.rotate = false); 337 } 338 private void Flip() 339 { 340 this.GeneratePrimesMap(this.flip = !this.flip, this.inverse, this.rotate); 341 } 342 private void Inverse() 343 { 344 this.GeneratePrimesMap(this.flip, this.inverse = !this.inverse, this.rotate); 345 } 346 private void Rotate() 347 { 348 this.GeneratePrimesMap(this.flip, this.inverse, this.rotate = !this.rotate); 349 } 350 private void GenerateButton_Click(object sender, EventArgs e) 351 { 352 if (this.PrimesPictureBox.Image is Bitmap bitmap 353 && bitmap.Clone() is Bitmap clone) 354 { 355 bitmap.Dispose(); 356 this.PrimesPictureBox.Image = null; 357 this.PrimesPictureBox.Image = Fourier(clone); 358 clone.Dispose(); 359 } 360 } 361 362 private void FormMain_Resize(object sender, EventArgs e) 363 { 364 this.GeneratePrimesMap(this.flip, this.inverse, this.rotate); 365 } 366 367 private void FormMain_Load(object sender, EventArgs e) 368 { 369 this.GeneratePrimesMap(); 370 } 371 372 private void PrimesPictureBox_MouseMove(object sender, MouseEventArgs e) 373 { 374 if (this.primes != null && PrimesPictureBox.Image != null) 375 { 376 var x = e.X; 377 var y = e.Y; 378 if (x >= 0 && x < PrimesPictureBox.Image.Width 379 && y >= 0 && y < PrimesPictureBox.Image.Height) 380 { 381 var cp = new Point(PrimesPictureBox.Image.Width >> 1, PrimesPictureBox.Image.Height >> 1); 382 var dp = new Point(x - cp.X, cp.Y - y); 383 var mp = new Point(dp.X + (this.length >> 1), dp.Y + (this.length >> 1) - 1); 384 if (mp.X > this.length - 1) 385 mp.X = this.length - 1; 386 if (mp.Y > this.length - 1) 387 mp.Y = this.length - 1; 388 if (mp.X < 0) 389 mp.X = 0; 390 if (mp.Y < 0) 391 mp.Y = 0; 392 393 var p = this.primes![(int)mp.X, (int)mp.Y]; 394 long n = p.Item2; 395 bool b = p.Item3; 396 var t = Math.Atan2(dp.Y, dp.X) / Math.PI * 180.0; 397 this.InfoLabel.Text = $"{(b ? 'P' : 'C')}:{n} ({dp.X},{dp.Y},{t:N2}°)"; 398 } 399 } 400 } 401 402 private void ResetButton_Click(object sender, EventArgs e) 403 { 404 this.Reset(); 405 } 406 407 private void FlipButton_Click(object sender, EventArgs e) 408 { 409 this.Flip(); 410 } 411 412 private void InverseButton_Click(object sender, EventArgs e) 413 { 414 this.Inverse(); 415 } 416 417 private void RotateButton_Click(object sender, EventArgs e) 418 { 419 this.Rotate(); 420 } 421} 422
《再论自然数全加和 - 质数螺旋》 是转载文章,点击查看原文。