C# 温度时间计算

C# 温度时间计算,c#,math,time,C#,Math,Time,这可能不是正确的地方,如果不是,请提前道歉 我的情况-我需要想出一个简单的公式/方法,给它一个小时,例如13、15、01等,并根据该数字,该方法将返回该特定时间的“近似”温度 这是非常近似的,它不会使用天气数据或任何类似的数据,它只需要一天中的一个小时,然后返回一个介于-6摄氏度>35摄氏度之间的值。非常极端的天气,但你明白了 这就是我想知道的例子: 请注意,我可以使用一个由24个项目组成的丑陋数组,每个项目都引用该小时的温度,但这需要基于浮动-例如,19.76应该返回9.25度 另一个注意事项

这可能不是正确的地方,如果不是,请提前道歉

我的情况-我需要想出一个简单的公式/方法,给它一个小时,例如13、15、01等,并根据该数字,该方法将返回该特定时间的“近似”温度

这是非常近似的,它不会使用天气数据或任何类似的数据,它只需要一天中的一个小时,然后返回一个介于-6摄氏度>35摄氏度之间的值。非常极端的天气,但你明白了

这就是我想知道的例子:

请注意,我可以使用一个由24个项目组成的丑陋数组,每个项目都引用该小时的温度,但这需要基于浮动-例如,19.76应该返回9.25度

另一个注意事项:我不想要一个完整的解决方案——我是一个自信的程序员,精通各种语言,但数学真的让我难堪。我在纸上试过各种方法,用TimeToPeak高峰时间是下午1点左右,但都没有用。如果您有任何帮助,我们将不胜感激。

编辑

在您的评论之后,这里有一个函数,它提供了一个正弦分布,其中包含各种有用的可选参数

private static double SinDistribution(
    double value,
    double lowToHighMeanPoint = 0.0,
    double length = 10.0,
    double low = -1.0,
    double high = 1.0)
{
    var amplitude = (high - low) / 2;
    var mean = low + amplitude;
    return mean + (amplitude * Math.Sin(
        (((value - lowToHighMeanPoint) % length) / length) * 2 * Math.PI));
}
你可以这样使用它,以获得你想要的结果

for (double i = 0.0; i < 24.0; i++)
{
    Console.WriteLine("{0}: {1}", i, SinDistribution(i, 6.5, 24.0, -6.0, 35.0));
}
这显然打折了环境因素,并假设这一天是春分,但我认为它回答了这个问题

所以

假设分布中的每个点之间有一个相当简单的线性过渡。如果将小时映射到分布中不存在的元素,则会得到错误的结果

可以使用简单的两点线性近似。试试这样的事情: 或使用3、5或更多点,用普通最小二乘法得到多项式系数。 您的示例数据类似于sin函数,因此可以进行sin函数近似。
表中的数据与第13小时的峰值和第1小时的最小值呈线性上下变化。如果这是您想要的模型类型,那么这很容易放入公式化解决方案中。您只需根据小时值在温度的两个极端之间执行线性插值。您将有两个数据点:

xmin,ymin为小时最小值,温度最小值

xmax,ymax为最大小时数,最大温度

有两个方程式的形式:

这两个方程将使用x0、y0和x1、y1值作为上述两个数据点,但将它们应用于相反的赋值,即一个方程的峰值为x0、y0,另一个方程的峰值为x1、y1

然后,您将根据小时值选择要使用的方程式,插入X值作为小时,并将温度值计算为Y


您需要对方程式中使用的X值进行偏移,以便处理0小时与最低温度峰值之间的偏移。

以下是一个示例,说明如何使用函数中的一组简单值进行此操作,如果您愿意,可以将这些值添加为参数

    public double GetTemp(double hour)
    {
        int min = 1;
        int max = min + 12;

        double lowest = -10;
        double highest = 35;

        double change = 3.75;

        return (hour > max) ? ((max - hour) * change) + highest : (hour < min) ? ((min - hour)*change) + lowest : ((hour - max) * change) + highest;
    }
我已经根据您的示例对此进行了测试,它使用19.75=9.6875


没有检查输入的值是否在0-24范围内,但您可能可以自己管理:

对于任意数据点,我将使用已提供的其他线性插值解决方案之一

但是,此特定数据集由以下程序生成:


编写一个包含24个元素的数组的类,其中包含小时值。添加一个采用float的函数。取整数和分数,根据分布选择正确的温度。我看不出有什么复杂的地方;19.76不是应该在9.25左右返回吗?@ElRonnoco-是的,我给出了一个非常糟糕的近似值。谢谢大家的回答。但是这并不能解决24个温度值数组的问题。这是一个简单的解决方案,可能会很好-但我不想使用值数组。这是一个游戏,我不想在玩家以不同的最大值和最小值在不同的区域走动时不断地改变一组值。无论如何,谢谢,这是一个很好的解决方案。我添加了一个简短的示例,说明如何在返回之前通过简单的测试来完成此操作。@brighterdean,经过编辑以提供类似您所寻找的内容。@brighterdean,如果您的虚拟世界只有一个太阳,您可以查看此示例。这听起来很完美。然而,我的数学会让我失望——我是一个自信的程序员,而不是数学家。有没有什么地方可以向一个白痴解释这一点?这基本上只是说-如果小时低于峰值,lerp介于最低温度和最高温度之间。如果高于峰值,则在最高温度和最低温度之间翻转lerp周围的值?@brighterdean-是。这几乎就是这么简单。但您需要抵消小时数,以说明最低温度发生在1小时
该死,这个答案太小了,我差点错过了。拥有这个公式是很好的,但是有没有可能有人真的能解释它背后的数学呢?很遗憾,但这是真的。如果你采取简单的方法,有人调出解决方案,你将永远无法提高你的知识一点点。那么这个答案是否适合任意数据插值,因为OP建议他的数据是例如温度???@brighterdean-数学的简要解释:从Wikipedia链接开始。然后,这个问题的特定常数:45:最大和最小温度之间的差异;24:周期每24小时重复的波周期-10:因为你的最小值是-10,而不是0;t-1而不是t:因为最小值出现在t==1,而不是t==0。@ElRonnoco-对于任意数据点,我将使用已提供的其他线性插值解决方案之一。。
    function double hourTemp(double hour)
    {
       idx1 = round(hour); 
       idx2 = idx1 + 1;
       return (data[idx2] - data[idx1]) * (hour - idx1) + data[idx1];
    }
    public double GetTemp(double hour)
    {
        int min = 1;
        int max = min + 12;

        double lowest = -10;
        double highest = 35;

        double change = 3.75;

        return (hour > max) ? ((max - hour) * change) + highest : (hour < min) ? ((min - hour)*change) + lowest : ((hour - max) * change) + highest;
    }
temp = 45*Math.Abs(2*((t-1)/24-Math.Floor((t-1)/24+.5)))-10;