-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
694 lines (656 loc) · 55.1 KB
/
Copy pathindex.html
File metadata and controls
694 lines (656 loc) · 55.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
<!DOCTYPE html>
<html lang="ja">
<head>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8270840061039680" crossorigin="anonymous"></script>
<meta charset="UTF-8">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RSYX6L0L61"></script>
<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-RSYX6L0L61');</script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>チューリングパターン・反応拡散シミュレーター — 無料オンライン計算機 | NovaSolver</title>
<meta name="description" content="NovaSolverのチューリングパターン・反応拡散シミュレーターで、ヒョウの斑点やシマウマの縞などの自己組織化パターンを生成。パラメータを調整するだけで、迷路や螺旋など複雑な模様の形成過程をリアルタイムで体験できます。生命のデザインの秘密に迫る、直感的なシミュレーションツールです。">
<link rel="canonical" href="https://novasolver.jp/tools/turing-patterns.html">
<link rel="alternate" hreflang="ja" href="https://novasolver.jp/tools/turing-patterns.html">
<link rel="alternate" hreflang="en" href="https://novasolver.jp/en/tools/turing-patterns.html">
<link rel="alternate" hreflang="zh-Hans" href="https://novasolver.jp/zh/tools/turing-patterns.html">
<link rel="alternate" hreflang="x-default" href="https://novasolver.jp/tools/turing-patterns.html">
<meta name="robots" content="index,follow">
<meta property="og:title" content="チューリングパターン・反応拡散シミュレーター — 自己組織化パターン可視化 | NovaSolver">
<meta property="og:description" content="Gray-Scottモデルによる反応拡散シミュレーター。ヒョウの斑点・シマウマの縞・迷路・螺旋など自己組織化パターンをリアルタイム生成。">
<meta property="og:type" content="website">
<meta property="og:url" content="https://novasolver.jp/tools/turing-patterns.html">
<meta property="og:image" content="https://novasolver.jp/assets/images/general/blueprint.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="675">
<meta property="og:image:alt" content="Turing reaction-diffusion pattern simulator showing self-organizing spots and stripes">
<meta property="og:site_name" content="NovaSolver">
<meta property="og:locale" content="ja_JP">
<meta property="og:locale:alternate" content="en_US">
<meta property="og:locale:alternate" content="zh_CN">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://novasolver.jp/assets/images/general/blueprint.jpg">
<meta name="twitter:site" content="@novasolver_jp">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="icon" type="image/png" sizes="256x256" href="/favicon.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" crossorigin="anonymous">
<script type="application/ld+json">{
"@context": "https://schema.org",
"@graph": [
{
"@type": "SoftwareApplication",
"name": "チューリングパターン・反応拡散シミュレーター",
"description": "Gray-Scottモデルによる2次元反応拡散方程式のインタラクティブシミュレーター。フィードレート・キルレートを変化させることで、ヒョウの斑点・シマウマの縞・迷路・螺旋など多様な自己組織化パターンをリアルタイム生成できる。",
"applicationCategory": "EngineeringApplication",
"operatingSystem": "Web",
"url": "https://novasolver.jp/tools/turing-patterns.html",
"datePublished": "2026-04-06",
"dateModified": "2026-04-06",
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "JPY" },
"publisher":{ "@type": "Organization", "name": "NovaSolver Project", "url": "https://novasolver.jp" },
"inLanguage": "ja",
"isAccessibleForFree": true,
"featureList": [
"200×200グリッドのGray-Scott反応拡散方程式リアルタイムシミュレーション",
"斑点・縞・迷路・螺旋・細胞分裂プリセット",
"クリックでパターン種を追加",
"5種類のカラースキーム",
"フィードレート・キルレート・拡散係数のリアルタイム調整"
],
"keywords": "チューリングパターン,反応拡散方程式,Gray-Scottモデル,自己組織化,パターン形成,活性因子・抑制因子"
},{
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "チューリングパターンとは何ですか?",
"acceptedAnswer": {
"@type": "Answer",
"text": "チューリングパターンとは、1952年にアラン・チューリングが提唱した反応拡散系から自発的に生じる空間的模様です。活性化因子(自己触媒的)と抑制因子(拡散が速い)の2つの化学物質の相互作用により、均一な状態が不安定化して斑点・縞・迷路などの規則的なパターンが形成されます。ヒョウの斑点、シマウマの縞、熱帯魚の模様など、自然界の多くのパターンがこのメカニズムで説明されます。"
}
},{
"@type": "Question",
"name": "Gray-Scottモデルはどのような方程式ですか?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Gray-Scottモデルは∂u/∂t = Du·∇²u - u·v² + f·(1-u)、∂v/∂t = Dv·∇²v + u·v² - (f+k)·vという2つの偏微分方程式で表されます。uが活性化因子(化学物質A)、vが抑制因子(化学物質B)の濃度を表します。fはフィードレート(外部からの供給量)、kはキルレート(消費率)で、この2つのパラメータを変化させるだけで驚くほど多様なパターンが現れます。"
}
},{
"@type": "Question",
"name": "反応拡散系はCAEでどう活用されますか?",
"acceptedAnswer": {
"@type": "Answer",
"text": "CAE・工学分野では、反応拡散方程式は燃焼フロントの伝播、腐食の進行、凝固フロントの安定性解析、バイオメカニクスでの細胞増殖モデルなどに応用されます。また、トポロジー最適化でパターン形成を制御したり、表面処理の不均一性を予測するモデルとしても使われます。チューリングの不安定性は、均一解が意図せず破れる「不安定現象」の原型として数値解析の検証にも活用されます。"
}
},{
"@type": "Question",
"name": "フィードレートとキルレートを変えるとなぜパターンが変わるのですか?",
"acceptedAnswer": {
"@type": "Answer",
"text": "フィードレートf(外部からの化学物質A補給速度)とキルレートk(化学物質Bの除去速度)のバランスによって、系の安定性が変化します。fが低くkが適度なら螺旋や斑点、fが高めでkが低めなら縞模様、f・kが特定の組み合わせでは「ミトーシス(細胞分裂的増殖)」が現れます。数学的には固有値解析でこの分岐を予測でき、パラメータ空間に「パターン図」を描くことができます。"
}
}
]
},{
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "NovaSolver", "item": "https://novasolver.jp/" },{ "@type": "ListItem", "position": 2, "name": "シミュレーター", "item": "https://novasolver.jp/tools/" },{ "@type": "ListItem", "position": 3, "name": "チューリングパターン", "item": "https://novasolver.jp/tools/turing-patterns.html" }
]
}
]
}</script>
<link rel="stylesheet" href="/tools/tools-common.css?v20260510r6">
<link href="/tools/tool-ux-template.css?v20260529r1" rel="stylesheet"/>
<style>
*{ box-sizing: border-box; margin: 0; padding: 0; }:root{
--navy: #001F3F;
--accent: #007BFF;
--accent2: #00B4D8;
--bg: #F8F9FA;
--card: #ffffff;
--text: #1a1a2e;
--muted: #6c757d;
--border: #dee2e6;
}
html,body{overflow-x:hidden}
body { font-family: 'Noto Sans JP', sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; }
header { background: var(--navy); color: #fff; padding: 0 24px; }
.header-inner { max-width: 1200px; margin: 0 auto; display: flex; align-items: center; gap: 16px; height: 56px; }
.header-logo { font-size: 0.85rem; font-weight: 600; color: #fff; text-decoration: none; opacity: .8; }
.header-logo:hover { opacity: 1; }
.header-sep { color: rgba(255,255,255,.3); }
.header-title { font-size: 1rem; font-weight: 700; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; ;flex:1}
.hero { background: linear-gradient(135deg, #0a0a1a 0%, #001F3F 40%, #003875 75%, #0056a8 100%); color: #fff; padding: 40px 0 36px; position: relative; overflow: hidden; }
.hero::before { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse 60% 80% at 80% 50%, rgba(0,180,216,.12) 0%, transparent 70%); pointer-events: none; }
.hero-inner { max-width: 1200px; margin: 0 auto; position: relative; padding: 0 24px; }
.hero-badge { display: inline-block; background: rgba(0,180,216,.2); color: var(--accent2); font-size: 0.72rem; font-weight: 700; letter-spacing: .1em; padding: 4px 12px; border-radius: 20px; border: 1px solid rgba(0,180,216,.4); margin-bottom: 12px; text-transform: uppercase; }
.hero h1 { font-size: clamp(1.5rem, 3.5vw, 2.2rem); font-weight: 800; margin-bottom: 10px; line-height: 1.2; }
.hero-sub { color: rgba(255,255,255,.75); font-size: 0.92rem; line-height: 1.7; max-width: 640px; }
.hero-meta { display: flex; gap: 20px; margin-top: 18px; flex-wrap: wrap; }
.hero-meta span { font-size: 0.78rem; color: rgba(255,255,255,.5); display: flex; align-items: center; gap: 5px; }
.hero-meta i { color: var(--accent2); }.sim-outer{ max-width: 1100px; margin: 0 auto; padding: 28px 24px 0; overflow-x: hidden; }.sim-outer > *{ min-width: 0; max-width: 100%; }
.canvas-stage { position: relative; }
#turing-canvas {
width: 100%;
aspect-ratio: 1;
cursor: crosshair;
border-radius: 12px;
display: block;
box-shadow: 0 4px 24px rgba(0,0,0,.2);
image-rendering: pixelated;
}.controls-panel{ display: flex; flex-direction: column; gap: 14px; }.panel{ background: var(--card); border-radius: 14px; padding: 18px 20px; box-shadow: 0 2px 12px rgba(0,0,0,.06); border: 1px solid var(--border); }.panel-title{ font-size: 0.68rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }.panel-title i{ color: var(--accent); font-size: 0.72rem; }.panel-title::after{ content: ''; flex: 1; height: 1px; background: var(--border); }.preset-grid{ display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }.preset-btn{ background: #f0f4f8; border: 1px solid var(--border); border-radius: 8px; padding: 8px 6px; font-size: 0.75rem; font-family: 'Noto Sans JP', sans-serif; color: var(--text); cursor: pointer; text-align: center; transition: all .15s; line-height: 1.3; }.preset-btn:hover{ background: var(--accent); color: #fff; border-color: var(--accent); }.preset-btn.active{ background: var(--accent); color: #fff; border-color: var(--accent); }.slider-row{ margin-bottom: 12px; }.slider-label{ display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; }.slider-name{ font-size: 0.78rem; font-weight: 600; color: var(--text); }.slider-val{ font-size: 0.78rem; font-family: 'Roboto Mono', monospace; color: var(--accent); font-weight: 700; background: #e8f0fe; padding: 2px 7px; border-radius: 5px; }input[type=range]{ width: 100%; height: 5px; accent-color: var(--accent); cursor: pointer; }.color-grid{ display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }.color-btn{ height: 28px; border-radius: 6px; border: 2px solid transparent; cursor: pointer; transition: border-color .15s; }.color-btn.active{ border-color: var(--accent); }.color-classic{ background: linear-gradient(to right, #00008b, #0066ff, #ffff00); }.color-fire{ background: linear-gradient(to right, #000, #8b0000, #ff4500, #ffd700); }.color-ocean{ background: linear-gradient(to right, #000528, #006994, #00bcd4, #e0f7fa); }.color-gray{ background: linear-gradient(to right, #000, #888, #fff); }.color-neon{ background: linear-gradient(to right, #000, #ff00ff, #00ff00); }.action-btn{ width: 100%; padding: 10px; border: none; border-radius: 8px; font-family: 'Noto Sans JP', sans-serif; font-size: 0.82rem; font-weight: 600; cursor: pointer; transition: all .15s; display: flex; align-items: center; justify-content: center; gap: 8px; }.btn-primary{ background: var(--accent); color: #fff; }.btn-primary:hover{ background: #0056b3; }.btn-secondary{ background: #f0f4f8; color: var(--text); border: 1px solid var(--border); }.btn-secondary:hover{ background: #e0e8f0; }.btn-row{ display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }.stats-grid{ display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }.stat-card{ background: #f8f9fa; border-radius: 8px; padding: 10px 12px; border: 1px solid var(--border); }.stat-label{ font-size: 0.65rem; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }.stat-value{ font-size: 1rem; font-weight: 700; color: var(--navy); font-family: 'Roboto Mono', monospace; margin-top: 2px; }.theory-section{ max-width: 1100px; margin: 32px auto 48px; padding: 0 24px; }.theory-card{ background: var(--card); border-radius: 16px; padding: 32px; box-shadow: 0 2px 12px rgba(0,0,0,.06); border: 1px solid var(--border); }.theory-card h2{ font-size: 1.2rem; font-weight: 800; color: var(--navy); margin-bottom: 20px; border-left: 4px solid var(--accent); padding-left: 12px; }.theory-card h3{ font-size: 0.95rem; font-weight: 700; margin: 20px 0 8px; color: var(--text); }.theory-card p{ font-size: 0.88rem; line-height: 1.8; color: #444; margin-bottom: 12px; }.eq-box{ background: #f0f4f8; border-left: 3px solid var(--accent); padding: 14px 18px; border-radius: 0 8px 8px 0; margin: 12px 0; font-family: 'Roboto Mono', monospace; font-size: 0.82rem; color: var(--navy); }.chat-section{ max-width: 1100px; margin: 0 auto 48px; padding: 0 24px; }.chat-card{ background: var(--card); border-radius: 16px; padding: 32px; box-shadow: 0 2px 12px rgba(0,0,0,.06); border: 1px solid var(--border); }.chat-card h2{ font-size: 1.1rem; font-weight: 800; color: var(--navy); margin-bottom: 20px; }.chat-bubble{ display: flex; gap: 12px; margin-bottom: 16px; align-items: flex-start; }.chat-bubble.student{ flex-direction: row; }.chat-bubble.prof{ flex-direction: row-reverse; }.chat-icon{ font-size: 1.5rem; flex-shrink: 0; }.chat-text{ background: #f0f4f8; border-radius: 12px; padding: 12px 16px; font-size: 0.88rem; line-height: 1.7; max-width: 80%; }.chat-bubble.prof .chat-text{ background: #e8f0fe; }
footer { background: var(--navy); color: rgba(255,255,255,.5); padding: 24px; text-align: center; font-size: 0.78rem; }
footer a { color: rgba(255,255,255,.7); text-decoration: none; }
footer a:hover { color: #fff; }@media (max-width: 820px){
.main { grid-template-columns: 1fr; }.controls-panel{ order: 1; }
.canvas-stage { order: 0; }
}/* === Mobile Compact === */
@media(max-width:820px){
.hero h1{font-size:1.15rem;margin-bottom:4px}
.hero-sub{font-size:0.78rem;line-height:1.4}
.hero-badge{margin-bottom:6px;font-size:0.65rem;padding:3px 8px}.panel-title{margin-bottom:10px;font-size:0.65rem}.param-group{margin-bottom:8px}.param-label{margin-bottom:3px}.param-name{font-size:0.78rem}.param-value{font-size:0.76rem;padding:1px 6px}input[type=range]{height:3px;margin:2px 0}.divider{margin:8px 0}.theory-box{font-size:0.78rem;padding:10px 12px;margin-top:10px}.theory-box h3{font-size:0.8rem;margin-bottom:4px}.stat-cards{gap:6px}.stat-card{padding:8px}.stat-card .sv{font-size:0.95rem}.stat-card .sl{font-size:0.62rem}.btn{padding:7px 14px;font-size:0.8rem}.btn-group{gap:6px;margin-bottom:8px}.preset-btn{padding:4px 8px;font-size:0.7rem}.cae-note{padding:8px 10px;font-size:0.73rem;margin-top:8px}.toggle-btn{padding:4px 10px;font-size:0.73rem}
}@media(max-width:640px){
.hero h1{font-size:1.05rem}
.hero-sub{display:none}
.hero-badge{margin-bottom:4px;font-size:0.6rem;padding:2px 6px}.panel-title{margin-bottom:6px;font-size:.6rem}.param-group{margin-bottom:4px}.param-name{font-size:.72rem}.param-value{font-size:0.73rem}.divider{margin:4px 0}.theory-box{padding:8px 10px;margin-top:8px}.viz-panel{padding:12px;border-radius:10px}.stat-card{padding:6px}.stat-card .sv{font-size:0.85rem}.btn{padding:6px 12px;font-size:0.78rem}.preset-btn{padding:3px 6px;font-size:0.68rem}
.param-group{margin-bottom:2px}.field-header{margin-bottom:0}.param-label{margin-bottom:0}.num-wrap{gap:2px}.num-input{width:56px;padding:1px 3px;font-size:.74rem;border-radius:4px}.num-unit{font-size:.68rem;min-width:16px}.param-name{font-size:.71rem}.param-value{font-size:.71rem;padding:1px 5px;min-width:auto}input[type=range]{height:3px;margin:0}select{padding:3px 5px;font-size:.74rem;margin-bottom:2px}.divider{margin:3px 0;opacity:.4}.panel{padding:7px}.panel-title{margin-bottom:4px;font-size:.58rem}
}/* === Controls Compact === */
@media(max-width:820px){
.controls{;padding:14px}.controls .field,.controls .param-group,.controls .ctrl-group{margin-bottom:8px}.controls label{font-size:0.78rem}.controls select,.controls input[type=number]{font-size:0.8rem;padding:5px 8px}
}@media(max-width:640px){
.controls{padding:10px}.controls .field,.controls .param-group,.controls .ctrl-group{margin-bottom:6px}.controls label{font-size:0.75rem}
}.explanation{max-width:1200px;margin:0 auto;padding:40px 24px 60px}.explanation h2{font-size:19px;font-weight:700;color:var(--accent);margin:24px 0 10px;border-left:3px solid var(--accent);padding-left:12px}.explanation p{font-size:15px;line-height:1.8;color:var(--text);margin-bottom:12px}.fblock{background:rgba(0,123,255,.04);border:1px solid rgba(0,123,255,.15);border-radius:8px;padding:16px 20px;margin:14px 0;overflow-x:auto}.fblock p{margin-bottom:8px;font-size:14px;color:var(--text)}.chat{background:rgba(0,123,255,.04);border:1px solid rgba(0,123,255,.1);border-radius:12px;padding:16px;margin:20px 0}.cmsg{display:flex;gap:10px;margin-bottom:12px;align-items:flex-start}.cmsg .ico{font-size:22px;flex-shrink:0}.cmsg .bub{background:var(--card);border-radius:8px;padding:10px 14px;font-size:14px;line-height:1.7;color:var(--text);border:1px solid var(--border)}.cmsg.st .bub{border-left:3px solid var(--accent2)}.cmsg.pr .bub{border-left:3px solid #f59e0b}
/* codex-main-normalize */
.main > .panel,.main > .viz-panel{min-width:0;max-width:100%;background:transparent!important;border:0!important;box-shadow:none!important;padding:0!important;margin:0!important;overflow:visible!important}
.main > .viz-panel{display:flex;flex-direction:column;gap:16px}.sim-wrap.main > .panel{flex-shrink:0}.sim-wrap.main > .viz-panel{flex:1;min-width:220px}
@media(max-width:820px){.main > .panel,.main > .viz-panel{width:100%}}
</style>
<script>window.MathJax={tex:{inlineMath:[['$','$']],displayMath:[['$$','$$'],['\\[','\\]']]},options:{skipHtmlTags:['script','noscript','style','textarea','pre']}};</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" async></script>
<script src="/tools/tools-common.js?v20260511r13"></script>
</head>
<body>
<header>
<div class="header-inner">
<a href="/tools/index.html" class="header-logo">NovaSolver</a>
<span class="header-sep">/</span>
<span class="header-title">チューリングパターン・シミュレーター</span>
<nav class="lang-nav">
<a href="/tools/turing-patterns.html" class="active">JA</a>
<a href="/en/tools/turing-patterns.html">EN</a>
<a href="/zh/tools/turing-patterns.html">ZH</a>
</nav>
<a href="/tools/index.html" class="header-back"><i class="fas fa-arrow-left"></i> 戻る</a>
</div>
</header>
<div class="hero">
<div class="hero-inner">
<div class="hero-badge"><i class="fas fa-dna"></i> 化学工学</div>
<h1>チューリングパターン<br>反応拡散シミュレーター</h1>
<p class="hero-sub">Gray-Scottモデルによる自己組織化パターン生成。フィードレートとキルレートを変化させるだけで、ヒョウの斑点からシマウマの縞、螺旋構造まで多様なパターンが現れる。クリックで新たな種を植え付けよう。</p>
<div class="hero-meta">
<span><i class="fas fa-microchip"></i> Gray-Scott Model</span>
<span><i class="fas fa-bolt"></i> Float32Array高速演算</span>
<span><i class="fas fa-mouse-pointer"></i> クリックでインタラクション</span>
<span><i class="fas fa-palette"></i> 5種カラースキーム</span>
</div>
</div>
</div>
<div class="sim-outer">
<div class="main">
<div class="panel">
<div class="canvas-stage">
<div class="chart-card"><div class="chart-title"><i class="fas fa-chart-line"></i> チューリングパターン</div><canvas id="turing-canvas" width="200" height="200"></canvas></div>
</div>
</div>
<div class="viz-panel">
<div class="controls-panel">
<div class="panel">
<div class="panel-title"><i class="fas fa-shapes"></i> プリセットパターン</div>
<div class="preset-grid">
<button class="preset-btn" onclick="setPreset('spots')" id="preset-spots">🐆 斑点<br><small>f=0.035, k=0.065</small></button>
<button class="preset-btn" onclick="setPreset('stripes')" id="preset-stripes">🦓 縞模様<br><small>f=0.055, k=0.062</small></button>
<button class="preset-btn" onclick="setPreset('labyrinth')" id="preset-labyrinth">🌀 迷路<br><small>f=0.037, k=0.060</small></button>
<button class="preset-btn" onclick="setPreset('spirals')" id="preset-spirals">🌪 螺旋<br><small>f=0.012, k=0.050</small></button>
<button class="preset-btn" onclick="setPreset('mitosis')" id="preset-mitosis">🔬 細胞分裂<br><small>f=0.0367, k=0.0649</small></button>
<button class="preset-btn" onclick="setPreset('coral')" id="preset-coral">🪸 珊瑚<br><small>f=0.022, k=0.059</small></button>
</div>
</div>
<div class="panel">
<div class="panel-title"><i class="fas fa-sliders-h"></i> パラメータ</div>
<div class="slider-row">
<div class="slider-label"><span class="slider-name">フィードレート f</span><div class="num-wrap"><input type="number" class="num-input" id="val-f" value="0.035" min="0.010" max="0.080" step="0.001" oninput="syncFromNum('sl-f','val-f')"><span class="num-unit"></span></div></div>
<input type="range" id="sl-f" min="0.010" max="0.080" step="0.001" value="0.035" oninput="syncToNum('sl-f','val-f');updateParam('f',this.value)">
</div>
<div class="slider-row">
<div class="slider-label"><span class="slider-name">キルレート k</span><div class="num-wrap"><input type="number" class="num-input" id="val-k" value="0.065" min="0.040" max="0.073" step="0.001" oninput="syncFromNum('sl-k','val-k')"><span class="num-unit"></span></div></div>
<input type="range" id="sl-k" min="0.040" max="0.073" step="0.001" value="0.065" oninput="syncToNum('sl-k','val-k');updateParam('k',this.value)">
</div>
<div class="slider-row">
<div class="slider-label"><span class="slider-name">拡散係数 Du</span><div class="num-wrap"><input type="number" class="num-input" id="val-du" value="0.2097" min="0.10" max="0.40" step="0.005" oninput="syncFromNum('sl-du','val-du')"><span class="num-unit"></span></div></div>
<input type="range" id="sl-du" min="0.10" max="0.40" step="0.005" value="0.2097" oninput="syncToNum('sl-du','val-du');updateParam('Du',this.value)">
</div>
<div class="slider-row">
<div class="slider-label"><span class="slider-name">拡散係数 Dv</span><div class="num-wrap"><input type="number" class="num-input" id="val-dv" value="0.1050" min="0.05" max="0.20" step="0.002" oninput="syncFromNum('sl-dv','val-dv')"><span class="num-unit"></span></div></div>
<input type="range" id="sl-dv" min="0.05" max="0.20" step="0.002" value="0.1050" oninput="syncToNum('sl-dv','val-dv');updateParam('Dv',this.value)">
</div>
<div class="slider-row">
<div class="slider-label"><span class="slider-name">速度 (steps/frame)</span><span class="slider-val" id="val-spd">8</span></div>
<input type="range" id="sl-spd" min="1" max="20" step="1" value="8" oninput="syncToNum('sl-spd','sl-spdNum');updateParam('speed',this.value)">
<input type="number" class="num-input" id="sl-spdNum" value="8" min="1" max="20" step="1" style="width:70px;margin-left:6px;" oninput="syncFromNum('sl-spd','sl-spdNum')">
</div>
</div>
<div class="panel">
<div class="panel-title"><i class="fas fa-palette"></i> カラースキーム</div>
<div class="color-grid">
<div class="color-btn color-classic active" onclick="setColorScheme('classic')" title="クラシック (青/黄)"></div>
<div class="color-btn color-fire" onclick="setColorScheme('fire')" title="炎"></div>
<div class="color-btn color-ocean" onclick="setColorScheme('ocean')" title="海洋"></div>
<div class="color-btn color-gray" onclick="setColorScheme('gray')" title="グレースケール"></div>
<div class="color-btn color-neon" onclick="setColorScheme('neon')" title="ネオン"></div>
</div>
</div>
<div class="panel">
<div class="panel-title"><i class="fas fa-chart-bar"></i> 統計</div>
<div class="chart-card"><div class="chart-title"><i class="fas fa-calculator"></i> 計算結果</div>
<div class="stats-grid">
<div class="stat-card"><div class="stat-label">ステップ数</div><div class="stat-value" id="stat-steps">0</div></div>
<div class="stat-card"><div class="stat-label">平均 v 濃度</div><div class="stat-value" id="stat-avgv">0.000</div></div>
<div class="stat-card"><div class="stat-label">パターン種</div><div class="stat-value" id="stat-type" style="font-size:.75rem;font-family:'Noto Sans JP',sans-serif">斑点</div></div>
<div class="stat-card"><div class="stat-label">FPS</div><div class="stat-value" id="stat-fps">--</div></div>
</div>
</div>
</div>
<div class="panel">
<div class="panel-title"><i class="fas fa-tools"></i> アクション</div>
<div class="btn-row" style="margin-bottom:8px">
<button class="action-btn btn-primary" onclick="randomizeSeed()"><i class="fas fa-random"></i> 種を変える</button>
<button class="action-btn btn-secondary" onclick="resetSim()"><i class="fas fa-undo"></i> リセット</button>
</div>
<button class="action-btn btn-secondary" onclick="togglePause()" id="pause-btn"><i class="fas fa-pause"></i> 一時停止</button>
</div>
<p style="font-size:0.75rem;color:var(--muted);text-align:center;padding:4px 0"><i class="fas fa-hand-pointer"></i> キャンバスをクリックして化学物質Bを注入</p>
</div>
</div>
</div>
</div>
<div class="theory-section">
<div class="theory-card">
<h2>理論:チューリングの反応拡散方程式</h2>
<h3>Gray-Scottモデル</h3>
<p>このシミュレーターはGray-Scottモデルを数値的に解きます。化学物質A(濃度 u)と化学物質B(濃度 v)が空間中で反応・拡散します。</p>
<div class="eq-box">
∂u/∂t = Du · ∇²u − u·v² + f·(1−u)<br>
∂v/∂t = Dv · ∇²v + u·v² − (f+k)·v
</div>
<p>反応項 <strong>u·v²</strong> は「AとBが2対1で反応し、Bが3つになる自己触媒反応」を表します。fはフィードレート(Aの補給量)、kはキルレート(Bの消費率)です。</p>
<h3>パターン形成の直感</h3>
<p>Duが大きい(Aが速く拡散)とAは広域に均一化されます。一方DvはDuより小さく設定されているため、Bは局所的に高濃度域を保ちます。この「遅い活性化因子・速い抑制因子」の非対称性がチューリング不安定性を生み、空間的な濃度波を作り出します。</p>
<h3>CAE・工学への応用</h3>
<p>反応拡散方程式は燃焼フロントの伝播解析、金属腐食の局所化モデル、凝固界面の安定性解析、バイオエンジニアリングでの組織パターン形成に応用されます。チューリング不安定性は均一解が崩れる典型例として、数値解析の検証ベンチマークにも使われます。</p>
</div>
</div>
<section class="explanation">
<h2>反応拡散とチューリングパターンとは</h2>
<div class="chat">
<div class="cmsg st"><span class="ico">🙋</span>
<div class="bub">このシミュレーターで作れるヒョウの斑点やシマウマの縞って、どうやってコンピューターで再現してるんですか?</div>
</div>
<div class="cmsg pr"><span class="ico">🎓</span>
<div class="bub">大まかに言うと、2種類の「仮想的な化学物質」が反応しながら広がる様子を計算してるんだ。例えば、物質Aは自分自身を増やす性質(活性化因子)があって、物質BはAを消す性質(抑制因子)がある。この2つが、広がる速さ(拡散係数)を変えて相互作用すると、均一だった状態から自発的に模様が浮かび上がるんだよ。実際に、上の「フィードレート」と「キルレート」のスライダーをちょっと動かしてみて、模様がどう変わるか確認してみよう。</div>
</div>
<div class="cmsg st"><span class="ico">🙋</span>
<div class="bub">え、自発的に模様が? 最初はランダムな状態からスタートするだけなのに、規則正しい模様になるのが不思議です。どういう条件だと縞になったり、斑点になったりするんですか?</div>
</div>
<div class="cmsg pr"><span class="ico">🎓</span>
<div class="bub">それがチューリングパターンの面白いところで、カギは2つの物質の「広がる速さの差」にあるんだ。抑制因子の方が活性化因子よりずっと速く広がると、活性化因子が増えすぎるのを局所的に抑えられる。その結果、活性化因子が集まった「島」が斑点になったり、連なって縞になったりする。シミュレーターで「拡散係数B」を大きくして、抑制因子の広がりを速くしてみると、模様の形が変わるのが観察できるよ。</div>
</div>
<div class="cmsg st"><span class="ico">🙋</span>
<div class="bub">なるほど!でも、こういう模様のシミュレーションって、実務では何に使われるんですか? お絵描きツールみたいなものですか?</div>
</div>
<div class="cmsg pr"><span class="ico">🎓</span>
<div class="bub">いやいや、実はすごく応用範囲が広いんだ。例えば、新しい素材の表面に微細な模様(ナノパターン)を自己組織化で作る設計や、生体組織が形作られる発生生物学の研究、さらには都市の人口分布のシミュレーションにも使われる考え方なんだ。このツールで「フィードレート」を極端に低くして「キルレート」を高くすると、迷路みたいな複雑な構造ができるでしょ?ああいう構造は、材料科学では多孔質材料の設計の参考になるんだ。</div>
</div>
</div>
<h2>よくある質問</h2>
<div class="faq-section">
<div class="faq-item">
<button class="faq-q" type="button" onclick="toggleFaq(this)">フィードレートとキルレートの違いは何ですか? <span class="arrow"><i class="fas fa-chevron-down"></i></span></button>
<div class="faq-a">フィードレート(f)はU成分の供給速度、キルレート(k)はV成分の除去速度です。fが大きいと斑点模様、kが大きいと縞模様になりやすい傾向があります。両者のバランスでパターンが決まるため、少しずつ変化させて試すのがコツです。</div>
</div>
<div class="faq-item">
<button class="faq-q" type="button" onclick="toggleFaq(this)">キャンバスをクリックすると何が起こりますか? <span class="arrow"><i class="fas fa-chevron-down"></i></span></button>
<div class="faq-a">クリックした位置に新しい種(U成分の濃度が高い領域)が植え付けられます。これにより、既存のパターンに乱れが生じ、そこから新たな模様が広がっていきます。反応の進行を局所的にリセットしたいときや、複数のパターンを衝突させたいときに便利です。</div>
</div>
<div class="faq-item">
<button class="faq-q" type="button" onclick="toggleFaq(this)">パターンがすぐに消えてしまうのですが、なぜですか? <span class="arrow"><i class="fas fa-chevron-down"></i></span></button>
<div class="faq-a">フィードレートとキルレートの組み合わせが反応拡散系の不安定領域から外れている可能性があります。まずはf=0.035, k=0.065程度の標準値から始め、徐々に調整してください。また、拡散係数の比率Dv/Duが大きすぎるとパターンが形成されにくくなります。</div>
</div>
<div class="faq-item">
<button class="faq-q" type="button" onclick="toggleFaq(this)">このシミュレーションは現実の生物模様を再現できますか? <span class="arrow"><i class="fas fa-chevron-down"></i></span></button>
<div class="faq-a">完全な再現ではなく、チューリングパターンの基本原理に基づく近似モデルです。ヒョウ斑やシマウマ縞など自然界の模様と類似したパターンが生成されますが、実際の生物の発生過程には遺伝子制御など他の要素も関与します。教育やデザインの参考としてご活用ください。</div>
</div>
</div>
<h2>実世界での応用</h2>
<div class="fblock">
<p><strong>発生生物学と形態形成:</strong>生物の胚発生において、手足の指が分かれる位置や、毛根(毛並み)のパターンがどのように決定されるかを説明するモデルとして研究されています。シマウマの縞やヒョウの斑点の形成メカニズムも、この反応拡散系で説明が試みられています。</p>
<p><strong>材料科学とナノ加工:</strong>自己組織化現象を利用して、均一な基板上にナノスケールの規則的な凹凸や孔パターンを形成する技術の基礎理論です。半導体の微細加工や、特殊な光学特性を持つメタマテリアルの設計に応用されます。</p>
<p><strong>生態学と人口動態:</strong>捕食者と被食者の個体数が空間的に分布する様子をモデル化する際に、反応拡散方程式が用いられます。被食者が増える地域と捕食者が駆逐する地域が交互に現れ、斑状の分布パターンを形成することがあります。</p>
<p><strong>コンピュータグラフィックスとデザイン:</strong>自然らしいテクスチャ(毛皮、羽毛、大理石の模様など)をアルゴリズム的に生成する手法として利用されます。パラメータを調整するだけで多様な模様が得られるため、ゲームやVFXの制作現場でも活用される概念です。</p>
</div>
<h2>よくある誤解と注意点</h2>
<div class="fblock">
<p>「パラメータを変えればどんな模様でも自由に作れる」と思いがちですが、実際はフィードレートとキルレートのごく狭い範囲でしか安定したパターンは出現しません。わずかな数値の違いで縞模様が一瞬で均一な状態に消えたり、逆に全面が反応物質で埋め尽くされたりするため、パラメータ調整は非常に繊細です。また、「シミュレーション上の模様が現実の生物模様と完全に一致する」と誤解されがちですが、Gray-Scottモデルはあくまで反応拡散系の原理を再現した数理モデルであり、実際の生物の発生過程における遺伝子制御や物理的制約までは再現していません。さらに、「クリックで種を植え付ければ、クリックした場所から必ずパターンが広がる」と考えがちですが、実際にはパラメータによっては種がすぐに消滅するか、逆に異常に増殖してシミュレーション領域全体を単一色にしてしまうことがあります。初期条件とパラメータの組み合わせによって振る舞いが大きく変わる点に注意が必要です。</p>
</div>
</section>
<!-- codex-static-related-tools:start -->
<section class="related-section static-related-tools" aria-label="関連ツール" data-related-source="turing-patterns.html" style="max-width:1100px;margin:32px auto 0;padding:0 24px">
<h2 style="font-size:1.05rem;line-height:1.35;margin:0 0 14px;color:#102033;display:flex;align-items:center;gap:8px"><i class="fas fa-diagram-project" style="color:#007BFF"></i>関連ツール</h2>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px">
<a class="related-tool-card" href="/tools/reaction-diffusion.html" style="display:flex;gap:12px;align-items:flex-start;padding:14px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;text-decoration:none;color:inherit;box-shadow:0 1px 2px rgba(15,23,42,.04)">
<span style="width:34px;height:34px;border-radius:8px;background:#e6f2ff;color:#007BFF;display:grid;place-items:center;flex:0 0 auto"><i class="fas fa-circle-notch"></i></span>
<span style="display:grid;gap:4px;min-width:0">
<strong style="font-size:.9rem;line-height:1.35;color:#102033">反応拡散シミュレーター</strong>
<span style="font-size:.75rem;line-height:1.45;color:#5f6b7a">反応拡散シミュレーターでGray-Scottモデルを操作し、自然界の模様が生まれる仕組みを体験。斑点や縞模様などのチューリングパターンをリアルタイムで生成・観察できるオンラインツール...</span>
</span>
</a>
<a class="related-tool-card" href="/tools/acid-base-ph.html" style="display:flex;gap:12px;align-items:flex-start;padding:14px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;text-decoration:none;color:inherit;box-shadow:0 1px 2px rgba(15,23,42,.04)">
<span style="width:34px;height:34px;border-radius:8px;background:#e6f2ff;color:#007BFF;display:grid;place-items:center;flex:0 0 auto"><i class="fas fa-vial"></i></span>
<span style="display:grid;gap:4px;min-width:0">
<strong style="font-size:.9rem;line-height:1.35;color:#102033">pH計算シミュレーター</strong>
<span style="font-size:.75rem;line-height:1.45;color:#5f6b7a">pH計算シミュレーターで酸・塩基・緩衝液のpHをリアルタイム計算。強酸から弱酸、Henderson-Hasselbalch式を用いた緩衝液のpH計算、滴定曲線のグラフ表示まで、化学・...</span>
</span>
</a>
<a class="related-tool-card" href="/tools/blood-type-genetics.html" style="display:flex;gap:12px;align-items:flex-start;padding:14px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;text-decoration:none;color:inherit;box-shadow:0 1px 2px rgba(15,23,42,.04)">
<span style="width:34px;height:34px;border-radius:8px;background:#e6f2ff;color:#007BFF;display:grid;place-items:center;flex:0 0 auto"><i class="fas fa-dna"></i></span>
<span style="display:grid;gap:4px;min-width:0">
<strong style="font-size:.9rem;line-height:1.35;color:#102033">血液型遺伝シミュレーター</strong>
<span style="font-size:.75rem;line-height:1.45;color:#5f6b7a">ABO式・Rh式血液型の遺伝子型(AA/AO/BB/BO等)を入力し、子の血液型確率を計算・可視化。メンデルの遺伝法則を血液型で学べる高校生物ツール。</span>
</span>
</a>
<a class="related-tool-card" href="/tools/car-braking-distance.html" style="display:flex;gap:12px;align-items:flex-start;padding:14px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;text-decoration:none;color:inherit;box-shadow:0 1px 2px rgba(15,23,42,.04)">
<span style="width:34px;height:34px;border-radius:8px;background:#e6f2ff;color:#007BFF;display:grid;place-items:center;flex:0 0 auto"><i class="fas fa-flask"></i></span>
<span style="display:grid;gap:4px;min-width:0">
<strong style="font-size:.9rem;line-height:1.35;color:#102033">車の制動距離・停車距離計算機</strong>
<span style="font-size:.75rem;line-height:1.45;color:#5f6b7a">速度・路面摩擦係数・反応時間を変えて自動車の制動距離と停車距離をリアルタイム計算。空走距離・制動距離の内訳グラフ付き。安全運転の物理を直感的に学べる無料シミュレーター。</span>
</span>
</a>
<a class="related-tool-card" href="/tools/cell-division.html" style="display:flex;gap:12px;align-items:flex-start;padding:14px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;text-decoration:none;color:inherit;box-shadow:0 1px 2px rgba(15,23,42,.04)">
<span style="width:34px;height:34px;border-radius:8px;background:#e6f2ff;color:#007BFF;display:grid;place-items:center;flex:0 0 auto"><i class="fas fa-microscope"></i></span>
<span style="display:grid;gap:4px;min-width:0">
<strong style="font-size:.9rem;line-height:1.35;color:#102033">細胞分裂・有糸分裂シミュレーター</strong>
<span style="font-size:.75rem;line-height:1.45;color:#5f6b7a">細胞分裂・有糸分裂シミュレーターで、間期から細胞質分裂までの全過程をアニメーションで学べます。分裂速度や細胞種類を変更しながら、細胞の指数関数的増殖をリアルタイムのグラフで確認。生物...</span>
</span>
</a>
<a class="related-tool-card" href="/tools/cell-potential.html" style="display:flex;gap:12px;align-items:flex-start;padding:14px;border:1px solid #e2e8f0;border-radius:8px;background:#fff;text-decoration:none;color:inherit;box-shadow:0 1px 2px rgba(15,23,42,.04)">
<span style="width:34px;height:34px;border-radius:8px;background:#e6f2ff;color:#007BFF;display:grid;place-items:center;flex:0 0 auto"><i class="fas fa-flask"></i></span>
<span style="display:grid;gap:4px;min-width:0">
<strong style="font-size:.9rem;line-height:1.35;color:#102033">膜電位・ネルンスト式 シミュレーター</strong>
<span style="font-size:.75rem;line-height:1.45;color:#5f6b7a">膜電位とネルンスト式をオンラインでシミュレーション。イオン濃度や透過性をスライダーで調整し、ゴールドマン方程式による膜電位の計算や活動電位の波形変化をリアルタイムに可視化できます。生...</span>
</span>
</a>
</div>
</section>
<!-- codex-static-related-tools:end -->
<div class="howto-card howto-guide">
<h3>使い方ガイド</h3>
<ol>
<li>val-f(フィードレート)を0.02~0.08の範囲で設定し、反応物Aの供給速度を制御します</li>
<li>val-k(キル率)を0.045~0.065で調整して、反応物Bの消費速度を決定し、パターンの密度を変更します</li>
<li>val-du(Aの拡散係数)とval-dv(Bの拡散係数)を1:5~1:8の比率で設定し、縞状または斑点状パターンの形成を選択します</li>
<li>シミュレーション開始後、1000~5000イテレーション経過時点でパターンの自己組織化を観察します</li>
</ol>
</div>
<div class="howto-card howto-example">
<h3>具体的な計算例</h3>
<p>ヒョウの斑点パターンを生成する場合、f=0.055、k=0.062、Du=0.16、Dv=0.80を設定します。反応拡散方程式∂u/∂t=Du∇²u+f(1-u)-uv²、∂v/∂t=Dv∇²v-kv+uv²を100×100グリッド上で計算すると、約2000イテレーション後に直径8~12ピクセルの円形斑点が規則正しく配置されます。シマウマの縞模様はf=0.030、k=0.050で同じDu/Dv比を保つと、幅6ピクセルの平行線構造が出現します。計算時間は標準CPU環境で約15秒/1000イテレーション。</p>
</div>
<div class="howto-card howto-notes">
<h3>実務での注意点</h3>
<ol>
<li>f値が0.06を超えるとパターンが不安定化し、ノイズのみが残るため、段階的に0.001刻みで調整してください</li>
<li>Du/Dv比が1:3以下またはDu≥0.5の場合、解が発散するため、sl-duとsl-dvの上限値を厳守します</li>
<li>初期条件にランダムノイズが必須です。均一分布では対称性のため、ほぼすべてのパターンが不可視化されます</li>
<li>実装時、時間刻み幅Δt=0.5、空間刻み幅Δx=1.0でLaplacian計算には5点ステンシルを使用してください</li>
</ol>
</div>
<footer style="background:#001F3F;color:rgba(255,255,255,.7);padding:24px;margin-top:32px;text-align:center">
<div style="max-width:1200px;margin:0 auto">
<div style="font-weight:700;color:#fff;margin-bottom:8px">NovaSolver Project</div>
<div style="display:flex;gap:16px;justify-content:center;flex-wrap:wrap;margin-bottom:8px;font-size:.78rem">
<a href="/tools/" style="color:rgba(255,255,255,.7);text-decoration:none">ライブラリ</a>
<a href="/index.html" style="color:rgba(255,255,255,.7);text-decoration:none">トップ</a>
<a href="/sitemap.html" style="color:rgba(255,255,255,.7);text-decoration:none">サイトマップ</a>
<a href="/about/author.html" style="color:rgba(255,255,255,.7);text-decoration:none">著者情報</a>
</div>
<div style="font-size:.65rem;color:rgba(255,255,255,.35)">© 2026 NovaSolver Contributors. All rights reserved.</div>
</div>
</footer>
<script>
const N = 200;
let U = new Float32Array(N * N);
let V = new Float32Array(N * N);
let nU = new Float32Array(N * N);
let nV = new Float32Array(N * N);
let params = { f: 0.035, k: 0.065, Du: 0.2097, Dv: 0.1050, speed: 8 };
let colorScheme = 'classic';
let paused = false;
let steps = 0;
let lastFpsTime = performance.now();
let frameCount = 0;
let fps = 0;
const PRESETS ={
spots: { f: 0.035, k: 0.065, name: '斑点' },
stripes:{ f: 0.055, k: 0.062, name: '縞模様' },
labyrinth:{ f: 0.037, k: 0.060, name: '迷路' },
spirals:{ f: 0.012, k: 0.050, name: '螺旋' },
mitosis:{ f: 0.0367, k: 0.0649, name: '細胞分裂' },
coral:{ f: 0.022, k: 0.059, name: '珊瑚' }
};
function initGrid(){
for (let i = 0; i < N * N; i++) {
U[i] = 1.0;
V[i] = 0.0;
}// Scatter random seeds
for (let s = 0; s < 40; s++){
const cx = Math.floor(Math.random() * (N - 20)) + 10;
const cy = Math.floor(Math.random() * (N - 20)) + 10;
for (let dy = -4; dy <= 4; dy++) {
for (let dx = -4; dx <= 4; dx++) {
if (dx*dx + dy*dy <= 16) {
const idx = (cy + dy) * N + (cx + dx);
if (idx >= 0 && idx < N * N) {
U[idx] = 0.5 + (Math.random() - 0.5) * 0.1;
V[idx] = 0.25 + (Math.random() - 0.5) * 0.1;
}
}
}
}
}
}function addSeed(cx, cy){
for (let dy = -5; dy <= 5; dy++) {
for (let dx = -5; dx <= 5; dx++) {
if (dx*dx + dy*dy <= 25) {
const nx = cx + dx, ny = cy + dy;
if (nx >= 0 && nx < N && ny >= 0 && ny < N) {
U[ny * N + nx] = 0.5;
V[ny * N + nx] = 0.25 + Math.random() * 0.05;
}
}
}
}
}function step(){
const f = params.f, k = params.k, Du = params.Du, Dv = params.Dv;
const dt = 1.0;
for (let y = 0; y < N; y++) {
const yn = (y - 1 + N) % N;
const yp = (y + 1) % N;
for (let x = 0; x < N; x++) {
const xn = (x - 1 + N) % N;
const xp = (x + 1) % N;
const idx = y * N + x;
const u = U[idx], v = V[idx];
const lapU = U[yn*N+x] + U[yp*N+x] + U[y*N+xn] + U[y*N+xp] - 4*u;
const lapV = V[yn*N+x] + V[yp*N+x] + V[y*N+xn] + V[y*N+xp] - 4*v;
const uvv = u * v * v;
nU[idx] = Math.max(0, Math.min(1, u + dt * (Du * lapU - uvv + f * (1 - u))));
nV[idx] = Math.max(0, Math.min(1, v + dt * (Dv * lapV + uvv - (f + k) * v)));
}
}
const tmp1 = U; U = nU; nU = tmp1;
const tmp2 = V; V = nV; nV = tmp2;
steps++;
}const COLOR_SCHEMES ={
classic: (t) => {
const r = t < 0.5 ? 0 : Math.round((t - 0.5) * 2 * 255);
const g = t < 0.25 ? 0 : t < 0.75 ? Math.round((t - 0.25) * 2 * 255) : 255;
const b = Math.round(Math.max(0, 1 - t * 2) * 255);
return [r, g, b];
},
fire: (t) =>{
const r = Math.round(Math.min(1, t * 2) * 255);
const g = Math.round(Math.max(0, t * 2 - 0.5) * 255);
const b = Math.round(Math.max(0, t * 3 - 2) * 255);
return [r, g, b];
},
ocean: (t) =>{
const r = Math.round(t * t * 100);
const g = Math.round(t * 180);
const b = Math.round(Math.min(1, t * 1.5 + 0.1) * 255);
return [r, g, b];
},
gray: (t) =>{ const v = Math.round(t * 255); return [v, v, v]; },
neon: (t) =>{
const r = Math.round(Math.sin(t * Math.PI) * 255);
const g = Math.round(Math.sin(t * Math.PI + Math.PI / 2) * 128 + 127);
const b = Math.round((1 - t) * 255);
return [r, g, b];
}
};
const canvas = document.getElementById('turing-canvas');
const ctx = canvas.getContext('2d');
function __novaCanvasCssW(canvas){
return parseFloat(canvas.dataset.cssW) || canvas.clientWidth || parseFloat(canvas.getAttribute("width")) || canvas.width / Math.min(window.devicePixelRatio || 1, 2.5);
}
function __novaCanvasCssH(canvas){
return parseFloat(canvas.dataset.cssH) || canvas.clientHeight || parseFloat(canvas.getAttribute("height")) || canvas.height / Math.min(window.devicePixelRatio || 1, 2.5);
}
function __novaHiDpiCanvas(canvas, cssW, cssH, ctx){
var dpr = Math.min(window.devicePixelRatio || 1, 2.5);
canvas.setAttribute('data-ux-no-scale', '1');
var w = Math.max(1, Math.round(cssW || canvas.clientWidth || parseFloat(canvas.getAttribute("width")) || canvas.width / dpr || 600));
var h = Math.max(1, Math.round(cssH || canvas.clientHeight || parseFloat(canvas.getAttribute("height")) || canvas.height / dpr || 320));
canvas.style.setProperty('width', w + 'px', 'important');
canvas.style.setProperty('height', h + 'px', 'important');
var bw = Math.round(w * dpr);
var bh = Math.round(h * dpr);
if (canvas.width !== bw || canvas.height !== bh) { canvas.width = bw; canvas.height = bh; }
canvas.dataset.cssW = String(w);
canvas.dataset.cssH = String(h);
if (ctx && ctx.setTransform) ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
return { w: w, h: h, dpr: dpr };
}
const turingBuffer = document.createElement('canvas');
turingBuffer.width = N;
turingBuffer.height = N;
const turingBufferCtx = turingBuffer.getContext('2d');
const imgData = turingBufferCtx.createImageData(N, N);
function render() {
const cfn = COLOR_SCHEMES[colorScheme];
let sumV = 0;
for (let i = 0; i < N * N; i++) {
const t = V[i];
sumV += t;
const [r, g, b] = cfn(t);
imgData.data[i * 4] = r;
imgData.data[i * 4 + 1] = g;
imgData.data[i * 4 + 2] = b;
imgData.data[i * 4 + 3] = 255;
}
__novaHiDpiCanvas(canvas, canvas.clientWidth || parseFloat(canvas.getAttribute('width')) || N, canvas.clientHeight || canvas.clientWidth || parseFloat(canvas.getAttribute('height')) || N, ctx);
turingBufferCtx.putImageData(imgData, 0, 0);
ctx.imageSmoothingEnabled = false;
ctx.clearRect(0, 0, __novaCanvasCssW(canvas), __novaCanvasCssH(canvas));
ctx.drawImage(turingBuffer, 0, 0, __novaCanvasCssW(canvas), __novaCanvasCssH(canvas));
document.getElementById('stat-steps').textContent = steps.toLocaleString();
document.getElementById('stat-avgv').textContent = (sumV / (N * N)).toFixed(3);
}function loop(ts){
if (!paused) {
for (let i = 0; i < params.speed; i++) step();
render();
frameCount++;
if (ts - lastFpsTime >= 1000) {
fps = Math.round(frameCount * 1000 / (ts - lastFpsTime));
document.getElementById('stat-fps').textContent = fps;
frameCount = 0; lastFpsTime = ts;
}
}
requestAnimationFrame(loop);
}function setPreset(name){
const p = PRESETS[name];
params.f = p.f; params.k = p.k;
document.getElementById('sl-f').value = p.f;
document.getElementById('sl-k').value = p.k;
document.getElementById('val-f').value = p.f.toFixed(4);
document.getElementById('val-k').value = p.k.toFixed(4);
document.getElementById('stat-type').textContent = p.name;
document.querySelectorAll('.preset-btn').forEach(b => b.classList.remove('active'));
document.getElementById('preset-' + name).classList.add('active');
resetSim();
}function updateParam(name, val){
const v = parseFloat(val);
params[name] = v;
const ids = { f: 'val-f', k: 'val-k', Du: 'val-du', Dv: 'val-dv', speed: 'val-spd' };
const decimals ={ f: 4, k: 4, Du: 4, Dv: 4, speed: 0 };
document.getElementById(ids[name]).textContent = v.toFixed(decimals[name]);
}function setColorScheme(s){
colorScheme = s;
document.querySelectorAll('.color-btn').forEach(b => b.classList.remove('active'));
document.querySelector('.color-' + s).classList.add('active');
}function randomizeSeed(){
initGrid();
steps = 0;
}function resetSim(){
initGrid();
steps = 0;
}function togglePause(){
paused = !paused;
const btn = document.getElementById('pause-btn');
btn.innerHTML = paused ? '<i class="fas fa-play"></i> 再開' : '<i class="fas fa-pause"></i> 一時停止';
}function getGridPos(e, rect){
const scaleX = N / rect.width;
const scaleY = N / rect.height;
return {
x: Math.floor((e.clientX - rect.left) * scaleX),
y: Math.floor((e.clientY - rect.top) * scaleY)
};
}
canvas.addEventListener('click', (e) => {
const rect = canvas.getBoundingClientRect();
const p = getGridPos(e, rect);
addSeed(p.x, p.y);
});
canvas.addEventListener('touchend', (e) => {
e.preventDefault();
const rect = canvas.getBoundingClientRect();
const t = e.changedTouches[0];
const p = getGridPos(t, rect);
addSeed(p.x, p.y);
},{ passive: false });
initGrid();
setPreset('spots');
requestAnimationFrame(loop);
</script>
<script src="/assets/sidebar-inject.v9.js" defer></script>
<script src="/tools/param-edit.js" defer></script>
<script src="/tools/share-state.js?v20260510r6" defer></script>
<script src="/tools/collapsible-cards.js" defer></script>
<script src="/tools/tooltips.js" defer></script>
<script src="/tools/tool-embed-share.js" defer></script>
<script src="/tools/related-tools.js" defer></script>
<script src="/tools/tool-objectives.js" defer></script>
<script defer src="/tools/tool-ux-template.js?v20260523r1"></script>
</body>
</html>