about summary refs log tree commit diff
path: root/senseless.h
diff options
context:
space:
mode:
Diffstat (limited to 'senseless.h')
-rw-r--r--senseless.h106
1 files changed, 106 insertions, 0 deletions
diff --git a/senseless.h b/senseless.h
new file mode 100644
index 0000000..e84eed4
--- /dev/null
+++ b/senseless.h
@@ -0,0 +1,106 @@
+#ifndef SENSELESS_H
+#define SENSELESS_H
+
+#include <stddef.h> // size_t
+#include <stdio.h>
+
+void _clamp(double lower, double upper, double *value) {
+	if (*value < lower) {
+		*value = lower;
+	} else if (*value > upper) {
+		*value = upper;
+	}
+}
+
+void _wrap(double *degree) {
+	do {
+		if (*degree < 0)
+			*degree += 360;
+		
+		if (*degree >= 360)
+			*degree -= 360;
+	} while (*degree < 0 || *degree >= 360);
+}
+
+void _min(double *value, double lower) {
+	if (*value < lower)
+		*value = lower;
+}
+
+void _max(double *value, double upper) {
+	if (*value > upper)
+		*value = upper;
+}
+
+double senseless_directions(const char *directions, size_t length) {
+	double degrees = 0.0;
+	double factor = 90.0;
+	size_t consumed = 0;
+
+	do {
+		if (length - consumed == 0)
+			return degrees;
+
+		char current = directions[consumed];
+		if (consumed == 0) {
+			switch (current) {
+				case 'N': case 'n': degrees = 0; break;
+				case 'E': case 'e': degrees = 90; break;
+				case 'S': case 's': degrees = 180; break;
+				case 'W': case 'w': degrees = 270; break;
+			}
+			_wrap(&degrees);
+			continue;
+		}
+
+		factor /= 2;
+		switch (current) {
+			case 'N': case 'n':
+				if (degrees >= 180) {
+					degrees += factor;
+				} else {
+					degrees -= factor;
+				}
+
+				_clamp(0, 360, &degrees);
+				break;
+			case 'S': case 's':
+				if (degrees >= 0 && degrees < 180) {
+					degrees += factor;
+
+					_clamp(0, 180, &degrees);
+				} else {
+					degrees -= factor;
+
+					_clamp(180, 360, &degrees);
+				}
+				break;
+			case 'W': case 'w':
+				if (degrees >= 90 && degrees < 270) {
+					// Covers the bottom-arc
+					degrees += factor;
+					_clamp(90, 270, &degrees);
+				} else if (degrees < 90 && degrees < factor) {
+					// Covers the top-right quadrant
+					degrees = 360 - (factor - degrees);
+				} else {
+					degrees -= factor;
+					_clamp(0, 360, &degrees);
+				}
+				break;
+			case 'E': case 'e':
+				if (degrees >= 270 || degrees < 90) {
+					degrees += factor;
+					_wrap(&degrees);
+				} else {
+					degrees -= factor;
+					_wrap(&degrees);
+				}
+				break;
+		}
+	} while (++consumed);
+
+	return 0.0;
+}
+
+#endif // SENSELESS_H
\ No newline at end of file