/// <summary>Determine the density limits</summary> private void CalculateDensity(GameConstants consts, Random rnd) { // Factors influency density: // -Bigger molar mass = higher density // -Stronger bonds = higher density // -More Ionic = higher density // -Smaller atomic radii = higher density var norm_ionicity = Math_.Frac(consts.MinElectronegativity, Ionicity, consts.MaxElectronegativity); var mass_adj = Math_.Frac(1, MolarMass / (Count1 + Count2), consts.MaxMolarMass); // normalised average molar mass var ionicity_adj = 1.0 + 0.5 * Math.Pow(norm_ionicity, 8); // no significant ionicity until about 0.7 //var bond_adj = dominant_bond.Strength; //var radii = Elem1.ValenceOrbitalRadius + Elem2.ValenceOrbitalRadius; var scaler = mass_adj * ionicity_adj; Debug.Assert(scaler >= 0 && scaler < 10); m_solid_density = Math_.Lerp(consts.MinSolidMaterialDensity, consts.MaxSolidMaterialDensity, scaler); // The liquid_density0 value can only be lower than the solid density when // the Compound is strongly ionic such that it forms a crystals var ionicity_solid_density_scaler = 0.1 * Math_.Max(0, norm_ionicity - 0.75); m_liquid_density0 = m_solid_density * rnd.Double(1.0, 1.0 - ionicity_solid_density_scaler); m_liquid_density1 = m_liquid_density0 * rnd.DoubleC(0.8, 0.0); // at boiling point, density is roughly 20% less }
/// <summary>Sets the density of the element in the solid state (assumed constant)</summary> private void CalcSolidDensity(GameConstants consts) { var frac = Math.Sin(TableX * 0.48 * Math_.Tau); var min = consts.MinSolidMaterialDensity * Math_.Lerp(1.0, 3.5, TableY); var max = consts.MaxSolidMaterialDensity * Math_.Lerp(0.015, 1.0, TableY); SolidDensity = Math_.Lerp(min, max, frac); }
/// <summary>Update the state of the progress form</summary> public void UpdateProgress(UserState us) { var do_layout = us.ForceLayout != null && us.ForceLayout.Value; if (us.FractionComplete != null) { m_progress.Value = (int)Math_.Lerp(m_progress.Minimum, m_progress.Maximum, Math_.Clamp(us.FractionComplete.Value, 0.0, 1.0)); } if (us.Title != null) { Text = us.Title; } if (us.Description != null) { m_description.Text = us.Description; do_layout |= true; } if (us.DescFont != null) { m_description.Font = us.DescFont; } if (us.Icon != null) { Icon = us.Icon; } if (us.ProgressBarVisible != null) { m_progress.Visible = us.ProgressBarVisible.Value; } if (us.ProgressBarStyle != null) { m_progress.Style = us.ProgressBarStyle.Value; } if (us.ProgressBarText != null) { m_progress.Text = us.ProgressBarText; } if (do_layout) { DoLayout(); } if (us.CloseDialog) { // Don't trigger a layout, we just want to exit m_allow_cancel = true; DialogResult = CancelPending ? DialogResult.Cancel : DialogResult.OK; //Close(); } }
/// <summary>The density of the Compound at the given temperature/pressure (kg/m³)</summary> public double Density(double temperature, double pressure) { switch (Phase(temperature, pressure)) { default: throw new ArgumentException(); case EPhase.Gas: return(0.0); case EPhase.Solid: return(m_solid_density); case EPhase.Liquid: var f = Math_.Frac(MeltingPoint, temperature, BoilingPoint); return(Math_.Lerp(m_liquid_density0, m_liquid_density1, f)); } }
public void TestLerp() { var a0 = new[] { 1.0, 10.0, 2.0, 5.0 }; Assert.Equal(Math_.Lerp(-0.1, a0), 1.0); Assert.Equal(Math_.Lerp(0.0, a0), 1.0); Assert.Equal(Math_.Lerp(1.0, a0), 5.0); Assert.Equal(Math_.Lerp(1.1, a0), 5.0); Assert.Equal(Math_.Lerp(1 / 2.0, a0), 6.0); Assert.Equal(Math_.Lerp(1 / 3.0, a0), 10.0); Assert.Equal(Math_.Lerp(2 / 3.0, a0), 2.0); Assert.Equal(Math_.Lerp(1 / 6.0, a0), 5.5); Assert.Equal(Math_.Lerp(5 / 6.0, a0), 3.5); Assert.Equal(Math_.Lerp(new v4(0f), new v4(1f), 0.5), new v4(0.5f)); }
/// <summary>Interpolate this candle between it's known values. Used to simulate higher resolution of price movement</summary> public Candle SubCandle(double t) { // Bullish candles, return: Open, Low, High, Close // Bearish candles, return: Open, High, Low, Close var vol = Math_.Lerp(t, 0, Volume); var t0 = Bullish ? 0.6667 : 0.3333; var t1 = Bullish ? 0.3333 : 0.6667; var close = Bullish ? Math_.Lerp(t, Open, Low, High, Close) : Math_.Lerp(t, Open, High, Low, Close); return(new Candle(Timestamp, Open, t < t0 ? Math.Max(Open, close) : High, t < t1 ? Math.Min(Open, close) : Low, close, Median, vol)); }
/// <summary>Sets the valency properties</summary> private void CalcValency(GameConstants consts) { // Noble gases have no valency if (AtomicNumber == consts.ValenceLevels[Period]) { ValenceElectrons = 0; ValenceHoles = 0; ValenceOrbitalRadius = consts.OrbitalRadii[Period].Min; return; } ValenceElectrons = AtomicNumber - consts.ValenceLevels[Period - 1]; ValenceHoles = consts.ValenceLevels[Period] - AtomicNumber; // Valency is never more than the stable shell count if (ValenceElectrons < consts.StableShellCount) { ValenceHoles = Math.Min(ValenceHoles, consts.StableShellCount - ValenceElectrons); } else if (ValenceHoles < consts.StableShellCount) { ValenceElectrons = Math.Min(ValenceElectrons, consts.StableShellCount - ValenceHoles); } else { const int MinValenceElectrons = 2; int MaxValenceElectrons = consts.StableShellCount - 1; for (int i = 0, iend = ValenceElectrons - MaxValenceElectrons; i < iend;) { ValenceElectrons = MaxValenceElectrons; for (; i < iend && ValenceElectrons > MinValenceElectrons; --ValenceElectrons, ++i) { } for (; i < iend && ValenceElectrons < MaxValenceElectrons; ++ValenceElectrons, ++i) { } } ValenceHoles = 8 - ValenceElectrons; } // Create an orbital radius for this element // Orbital radii decreases from bottom left to top right of the periodic table, i.e He is the smallest atom, Cs the biggest ValenceOrbitalRadius = Math_.Lerp(consts.OrbitalRadii[Period].Max, consts.OrbitalRadii[Period].Min, Math_.Sqrt(TableX)); }
/// <summary>Sets the electro negativity</summary> private void CalcElectronegativity(GameConstants consts) { if (AtomicNumber == 1) { Electronegativity = Math_.Lerp(consts.MinElectronegativity, consts.MaxElectronegativity, 0.5); return; } // This scale does not include the nobal gases so rescale TableX to make 1.0 = ValenceLevel[Period] - 1 var row_count = consts.ValenceLevels[Period] - consts.ValenceLevels[Period - 1]; var x = TableX * row_count / (row_count - 1); // Electronegativity increases from bottom left to top right of the // periodic table with a minor peak in the centre var frac = 0.03 * Period * Math.Sin(Math.Pow(x, Math_.Root2) * Math_.Tau) + x; // A normalised scaler with a hump in the middle that gets bigger for higher periods var min = consts.MinElectronegativity * Math_.Lerp(1.5, 1.0, TableY); var max = consts.MaxElectronegativity * Math_.Lerp(1.15, 0.45, TableY); Electronegativity = Math_.Lerp(min, max, frac); }
/// <summary>Linearly interpolates between 'lhs' and 'rhs'</summary> public static DateTimeOffset Lerp(DateTimeOffset lhs, DateTimeOffset rhs, double frac) { var lerp = Math_.Lerp(lhs.Ticks, rhs.Ticks, frac); return(new DateTimeOffset(lerp, lhs.Offset)); }
protected override void OnPaint(PaintEventArgs e) { var gfx = e.Graphics; var dim = LayoutDimensions; if (dim.Empty) { base.OnPaint(e); return; } // Draw the wheel if ((Parts & EParts.Wheel) != 0) { var bm = WheelBitmap; gfx.DrawImageUnscaled(bm, 0, 0); // Draw the colour selection if ((Parts & EParts.ColourSelection) != 0) { var pt = WheelPoint(HSVColour); gfx.DrawEllipse(Pens.Black, pt.X - 2f, pt.Y - 2f, 4f, 4f); } } gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; // Draw the VSlider if ((Parts & EParts.VSlider) != 0) { gfx.DrawString(ValueLabel, SystemFonts.DefaultFont, Brushes.Black, dim.VLabel); if (!dim.VSlider.IsEmpty) { using (var b = new LinearGradientBrush( VerticalLayout ? dim.VSlider.LeftCentre() : dim.VSlider.BottomCentre(), VerticalLayout ? dim.VSlider.RightCentre() : dim.VSlider.TopCentre(), Color.Black, Color.White)) gfx.FillRectangle(b, dim.VSlider); gfx.DrawRectangle(Pens.Black, dim.VSlider); } // Draw the brightness selection if ((Parts & EParts.VSelection) != 0) { var v = VerticalLayout ? Math_.Lerp(dim.VSlider.Left, dim.VSlider.Right, (double)HSVColour.V) : Math_.Lerp(dim.VSlider.Bottom, dim.VSlider.Top, (double)HSVColour.V); var pts = SliderSelector(v, dim.VSlider, VerticalLayout); gfx.DrawLines(Pens.Black, pts); } } // Draw the ASlider if ((Parts & EParts.ASlider) != 0) { gfx.DrawString(AlphaLabel, SystemFonts.DefaultFont, Brushes.Black, dim.ALabel); if (!dim.ASlider.IsEmpty) { using (var b = new LinearGradientBrush( VerticalLayout ? dim.ASlider.LeftCentre() : dim.ASlider.BottomCentre(), VerticalLayout ? dim.ASlider.RightCentre() : dim.ASlider.TopCentre(), Color.Black, Color.White)) gfx.FillRectangle(b, dim.ASlider); gfx.DrawRectangle(Pens.Black, dim.ASlider); } // Draw the alpha selection if ((Parts & EParts.ASelection) != 0) { var v = VerticalLayout ? Math_.Lerp(dim.ASlider.Left, dim.ASlider.Right, (double)HSVColour.A) : Math_.Lerp(dim.ASlider.Bottom, dim.ASlider.Top, (double)HSVColour.A); var pts = SliderSelector(v, dim.ASlider, VerticalLayout); gfx.DrawLines(Pens.Black, pts); } } }