Как рассчитать площадь синусоидальной волны с пересечениями

Я хочу сгенерировать синусоидальную волну из двух точек данных: 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, но я очень растерялся

Обновление 1

У меня есть tmin, tmax — это значения, необходимые для генерации синусоидальной волны. тогда у меня есть tbase и tlimit, которые пересекают синусоидальную волну.

Я хочу вычислить площадь заштрихованной синей части, отмеченной 1 и 2.

t неизвестно (это время, горизонтальная ось), а c^ (c с кружком) — это просто ось y.

У меня есть только эти 4 значения для работы, пятое значение является средним, например (tmax + tmin) / 2

Обновление 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

Обновление 3

Причина получения площадей: мне нужно рассчитать эти площади для работающего проекта, поскольку они связаны с GDD (дни роста градусов). поэтому tmin и tmax — это минимальное и максимальное значения за день. tbase и tlimit уникальны для каждой культуры.

Синусоидальная волна начнется в точках x = 0 и y = tmin, пик синусоиды достигнет y = tmax.

Обновление 4

после ознакомления с предложенными документами/ссылками. и общаемся с 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 обратно

вот несколько тестов, которые я сделал

Тест 1

// inputs
tmin:5, tmax:25, tbase:10, tlimit:30
// calculated
amplitude:10, angleBase:30.000000000000004, angleLimit:NaN, areaBase:5.23598775598299, areaLimit:NaN, finalArea:NaN

Тест 2

// inputs
tmin:5, tmax:25, tbase:20, tlimit:30
// calculated
amplitude:10, angleBase:NaN, angleLimit:NaN, areaBase:NaN, areaLimit:NaN, finalArea:NaN

Тест 3

// inputs
tmin:5, tmax:25, tbase:15, tlimit:22
// calculated
amplitude:10, angleBase:90, angleLimit:NaN, areaBase:15.707963267948966, areaLimit:NaN, finalArea:NaN

Кажется, это элементарная тригонометрия, но мне трудно понять, где находятся ваши tmin и tmax и что вы пытаетесь вычислить. Можете ли вы прочитать свой текст еще раз? Возможно, изображение не очень четкое. Находится ли t на горизонтальной оси? t возможно, для «времени»?

KIKO Software 13.06.2024 12:40

@KIKOSoftware смотрите мое обновление, но да, это горизонтальная ось. Я не занимался такой математикой более 10 лет, поэтому забыл, как это делать.

X3R0 13.06.2024 12:45

Я думаю, вам нужна интеграция вашей функции, в вашем случае это sin(x). Затем вам нужно найти точки пересечения и получить площадь, просто поставив значения ∫sin(x), насколько я понимаю

mbattaloglu 13.06.2024 12:51

@mbattaloglu Я не понимаю, что ты имеешь в виду.

X3R0 13.06.2024 12:53

Итак, можем ли мы согласиться, что площади 1 и 2 одинаковы? Затем, как уже сказал Мбатталоглу, используйте интеграл от sin(), то есть -cos(). Видеть; Интеграл от Sin x со смещением.

KIKO Software 13.06.2024 12:54

Я думаю, ChatGPT думает, что вы имеете дело с аналоговыми часами? Довольно забавно.

KIKO Software 13.06.2024 12:55

@ X3R0 Итак, вы рисуете графики sin(x). Затем вам нужно найти точки пересечения tbase и tlimit. Затем вычислите ∫sin(x)dx, которое равно -cos(x) + c. Наконец, вы можете поместить значения в -cos(x), вычесть их и просто найти площадь. (При поиске точек пересечения вам необходимо решить sin(x) = tbase, найти x, и x может иметь более 1 решения)

mbattaloglu 13.06.2024 12:56

Просто прочитайте ссылку, предложенную @KIKOSoftware, я не до конца понимаю объяснение.

X3R0 13.06.2024 12:57

@ X3R0 Да, это то, что я говорю, с более понятным способом объяснить вещи.

mbattaloglu 13.06.2024 12:59

Я тоже думаю, что ваш вопрос не совсем ясен. Понятно, но затрудняюсь дать однозначный ответ. Например, где начинается ваша синусоидальная кривая? Это важно. Было бы еще лучше, если бы вы рассказали нам, почему вы хотите знать эти области.

