Я хочу сгенерировать синусоидальную волну из двух точек данных: tmin и tmax. где tmin — это место начала синусоидальной волны, а tmax — самая верхняя точка синусоидальной волны.
Затем я хочу найти, где tbase и tlimit пересекаются с синусоидой, созданной на предыдущем шаге.
Пример.
C = tlimit
B = tbase
Я хочу найти области 1 и 2 (как в примере изображения).
в настоящее время я могу вычислить площадь, когда tlimit выше tmax и tbase меньше или равно tmin, просто нужна помощь с этим. вот мой существующий код, но он может быть неправильным.
Существующий код
const calculateArea = (amplitude, meanTemp, threshold, start, end, steps = 1000) => {
const dx = (end - start) / steps;
let area = 0;
for (let i = 0; i < steps; i++) {
const x = start + (i * dx);
const y = amplitude * Math.sin(x) + meanTemp;
if (y > threshold) {
const areaToAdd = (y - threshold) * dx;
area += areaToAdd;
}
}
return area;
}
// Called like
const tmean = (tmax + tmin) / 2;
const amplitude = (tmax - tmin) / 2;
const start = 0;
const end = 2 * Math.PI;
const area1 = calculateAreaThreshold(amplitude, tmean, tbase, start, end)
const area2 = calculateAreaThreshold(amplitude, tmean, tlimit, start, end)
return area1 + area2;
# Test Data 1
tmin = 5
tmax = 25
tbase = 10
tlimit = 30
current_returned_result = 39.610976908929906
# Test Data 2
tmin = 5
tmax = 25
tbase = 20
tlimit = 30
current_returned_result = 7.527554726471326
# Test Data 3
tmin = 5
tmax = 25
tbase = 15
tlimit = 22
current_returned_result = 24.679341500413543
Я смотрел видео с Khan Academy на YT, про AP Calculus, но я очень растерялся
У меня есть tmin, tmax — это значения, необходимые для генерации синусоидальной волны. тогда у меня есть tbase и tlimit, которые пересекают синусоидальную волну.
Я хочу вычислить площадь заштрихованной синей части, отмеченной 1 и 2.
t неизвестно (это время, горизонтальная ось), а c^ (c с кружком) — это просто ось y.
У меня есть только эти 4 значения для работы, пятое значение является средним, например (tmax + tmin) / 2
M = (T_max + T_min) / 2
A = (T_max - T_min) / 2
t1 = 12 - (24 / (2 * math.pi)) * math.asin((tbase - M) / A)
t2 = 12 + (24 / (2 * math.pi)) * math.asin((tbase - M) / A)
area_1 = (A * math.cos(math.pi * (t1 - 12) / 12) + M - tbase) * (12 - t1)
area_2 = (A * math.cos(math.pi * (t2 - 12) / 12) + M - tbase) * (t2 - 12)
area = (area_1 + area_2) / 24
Причина получения площадей: мне нужно рассчитать эти площади для работающего проекта, поскольку они связаны с GDD (дни роста градусов). поэтому tmin и tmax — это минимальное и максимальное значения за день. tbase и tlimit уникальны для каждой культуры.
Синусоидальная волна начнется в точках x = 0 и y = tmin, пик синусоиды достигнет y = tmax.
после ознакомления с предложенными документами/ссылками. и общаемся с ChatGPT
Мне удалось придумать эту функцию
const calculateSineArea = (tmin, tmax, tbase, tlimit) => {
const amplitude = (tmax - tmin) / 2;
const angleBase = Math.asin((tbase - tmin) / amplitude) * (180 / Math.PI);
const angleLimit = Math.asin((tlimit - tmin) / amplitude) * (180 / Math.PI);
const areaBase = (Math.PI / 180) * angleBase * amplitude;
const areaLimit = (Math.PI / 180) * angleLimit * amplitude;
const finalArea = (areaLimit - areaBase) * amplitude;
return finalArea;
}
но я получаю 0 обратно
вот несколько тестов, которые я сделал
// inputs
tmin:5, tmax:25, tbase:10, tlimit:30
// calculated
amplitude:10, angleBase:30.000000000000004, angleLimit:NaN, areaBase:5.23598775598299, areaLimit:NaN, finalArea:NaN
// inputs
tmin:5, tmax:25, tbase:20, tlimit:30
// calculated
amplitude:10, angleBase:NaN, angleLimit:NaN, areaBase:NaN, areaLimit:NaN, finalArea:NaN
// inputs
tmin:5, tmax:25, tbase:15, tlimit:22
// calculated
amplitude:10, angleBase:90, angleLimit:NaN, areaBase:15.707963267948966, areaLimit:NaN, finalArea:NaN
@KIKOSoftware смотрите мое обновление, но да, это горизонтальная ось. Я не занимался такой математикой более 10 лет, поэтому забыл, как это делать.
Я думаю, вам нужна интеграция вашей функции, в вашем случае это sin(x). Затем вам нужно найти точки пересечения и получить площадь, просто поставив значения ∫sin(x), насколько я понимаю
@mbattaloglu Я не понимаю, что ты имеешь в виду.
Итак, можем ли мы согласиться, что площади 1 и 2 одинаковы? Затем, как уже сказал Мбатталоглу, используйте интеграл от sin(), то есть -cos(). Видеть; Интеграл от Sin x со смещением.
Я думаю, ChatGPT думает, что вы имеете дело с аналоговыми часами? Довольно забавно.
@ X3R0 Итак, вы рисуете графики sin(x). Затем вам нужно найти точки пересечения tbase и tlimit. Затем вычислите ∫sin(x)dx, которое равно -cos(x) + c. Наконец, вы можете поместить значения в -cos(x), вычесть их и просто найти площадь. (При поиске точек пересечения вам необходимо решить sin(x) = tbase, найти x, и x может иметь более 1 решения)
Просто прочитайте ссылку, предложенную @KIKOSoftware, я не до конца понимаю объяснение.
@ X3R0 Да, это то, что я говорю, с более понятным способом объяснить вещи.
Я тоже думаю, что ваш вопрос не совсем ясен. Понятно, но затрудняюсь дать однозначный ответ. Например, где начинается ваша синусоидальная кривая? Это важно. Было бы еще лучше, если бы вы рассказали нам, почему вы хотите знать эти области.
Кстати, они симметричны, поэтому равны друг другу. Так что вам достаточно найти 1 область.
@KIKOSoftware см. обновление вопроса
@mbattaloglu да, это имеет смысл, тогда мне нужно найти только одну из областей, которую я могу просто вернуть area * 2
Возможно эта таблица поможет вам понять косинус. tmin — это наименьшее значение вашего синуса, то есть оно составляет 270 градусов. Косинус там 0,0. Затем вы перемещаетесь вперед, скажем, на 30 градусов, до 300, и там косинус равен 0,5, поэтому, если у вас есть синус с амплитудой 1,0, площадь равна 0,5. Сделайте это как для B, так и для C, вычтите, умножьте на амплитуду, и вы получите одну площадь.
Я знаю, что это не полное решение, но это может помочь вам понять, что вам нужно делать.
@KIKOSoftware, все в порядке, я не ожидал полного решения, но я обновил свой вопрос новой попыткой алгоритма, не могли бы вы указать, что я делаю неправильно?
Я посмотрю. Да, я забыл сказать: синусоидальная волна имеет как минимум два свойства: амплитуду и период. В вашем коде вы используете tmin и tmax для определения амплитуды, но я не вижу ничего, что определяло бы период. Вряд ли это будет 2*Пи. См.: Амплитуда, Период, Фазовый сдвиг и Частота.
ОК, я посмотрел. Я вижу, вы поняли идею, но я не вижу никакого косинуса? Также полезно, если вы сможете проверить свои расчеты. Например, площадь под единичной синусоидальной кривой от 0 до 180 градусов имеет площадь 2. Умножьте это на амплитуду и период, и вы узнаете, каким должен быть результат для этой площади. Ссылка: Почему площадь под одним горбом синусоиды равна ровно 2?
@KIKOSoftware, не могли бы вы исправить мою последнюю функцию?
Нет, извините, я все еще не уверен, что мне нужно посчитать. Я не хочу дать неправильный ответ.
я заменил в своей функции Math.asin на Math.cos и получил вот это tmin:5, tmax:25, tbase:10, tlimit:30, amplitude:10, angleBase:50.28177697059672, angleLimit:-45.902147954690705, areaBase:8.775825618903728, areaLimit:-8.011436155469337, finalArea:167.87261774373064
Функция арксинус является обратной функцией синуса. Вы не можете заменить Math.asin на Math.cos, потому что первое является обратным, а второе — нет. Математика – это не просто попытка что-то сделать, а знание того, что вы делаете. Я понимаю, что это занимает больше времени, и вы хотите пойти по простому пути, но здесь это не работает.
@KIKOSoftware Я согласен
В этом посте слишком много обновлений. Пожалуйста, просто перепишите свой пост в отдельный пост с вопросами, в котором будет указано, какой у вас код, какая проблема в этом коде и какую отладку/тестирование вы с ним выполняли. Если вы обновите ее, и это все изменит, старый вопрос больше не будет вашим вопросом, и будущим посетителям просто нужно будет прочитать всю книгу, чтобы увидеть, является ли ваша проблема и их проблемой.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


