<?php
/*
Code
© Charles Chandler
http://qdl.scs-inc.us/?top=7111
*/
// See http://scs-inc.us/Other/QuickDisclosure/?top=7105 for more info.
// Note that this code requires private utilities to run. This is being
// made public just so people can so how the numbers were crunched.
define('kAtomicMassKG', 1.660538921E-27);
$fontFile = '2ndParty/Images/Charles/Sun/Elements/Font.ttf';
$imgFile = '2ndParty/Images/Charles/Sun/Elements/Elements.png';
if (kIsPublic) { $elePgID = 7083; $layPgID = 7085; $abuPgID = 7106; }
else { $elePgID = 8804; $layPgID = 8810; $abuPgID = 8814; }
// Read the elements table.
$eleArr = array();
$elePg = GetPageByID($elePgID);
$tmp = TableToArray($elePg->contents);
// Skip the field names in the first row.
for ($i = 1; $i < sizeof($tmp); $i++) {
$eleArr[] = array(
'num' => $tmp[$i][0], // element number
'sym' => $tmp[$i][1], // abbreviation
'nam' => $tmp[$i][2], // element name
'per' => $tmp[$i][3], // period
'grp' => $tmp[$i][4], // group
'boi' => $tmp[$i][5], // boiling point (K)
'mas' => $tmp[$i][6], // atomic mass
'den' => $tmp[$i][7], // density (kg/m^3)
'a/v' => $tmp[$i][8], // atoms per m^3
);
}
// Recalculate the number of atoms per volume.
for ($i = 0; $i < sizeof($eleArr); $i++) {
$massOfAtomKG = $eleArr[$i]['mas'] * kAtomicMassKG;
$numAtoms = $eleArr[$i]['den'] / $massOfAtomKG;
$numAtoms = round($numAtoms / pow(10, 24));
$eleArr[$i]['a/v'] = ($numAtoms) ? $numAtoms : '';
}
// Regenerate the elements table.
if ((0) and (!kIsPublic)) {
$rows = MinimalWhiteSpace('
<tr>
<th class="right">#</th>
<th class="left">ab</th>
<th class="left">name</th>
<th>per</th>
<th>grp</th>
<th class="right">b.p. K</th>
<th class="right">a.mass</th>
<th class="right">kg/m<sup>3</sup></th>
<th class="right">at<sup>24</sup>/m<sup>3</sup></th>
</tr>
');
for ($i = 0; $i < sizeof($eleArr); $i++) {
$rows .= Row(
Cell(1, $eleArr[$i]['num'], 'right').
Cell(1, $eleArr[$i]['sym']).
Cell(1, $eleArr[$i]['nam']).
Cell(1, $eleArr[$i]['per'], 'center').
Cell(1, $eleArr[$i]['grp'], 'center').
Cell(1, $eleArr[$i]['boi'], 'right').
Cell(1, $eleArr[$i]['mas'], 'right').
Cell(1, $eleArr[$i]['den'], 'right').
Cell(1, $eleArr[$i]['a/v'], 'right')
);
}
$table = Table($rows, 'standard');
if (0) {
$clonePg = clone $elePg;
$elePg->contents = $table;
UpdatePage($elePg, $clonePg, 'me');
} else echo $table.'<br />';
}
// Read the abundance table.
$abuPg = GetPageByID($abuPgID);
$abuArr = TableToArray($abuPg->contents);
// Skip the field names in the first row.
array_shift($abuArr);
// Regenerate the abundance table.
if ((0) and (!kIsPublic)) {
$rows = MinimalWhiteSpace('
<tr>
<th class="right">#</th>
<th class="left">ab</th>
<th>set 1</th>
<th>set 2</th>
<th>set 3</th>
</tr>
');
for ($i = 0; $i < sizeof($abuArr); $i++) {
$rows .= Row(
Cell(1, $abuArr[$i][0], 'right').
Cell(1, $abuArr[$i][1]).
Cell(1, $abuArr[$i][2], 'right').
Cell(1, $abuArr[$i][3], 'right').
Cell(1, $abuArr[$i][4], 'right')
);
}
$table = Table($rows, 'standard');
if (0) {
$clonePg = clone $abuPg;
$abuPg->contents = $table;
UpdatePage($abuPg, $clonePg, 'me');
} else echo $table.'<br />';
}
// Select the abundance field to use.
// 2: Anders & Grevesse (1989)
// 3: Manuel (noble gases)
// 4: Manuel (B2FH)
$abuFld = 4;
// Calculate the volume of each element (as the abundance
// divided by the atoms per volume), and find the total volume.
// Note that this block contains the heuristically-derived
// correction factor, for getting the overall density right.
$totVol = 0;
for ($i = 0; $i < sizeof($abuArr); $i++) {
if ($abuArr[$i][$abuFld]) {
if ($abuFld == 2) { $correction = 0; } // Anders & Grevesse (1989)
else { $correction = 5.014441 / $eleArr[$i]['mas']; } // Manuel
$abuArr[$i][$abuFld] += $correction;
$abundance = pow(10, $abuArr[$i][$abuFld]);
$eleArr[$i]['vol'] = $abundance / $eleArr[$i]['a/v'];
$eleArr[$i]['vol'] *= 100000000; // shift the decimal point a few times
$totVol += $eleArr[$i]['vol'];
}
}
// Knowing the total volume, we can now calculate the overall density.
if (0) {
$avgDen = 0;
for ($i = 0; $i < sizeof($abuArr); $i++) {
if ($abuArr[$i][$abuFld]) {
$decOfTotVol = $eleArr[$i]['vol'] / $totVol;
$avgDen += $decOfTotVol * $eleArr[$i]['den'];
}
}
echo 'average density: '.$avgDen.'<br />';
echo 'density of Sun: 1408 kg/m<sup>3</sup><br />';
}
// Create the layers array.
$layArr = array();
for ($i = 0; $i < sizeof($abuArr); $i++) {
if ($abuArr[$i][$abuFld]) {
$layArr[] = array(
'num' => $eleArr[$i]['num'],
'sym' => $eleArr[$i]['sym'],
'nam' => $eleArr[$i]['nam'],
'den' => $eleArr[$i]['den'],
'a/v' => $eleArr[$i]['a/v'],
'abu' => $abuArr[$i][$abuFld],
'vol' => $eleArr[$i]['vol'],
);
}
}
// Now we figure out the radii of the core, and of each concentric shell.
// To do this, we sort by density, and find the innermost element, which
// will have settled to the bottom because of its greater density. Then
// we add that to the volume of the next element to get its outer radius.
function SortByDensity($a, $b) {
$numA = floatval($a['den']);
$numB = floatval($b['den']);
return ($numB > $numA) ? 1 : -1;
}
usort($layArr, 'SortByDensity');
$runVol = 0;
for ($i = 0; $i < sizeof($layArr); $i++) {
$runVol += $layArr[$i]['vol'];
$runRad = RadiusOfSphere($runVol) * 20;
$layArr[$i]['rad'] = $runRad;
}
// $runRad is now the total radius, so we can
// rewrite the radius as a decimal of the total.
for ($i = 0; $i < sizeof($layArr); $i++) {
$layArr[$i]['rad'] = $layArr[$i]['rad'] / $runRad;
}
// Regenerate the layers table.
if ((0) and (!kIsPublic)) {
$rows = MinimalWhiteSpace('
<tr>
<th class="right">#</th>
<th class="left">ab</th>
<th>kg/m<sup>3</sup></th>
<th>at<sup>24</sup>/m<sup>3</sup></th>
<th>log(a)</th>
<th class="right">volume</th>
<th>SR</th>
</tr>
');
for ($i = 0; $i < sizeof($layArr); $i++) {
$rows .= Row(
Cell(1, $layArr[$i]['num']).
Cell(1, $layArr[$i]['sym']).
Cell(1, $layArr[$i]['den'], 'right').
Cell(1, round( $layArr[$i]['a/v']), 'right').
Cell(1, sprintf('%1.3f', $layArr[$i]['abu']), 'right').
Cell(1, round( $layArr[$i]['vol']), 'right').
Cell(1, sprintf('%1.3f', $layArr[$i]['rad']), 'right')
);
}
$table = Table($rows, 'standard');
if (0) {
$layPg = GetPageByID($layPgID);
$clonePg = clone $layPg;
$layPg->contents = $table;
UpdatePage($layPg, $clonePg, 'me');
} else echo $table.'<br />';
}
function PlaceText($img, $x, $y, $text, $foreColor) {
global $fontFile;
$fontSize = 14;
$bbox = ImageFtBBox($fontSize, 0, $fontFile, 'A'); $y -= $bbox[5] / 2;
$bbox = ImageFtBBox($fontSize, 0, $fontFile, $text); $x -= $bbox[4] / 2;
ImageFtText($img, $fontSize, 0, $x, $y, $foreColor, $fontFile, $text);
}
// Generate the solar radii image, and
// display a list of elements in each group.
if (1) {
$imgWide = 200;
$imgTall = 400;
$img = ImageCreateTrueColor($imgWide, $imgTall);
$violet = ImageColorAllocate($img, 138, 43, 226);
$blue = ImageColorAllocate($img, 0, 0, 255);
$green = ImageColorAllocate($img, 0, 100, 0);
$yellow = ImageColorAllocate($img, 255, 255, 0);
$orange = ImageColorAllocate($img, 255, 185, 0);
$red = ImageColorAllocate($img, 255, 0, 0);
$black = ImageColorAllocate($img, 0, 0, 0);
$white = ImageColorAllocate($img, 255, 255, 255);
$violetNames = array();
$blueNames = array();
$greenNames = array();
$yellowNames = array();
$orangeNames = array();
$redNames = array();
$blackNames = array();
$cx = $imgWide / 2;
$cy = $imgTall;
$layArr = array_reverse($layArr); // draw the arcs from the outside in
for ($i = 0; $i < sizeof($layArr); $i++) {
if ($i > 83) { $color = $violet; $violetNames[] = $layArr[$i]['nam']; }
elseif ($i > 78) { $color = $blue; $blueNames [] = $layArr[$i]['nam']; }
elseif ($i > 76) { $color = $green; $greenNames [] = $layArr[$i]['nam']; }
elseif ($i > 69) { $color = $yellow; $yellowNames[] = $layArr[$i]['nam']; }
elseif ($i > 36) { $color = $orange; $orangeNames[] = $layArr[$i]['nam']; }
elseif ($i > 35) { $color = $red; $redNames [] = $layArr[$i]['nam']; }
else { $color = $black; $blackNames [] = $layArr[$i]['nam']; }
if (kIsPublic) {
$r = $layArr[$i]['rad'] * $imgTall * 1.5;
ImageFilledArc($img, $cx, $cy, $r, $r, 180, 0, $color, IMG_ARC_PIE);
}
}
function TmpOutStr($label, $array) {
if (0) { echo $label.': '.implode(', ', $array).'<br />'; }
$result = array_shift($array);
if ($array) { $result .= ' ~ '.array_pop($array); }
return $result;
}
$violetNames = TmpOutStr('violet', $violetNames);
$blueNames = TmpOutStr('blue', $blueNames );
$greenNames = TmpOutStr('green', $greenNames );
$yellowNames = TmpOutStr('yellow', $yellowNames);
$orangeNames = TmpOutStr('orange', $orangeNames);
$redNames = TmpOutStr('red', $redNames );
$blackNames = TmpOutStr('black', $blackNames );
if (kIsPublic) {
PlaceText($img, $cx, 150, $violetNames, $white);
PlaceText($img, $cx, 15, $blueNames, $blue);
PlaceText($img, $cx, 35, $greenNames, $green);
PlaceText($img, $cx, 55, $yellowNames, $yellow);
PlaceText($img, $cx, 75, $orangeNames, $orange);
PlaceText($img, $cx, 283, $redNames, $white);
PlaceText($img, $cx, 385, $blackNames, $white);
ImagePNG($img, $imgFile);
ImageDestroy($img);
echo '<img src="'.$imgFile.'" />';
}
}
?>
|