/// <summary> /// Figures out how much of the force should go to each point. The distances are distances from the point of impact. /// NOTE: This is basically: (1+baseConst)^-x /// </summary> /// <param name="baseConst"> /// Any number from 0 to infinity. Realistic values should be between .5 and 8. There's nothing magical about using e as /// the constant, it just seems to have a good amount of curve /// </param> /// <remarks> /// This doesn't need to create super realistic percents. If in doubt, use a larger base constant, which will give more of the force /// to the closer points. The physics engine won't let close objects fly past farther, so just like racking pool balls, the outer will /// fly out. But distributing the force a bit should help with jumpy behavior if the physics engine is under load /// /// I don't know for sure, but I'm guessing the shape of the curve should be roughly 1/x^2. This method isn't that, but should /// be similar enough. /// </remarks> private static double[] GetPercentOfProjForce(double[] distances, double baseConst = Math.E) { var avg_stdev = Math1D.Get_Average_StandardDeviation(distances); double scale = avg_stdev.Item2 / avg_stdev.Item1; scale *= baseConst; scale += 1; var deviations = distances. Select(o => { double distFromAvg = Math.Abs(o - avg_stdev.Item1); double deviationsFromAvg = distFromAvg / avg_stdev.Item2; if (o > avg_stdev.Item1) { deviationsFromAvg = -deviationsFromAvg; } //return Math.Pow(Math.E, deviationsFromAvg); return(Math.Pow(scale, deviationsFromAvg)); }). ToArray(); double sum = deviations.Sum(); return(deviations. Select(o => o / sum). ToArray()); }
private static double GetCellRadius(int index, Point3D[] points, Tuple <int, int>[] lines, double defaultRadius) { Tuple <int, int>[] connectedLines = lines. Where(o => o.Item1 == index || o.Item2 == index). ToArray(); if (connectedLines.Length == 0) { return(defaultRadius); } var stdDev = Math1D.Get_Average_StandardDeviation(connectedLines.Select(o => (points[o.Item2] - points[o.Item1]).Length)); //NOTE: avg + 1 std dev works well when the points are pretty evenly spaced. But the points that are close to each other also tend to //link to the farthest out points, so subtracting instead //return stdDev.Item1 + stdDev.Item2; return(stdDev.Item1 - (stdDev.Item2 / 2)); }
public static SOMFieldStats GetFieldStats(IEnumerable <string> field, SOMFieldType?typeOverride = null) { // Dedupe string[] deduped = field. Select(o => o.Trim()). Distinct(). ToArray(); // Unique Chars char[] uniqueChars = deduped. SelectMany(o => o). Distinct(). OrderBy(o => o). ToArray(); // FieldType SOMFieldType type = typeOverride ?? GetFieldType(field); // Numeric Stats double?numericMin = null; double?numericMax = null; double?numericAvg = null; double?numericStandDev = null; if (type == SOMFieldType.Integer || type == SOMFieldType.FloatingPoint) { double[] numerics = field. Select(o => string.IsNullOrWhiteSpace(o) ? 0d : double.Parse(o.Trim())). ToArray(); numericMin = numerics.Min(); numericMax = numerics.Max(); var avg_stdev = Math1D.Get_Average_StandardDeviation(numerics); numericAvg = avg_stdev.Item1; numericStandDev = avg_stdev.Item2; } // Date Stats DateTime?dateMin = null; DateTime?dateMax = null; DateTime?dateAvg = null; TimeSpan?dateStandDev = null; if (type == SOMFieldType.DateTime) { DateTime[] dates = field. Where(o => !string.IsNullOrWhiteSpace(o)). Select(o => DateTime.Parse(o.Trim())). ToArray(); dateMin = dates.Min(); dateMax = dates.Max(); var avg_stdev = Math1D.Get_Average_StandardDeviation(dates); dateAvg = avg_stdev.Item1; dateStandDev = avg_stdev.Item2; } // Return return(new SOMFieldStats() { Count = field.Count(), UniqueCount = deduped.Length, MinLength = deduped.Min(o => o.Length), // deduped are already trimmed MaxLength = deduped.Max(o => o.Length), UniqueChars = uniqueChars, UniqueChars_NonWhitespace = uniqueChars.Where(o => !UtilityCore.IsWhitespace(o)).ToArray(), FieldType = type, Numeric_Min = numericMin, Numeric_Max = numericMax, Numeric_Avg = numericAvg, Numeric_StandDev = numericStandDev, Date_Min = dateMin, Date_Max = dateMax, Date_Avg = dateAvg, Date_StandDev = dateStandDev, }); }