I want to generate a sine wave from 2 data points, tmin
and tmax
. where tmin
is where the sin wave starts, and the tmax
is the top most point of the sine wave.
Then I want to find where tbase
and tlimit
intersect with the sine wave created in the previous step.
Example.
C = tlimit
B = tbase
I want to find area's 1
and 2
(as in the example image)
currently, I'm able to calculate the area when tlimit
is above tmax
and tbase
is less than or equal to tmin
, just need help with this. here are my existing code but it may be wrong.
Existing Code
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
I've been watching videos from Khan Academy
on YT, about AP Calculus
but I'm super lost
I have tmin
, tmax
these are the values needed to generate the sine wave. then i have tbase
and tlimit
which intersect the sine wave.
I want to calculate the area for the blue shaded part labeled 1
and 2
.
t is unknown (its the time, horizontal axis) and c^ (c with a circle) is just the y axis.
I only have those 4 values to work with, a 5th value which is the mean such as (tmax + tmin) / 2
ChatGPT gave me this, but I don't think this is right at all.
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
Reason for getting the areas, I need to calculate these area's for a project at work as its related to GDD (Growing degree days). so the tmin
and tmax
are min and max values for a day. tbase
and tlimit
are the are unique to each crop.
The sine wave would start at x = 0
and y = tmin
, the peak of the sine wave would reach y = tmax
after reviewing the suggested documents / links. and chatting with ChatGPT
I've managed to come up with this function
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;
}
but I get 0 returned
here are the few tests I've done
// 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
How I understand you: If I understood you correctly that's what the curve looks like (here is a interactive desmos graph inccluding the value of the area):
How to make the problem simpler: Then by logic both areas are equal. Substituting the argument t
of the sine curve by t +
the distance between tmax
and the y-axis would give you ... * cos( x ) + ...
and the cosine function has axis symmetry to y = 0
aka bot areas are equal.
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;
}
This code seems gives the same output as desmos. E.g.:
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;
...
If you have any questions, just ask it.
So calculating one area is enough. Using your information the function describing the sine curve would f( x ) = (tmax - tmin) / 2 * sin( x ) + (tmax + tmin) / 2
, the upper line would be tlimit
and the lower line tbase
. The purple are is the difference between the area of sine curve to the x axis and the lower line to the x-axis. These are computable by taking the integral from f^-1( tbase )
to f^-1( tlimit )
.
We have to solve (tmax - tmin) / 2 * sin( x ) + (tmax + tmin) / 2 = c
for x
. Subtract (tmax + tmin) / 2
, then divide by (tmax - tmin) / 2
and take the inverse sine function: x = arcsin((c - (tmax + tmin) / 2) / ((tmax - tmin) / 2))
. f^-1( x ) = arcsin((x - (tmax + tmin) / 2) / ((tmax - tmin) / 2))
.
Taking the antiderivative of f( x )
and the lower line. Using the factor rule, sum rule and 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
So the integrals are -(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))
and tbase * tlimit - tbase * tbase
. That one area is equal to their difference and there are two so the sum of the areas A
is:
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)))|
Why the | ... |? The area can't be negative, so to fix to fix that possible problem we just use the absolute value.