-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstar.js
81 lines (67 loc) · 2.65 KB
/
star.js
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
import { romanNumeral, capitalize, objToHTML } from './utils.js'
import { starTypeData } from './astrophysics.js'
import { Planet } from './planet.js'
import { PRNG } from './prng.js'
class Star {
constructor (name, seed, position) {
this.name = name
this.seed = seed
this.position = position || {x: 0, y: 0, z: 0}
return this
}
get detail () {
if (!this._detail) {
const pseudoRandom = new PRNG(this.seed)
const detail = {}
// actual frequency
// spectralClass = pseudoRandom.pick(["O","B","A","F","G","K","M"], [0.0001,0.2,1,3,8,12,76]),
const spectralClass = pseudoRandom.pick(['O', 'B', 'A', 'F', 'G', 'K', 'M'], [0.0001, 0.2, 1, 3, 8, 12, 20])
const spectralIndex = pseudoRandom.range(0, 9)
const stellarTemplate = starTypeData[spectralClass]
detail.spectralType = spectralClass + spectralIndex
// TODO replace with better formulae/data
detail.luminosity = stellarTemplate.luminosity * 3 / (spectralIndex + 2)
detail.mass = stellarTemplate.mass * 5 / (spectralIndex + 2)
detail.numberOfPlanets = pseudoRandom.range(stellarTemplate.planets[0], stellarTemplate.planets[1])
detail.planetSeed = pseudoRandom.range(0, 1000000)
detail.template = stellarTemplate
detail.inSpiralArm = pseudoRandom.probability(stellarTemplate.inSpiralArm)
this._detail = detail
}
return this._detail
}
planets () {
const {detail} = this
const planets = []
const pseudoRandom = new PRNG(detail.planetSeed)
const radiusMin = 0.4 * pseudoRandom.realRange(0.5, 2)
const radiusMax = 50 * pseudoRandom.realRange(0.5, 2)
const totalWeight = (Math.pow(detail.numberOfPlanets, 2) + detail.numberOfPlanets) * 0.5
let r = radiusMin
for (let i = 0; i < detail.numberOfPlanets; i++) {
r += i / totalWeight * pseudoRandom.realRange(0.5, 1) * (radiusMax - radiusMin)
planets.push(new Planet(capitalize(this.name) + '-' + romanNumeral(i + 1), pseudoRandom.range(0, 100000), r, detail.luminosity / Math.pow(r, 2)))
}
return planets
}
planetsDetail () {
return this.planets().map(planet => planet.detail())
}
habitability () {
if (!this._habitability) {
const list = this.planetsDetail().map(detail => detail.HI).sort()
this._habitability = list.length ? list.shift() : 5
}
return this._habitability
}
description () {
let output = ''
output += '<h3>' + capitalize(this.name) + '</h3>\n'
output += objToHTML(this.detail(), true)
for (const planet of this.planets()) {
output += '<div class="subrecord">' + planet.description() + '</div>'
}
return output
}
}
export { Star }