KIKO Software 13.06.2024 13:00

Кстати, они симметричны, поэтому равны друг другу. Так что вам достаточно найти 1 область.

mbattaloglu 13.06.2024 13:02

@KIKOSoftware см. обновление вопроса

X3R0 13.06.2024 13:03

@mbattaloglu да, это имеет смысл, тогда мне нужно найти только одну из областей, которую я могу просто вернуть area * 2

X3R0 13.06.2024 13:04

Возможно эта таблица поможет вам понять косинус. tmin — это наименьшее значение вашего синуса, то есть оно составляет 270 градусов. Косинус там 0,0. Затем вы перемещаетесь вперед, скажем, на 30 градусов, до 300, и там косинус равен 0,5, поэтому, если у вас есть синус с амплитудой 1,0, площадь равна 0,5. Сделайте это как для B, так и для C, вычтите, умножьте на амплитуду, и вы получите одну площадь.

KIKO Software 13.06.2024 13:11

Я знаю, что это не полное решение, но это может помочь вам понять, что вам нужно делать.

KIKO Software 13.06.2024 13:12

@KIKOSoftware, все в порядке, я не ожидал полного решения, но я обновил свой вопрос новой попыткой алгоритма, не могли бы вы указать, что я делаю неправильно?

X3R0 13.06.2024 13:28

Я посмотрю. Да, я забыл сказать: синусоидальная волна имеет как минимум два свойства: амплитуду и период. В вашем коде вы используете tmin и tmax для определения амплитуды, но я не вижу ничего, что определяло бы период. Вряд ли это будет 2*Пи. См.: Амплитуда, Период, Фазовый сдвиг и Частота.

KIKO Software 13.06.2024 13:29

ОК, я посмотрел. Я вижу, вы поняли идею, но я не вижу никакого косинуса? Также полезно, если вы сможете проверить свои расчеты. Например, площадь под единичной синусоидальной кривой от 0 до 180 градусов имеет площадь 2. Умножьте это на амплитуду и период, и вы узнаете, каким должен быть результат для этой площади. Ссылка: Почему площадь под одним горбом синусоиды равна ровно 2?

KIKO Software 13.06.2024 13:34

@KIKOSoftware, не могли бы вы исправить мою последнюю функцию?

X3R0 13.06.2024 13:36

Нет, извините, я все еще не уверен, что мне нужно посчитать. Я не хочу дать неправильный ответ.

KIKO Software 13.06.2024 13:37

я заменил в своей функции 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

X3R0 13.06.2024 13:41

Функция арксинус является обратной функцией синуса. Вы не можете заменить Math.asin на Math.cos, потому что первое является обратным, а второе — нет. Математика – это не просто попытка что-то сделать, а знание того, что вы делаете. Я понимаю, что это занимает больше времени, и вы хотите пойти по простому пути, но здесь это не работает.

KIKO Software 13.06.2024 13:46

@KIKOSoftware Я согласен

X3R0 13.06.2024 13:48

В этом посте слишком много обновлений. Пожалуйста, просто перепишите свой пост в отдельный пост с вопросами, в котором будет указано, какой у вас код, какая проблема в этом коде и какую отладку/тестирование вы с ним выполняли. Если вы обновите ее, и это все изменит, старый вопрос больше не будет вашим вопросом, и будущим посетителям просто нужно будет прочитать всю книгу, чтобы увидеть, является ли ваша проблема и их проблемой.

Mike 'Pomax' Kamermans 13.06.2024 21:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
24
76
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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 13.06.2024 13:51

Я не понимаю, что ты имеешь в виду @X3R0

mbattaloglu 13.06.2024 13:52
Ответ принят как подходящий

Как я вас понимаю: Если я вас правильно понял, вот как выглядит кривая (вот интерактивный график десмоса, включающий значение площади):

Как упростить задачу: Тогда по логике обе площади равны. Замена аргумента 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?

X3R0 14.06.2024 10:54

пока я смотрю calculateAreaAboveThreshold = (tmin:number, tmax:number, tbase:number, tlimit:number) => {/*code here*/}

X3R0 14.06.2024 10:55

Да, это. tbase = start и tlimit = end.

Kevin Dietrich 14.06.2024 11:25

Другие вопросы по теме