const degreesToRadians = (degree) => {
return degree * (Math.PI / 180);
}
// value2 > value1
const calculateArea = (value1, value2) => {
const radiansValue1 = Math.asin(degreesToRadians(value1));
const radiansValue2 = Math.asin(degreesToRadians(value2));
// integration of sinx = -cosx
const resultValue1 = -Math.cos(radiansValue1);
const resultValue2 = -Math.cos(radiansValue2);
return resultValue2 - resultValue1;
};
Это должно сработать. Будьте осторожны с преобразованием градусов в радианы. И значение2 должно быть больше, чем значение1, иначе вы получите отрицательные значения. (Или просто оберните вызов функции Math.abs())
как бы я добавил это в свою функцию?
Я не понимаю, что ты имеешь в виду @X3R0
Как я вас понимаю: Если я вас правильно понял, вот как выглядит кривая (вот интерактивный график десмоса, включающий значение площади):
Как упростить задачу: Тогда по логике обе площади равны. Замена аргумента t синусоидальной кривой на t + расстояние между tmax и осью Y даст вам ... * cos( x ) + ..., а функция косинуса имеет осевую симметрию y = 0, то есть площади ботов равны.
function calculateArea(start, end, min, max) {
/* Declare: */
let tbase = start;
let tlimit = end;
let tmin = min;
let tmax = min;
/* Define integral bounds: */
let lowerlimit = Math.asin((tbase - (tmax + tmin) / 2) / ((tmax - tmin) / 2));
let upperlimit = Math.asin((tlimit - (tmax + tmin) / 2) / ((tmax - tmin) / 2));
/* Define integrals: */
let integralline = tbase * upperlimit - tbase * lowerlimit ;
let integralsine = -(tmax - tmin) / 2 * Math.cos(upperlimit) + (tmax + tmin) / 2 * upperlimit - (-(tmax - tmin) / 2 * Math.cos(lowerlimit) + (tmax + tmin) / 2 * lowerlimit);
/* Calculate area */
let A = 2 * Math.abs(integralsine - integralline);
return A;
}
Кажется, этот код дает тот же результат, что и Desmos. Например.:
calculateArea(1, 3.7, -1, 10) == 1.4088853715974081;
calculateArea(1, 6.5, -1, 8.5) == 6.791808139768918;
calculateArea(-1, 6.5, -1, 8.5) == 13.042250896482566;
...
Если у вас есть какие-либо вопросы, просто задайте их.
Так что расчета одной площади достаточно. Используя вашу информацию, функция, описывающая синусоидальную кривую, будет f( x ) = (tmax - tmin) / 2 * sin( x ) + (tmax + tmin) / 2, верхняя линия будет tlimit, а нижняя линия tbase. Фиолетовый цвет — это разница между площадью синусоиды по оси X и нижней линией по оси X. Их можно вычислить, взяв интеграл от f^-1( tbase ) до f^-1( tlimit ).
Нам нужно решить (tmax - tmin) / 2 * sin( x ) + (tmax + tmin) / 2 = c для x. Вычтите (tmax + tmin) / 2, затем разделите на (tmax - tmin) / 2 и возьмите обратную функцию синуса: x = arcsin((c - (tmax + tmin) / 2) / ((tmax - tmin) / 2)). f^-1( x ) = arcsin((x - (tmax + tmin) / 2) / ((tmax - tmin) / 2)).
Берём первообразную от f( x ) и нижнюю строку. Используя правило множителей, правило сумм и int sin( x ) dx = -cos( x ) + constant:
int f( x ) dx = -(tmax - tmin) / 2 * cos( x ) + (tmax + tmin) / 2 * x + constant
int lower line dx = tbase * x + constant
Итак, интегралы — это -(tmax - tmin) / 2 * cos( arcsin((tlimit - (tmax + tmin) / 2) / ((tmax - tmin) / 2)) ) + (tmax + tmin) / 2 * arcsin((x - (tmax + tmin) / 2) / ((tmax - tmin) / 2)) - -(tmax - tmin) / 2 * cos( arcsin((x - (tmax + tmin) / 2) / ((tmax - tmin) / 2)) ) + (tmax + tmin) / 2 * arcsin((tbase - (tmax + tmin) / 2) / ((tmax - tmin) / 2)) и tbase * tlimit - tbase * tbase. Одна площадь равна их разнице, а их две, поэтому сумма площадей A равна:
A = 2 * |-(tmax - tmin) / 2 * cos( arcsin((tlimit - (tmax + tmin) / 2) / ((tmax - tmin) / 2)) ) + (tmax + tmin) / 2 * arcsin((x - (tmax + tmin) / 2) / ((tmax - tmin) / 2)) - -(tmax - tmin) / 2 * cos( arcsin((x - (tmax + tmin) / 2) / ((tmax - tmin) / 2)) ) + (tmax + tmin) / 2 * arcsin((tbase - (tmax + tmin) / 2) / ((tmax - tmin) / 2)) - (tbase * arcsin((tlimit - (tmax + tmin) / 2) / ((tmax - tmin) / 2)) - tbase * arcsin((tbase - (tmax + tmin) / 2) / ((tmax - tmin) / 2)))|
Почему | ... |? Площадь не может быть отрицательной, поэтому для устранения этой возможной проблемы мы просто используем абсолютное значение.
в вашем коде что такое начало и конец? это мои tbase и tlimit?
пока я смотрю calculateAreaAboveThreshold = (tmin:number, tmax:number, tbase:number, tlimit:number) => {/*code here*/}
Да, это. tbase = start и tlimit = end.
Кажется, это элементарная тригонометрия, но мне трудно понять, где находятся ваши
tminиtmaxи что вы пытаетесь вычислить. Можете ли вы прочитать свой текст еще раз? Возможно, изображение не очень четкое. Находится лиtна горизонтальной оси?tвозможно, для «времени»?