From d27bc359531c6fd099f4c160eedb670031dab053 Mon Sep 17 00:00:00 2001
From: ezsh <ezsh.junk@gmail.com>
Date: Mon, 3 Jan 2022 22:46:00 +0100
Subject: [PATCH] Add function to compute volume of the breast pocket

---
 js/medicine/surgery/assets/boobs.js | 39 +++++++++++++++++++++++++++++
 js/utils.js                         | 14 +++++++++++
 2 files changed, 53 insertions(+)

diff --git a/js/medicine/surgery/assets/boobs.js b/js/medicine/surgery/assets/boobs.js
index f873c09c957..c7b0d4c4d14 100644
--- a/js/medicine/surgery/assets/boobs.js
+++ b/js/medicine/surgery/assets/boobs.js
@@ -411,3 +411,42 @@ App.Medicine.Surgery.Reactions.BoobsLoss = class extends App.Medicine.Surgery.Si
 		}
 	};
 }
+
+/**
+ * @param {FC.HumanState} slave
+ * @returns {number}
+ */
+App.Medicine.Surgery.breastPocketVolume = function(slave) {
+	/*
+	The breast is approximated by a spherical cap with the volume of slave.boobs.
+	The radius `a` of the cap is proportional to slave height and shoulders width
+	We assume that the skin has elasticity coefficient that depends on slave physical age.
+	Max pocket volume is therefore the volume of the cap with the same base but the
+	surface stretched by the skin elasticity coefficient
+	V = 1/6*πh(3a²+h²)
+	A = π(a²+h²)
+	*/
+	const a = 0.05 * slave.height + slave.shoulders * 1.1;
+	/* now the eq. for V we rewrite as
+	h³ + 3a³h -6/π*V = 0
+	and replace:
+	p = 3*a³, q = -6/π*V:
+	h³ + ph + q = 0
+	*/
+	const p = 3 * a * a;
+	const q = -6. / Math.PI * slave.boobs;
+	const Q = Math.pow(p / 3, 3) + Math.pow(q / 2, 2);
+	console.assert(Q > 0);
+	const h = Math.cbrt(-q / 2 + Math.sqrt(Q)) + Math.cbrt(-q / 2 - Math.sqrt(Q));
+
+	// now the current skin area:
+	const A = Math.PI * (a * a + h * h);
+
+	const skinStretchFactor = linearInterpolation(Math.max(slave.physicalAge, 13), 13, 1.5, 45, 1.15);
+	console.log(`skinStretchFactor = ${skinStretchFactor}`);
+
+	const hMax = Math.sqrt(A * skinStretchFactor / Math.PI - a * a);
+	const VMax = Math.PI / 6 * hMax * (3 * a * a + hMax * hMax);
+
+	return VMax;
+};
diff --git a/js/utils.js b/js/utils.js
index cba532a786e..985320decf2 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -383,3 +383,17 @@ function median(arr = []) {
 
 	return arr.length % 2 === 0 ? (nums[mid] + nums[mid - 1]) / 2 : nums[mid];
 }
+
+/**
+ * Returns value for point x, computed assuming linear function defined
+ * via two points (x0,y0) and (x1,y1)
+ * @param {number} x
+ * @param {number} x0
+ * @param {number} y0
+ * @param {number} x1
+ * @param {number} y1
+ * @returns {number}
+ */
+function linearInterpolation(x, x0, y0, x1, y1) {
+	return y0 + (x - x0) * ((y1 - y0) / (x1 - x0));
+}
-- 
GitLab