diff --git a/code/src/Fitbot/.idea/misc.xml b/code/src/Fitbot/.idea/misc.xml
index 135ab11..a67315e 100644
--- a/code/src/Fitbot/.idea/misc.xml
+++ b/code/src/Fitbot/.idea/misc.xml
@@ -22,6 +22,7 @@
+
diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/components/PersonalMotionPreviewElement.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/components/PersonalMotionPreviewElement.java
index d70c88c..32631ee 100644
--- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/components/PersonalMotionPreviewElement.java
+++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/ui/components/PersonalMotionPreviewElement.java
@@ -2,12 +2,12 @@ package com.example.fitbot.ui.components;
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.Paint;
import android.graphics.Path;
import android.view.View;
import com.example.fitbot.util.path.GesturePath;
import com.example.fitbot.util.path.PathSegment;
-import com.example.fitbot.util.path.Point3D;
import com.example.fitbot.util.processing.MotionData;
import com.example.fitbot.util.processing.MotionProcessor;
@@ -22,6 +22,7 @@ public class PersonalMotionPreviewElement extends View {
private double pathTime = 0.0D; // The timestamp at which the path is currently at.
private MotionProcessor motionProcessor;
private Path referencePath, performingPath;
+ private Paint referencePaint, performingPaint;
/**
* Constants for the preview path projection.
@@ -45,22 +46,41 @@ public class PersonalMotionPreviewElement extends View {
this.motionProcessor = new MotionProcessor();
this.motionProcessor.startListening();
this.motionProcessor.setMotionDataEventHandler((processed, preprocessed, sampleIndex, sampleRate) -> {
- // TODO: Implement the calculation of the drawing path
+ // TODO: Implement the calculation of the `performingPath` based on the motion data
});
- this.referencePath = generatePath()
+ this.referencePath = getDrawablePath(path.getSegments());
this.performingPath = new Path();
+
+ this.referencePaint = new Paint();
+ this.referencePaint.setColor(-1); // White
+ this.referencePaint.setStyle(Paint.Style.STROKE);
+ this.referencePaint.setStrokeWidth(5.0f);
+ this.performingPaint = new Paint();
+ this.performingPaint.setColor(0xFF0000FF); // Blue
+ this.performingPaint.setStyle(Paint.Style.STROKE);
+ this.performingPaint.setStrokeWidth(5.0f);
}
/**
* Method that calculates the path that will be drawn on the
* canvas. This method will be called every time new motion data is received.
*/
- private void calculateDrawingPath(Point3D transformedVector, MotionData motionData, int sampleIndex, double sampleRate) {
+ private void calculateDrawingPath(Vector3f transformedVector, MotionData motionData, int sampleIndex, double sampleRate) {
// Recalculate the personal path based on the new motion data
}
+ /**
+ * Method for setting the gesture path that will be drawn on the canvas.
+ *
+ * @param path The gesture path to draw.
+ */
+ public void setGesturePath(GesturePath path) {
+ this.path = path;
+ this.referencePath = getDrawablePath(path.getSegments());
+ }
+
/**
* Method for setting the rotation of the preview path.
*
@@ -111,17 +131,12 @@ public class PersonalMotionPreviewElement extends View {
* Method that converts a sequence of vectors to a Path object.
* This path is a set of bezier curves that will be drawn on the canvas.
*
- * @param curvature The curvature of the bezier curves.
- * This number must be between 0 and 1, and it represents
- * by how much the path segments will be curved.
- * A value of 0 represents no curvature at all,
- * while values closer to 1 approach full circular curvature.
* @param segments The path segments in the path.
* These segments will be connected by bezier curves, which
* all have unique curvature values.
* @return The generated path object.
*/
- private Path getDrawablePath(double curvature, PathSegment... segments) {
+ private Path getDrawablePath(PathSegment... segments) {
Path calculatedPath = new Path();
@@ -144,8 +159,7 @@ public class PersonalMotionPreviewElement extends View {
@Override
public void onDraw(Canvas canvas) {
// Draw the sport preview canvas
-
-
-
+ canvas.drawPath(referencePath, referencePaint);
+ canvas.drawPath(performingPath, performingPaint);
}
}
diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/PathSegment.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/PathSegment.java
index 05f58a7..9f0c361 100644
--- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/PathSegment.java
+++ b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/PathSegment.java
@@ -4,11 +4,8 @@ import org.joml.Vector3f;
public class PathSegment {
- private final double curvature;
- private final Vector3f start, end, normal;
- private final double horizontalDistance;
+ private final Vector3f start, end;
private final double distance;
- private final double vectorAngle; // The angle of the vector from the start to the end point.
/**
* Constructor for creating a PathSegment of two lines, with the normal vector
@@ -18,48 +15,8 @@ public class PathSegment {
* @param end The end point of the line segment.
*/
public PathSegment(Vector3f start, Vector3f end) {
- this.curvature = 0.0D;
this.start = start;
this.end = end;
- this.horizontalDistance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.z - start.z, 2));
- this.vectorAngle = Math.atan2(end.y - start.y, horizontalDistance);
- this.distance = start.distance(end);
-
- // Normal vector calculation
- double horizontalAngle = Math.atan2(end.z - start.z, end.x - start.x);
- double verticalAngle = Math.atan2(end.y - start.y, horizontalDistance);
- float sinVertical = (float)Math.sin(verticalAngle);
- float cosVertical = (float)Math.cos(verticalAngle);
- float sinHorizontal = (float)Math.sin(horizontalAngle);
- float cosHorizontal = (float)Math.cos(horizontalAngle);
- // The normal vector faces directly upward relative to the line between start and end.
- // This means the normal vector is the perpendicular bisecting line from the line segment.
- this.normal = new Vector3f(
- sinVertical * cosHorizontal,
- cosVertical,
- sinVertical * sinHorizontal
- );
- }
-
- /**
- * Create a new path segment with a given start and end point.
- *
- * @param start The start point of the path segment.
- * @param end The end point of the path segment.
- * A value of 0 will result in the normal vector pointing upwards.
- * @param normal The normal vector of the path segment.
- * This vector determines how the line curves, if it has a positive curvature.
- * @param curvature The curvature of the path segment.
- * This value is between -1 and 1, and is used to determine the curvature of the path,
- * around the normal vector.
- */
- public PathSegment(Vector3f start, Vector3f end, Vector3f normal, double curvature) {
- this.curvature = curvature;
- this.start = start;
- this.end = end;
- this.horizontalDistance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.z - start.z, 2));
- this.vectorAngle = Math.atan2(end.y - start.y, horizontalDistance);
- this.normal = normal;
this.distance = start.distance(end);
}
@@ -71,40 +28,9 @@ public class PathSegment {
* @param dst The destination vector to interpolate to.
* @param t The interpolation value between 0 and 1.
*/
- public void interpolate(Vector3f dst, double t) {
- t = Math.min(1.0D, Math.max(0.0D, t)); // Ensure boundaries
-
- // If curvature is 0, use linear interpolation.
- if (this.curvature == 0.0D) {
- dst.set(start).lerp(end, (float) t);
- } else {
- // Interpolate over the ellipse.
- double angle = t * Math.PI + vectorAngle; // Angle for on the ellipse
- double cos = Math.cos(angle);
- double sin = Math.sin(angle);
-
- double
-
- // Calculate the ellipse.
-
-
- }
- }
-
- /**
- * Method for returning the control point of the path segment.
- * This point is the point that the path segment curves around.
- *
- * @return The control point of the path segment.
- */
- public Vector3f getControlPoint() {
- return new Vector3f(
- (this.start.x + this.end.x) / 2.0F,
- (this.start.y + this.end.y) / 2.0F,
- (this.start.z + this.end.z) / 2.0F
- )
- .add(this.normal
- .mul((float) this.curvature * (float) this.distance / 2.0F));
+ public Vector3f interpolate(Vector3f dst, double t) {
+ return new Vector3f(this.start)
+ .lerp(this.end, (float) Math.min(1.0F, Math.max(0.0F, t)));
}
/**
@@ -117,16 +43,21 @@ public class PathSegment {
* @return The difference between the vector and the path segment.
*/
public double difference(Vector3f other) {
- return 0.0D; // TODO: Implement.
- }
- /**
- * Get the curvature of the path segment.
- *
- * @return The curvature of the path segment.
- */
- public double getVectorAngle() {
- return this.vectorAngle;
+ if (this.distance == 0)
+ return this.start.distance(other);
+
+ double t = ((other.x - this.start.x) * (this.end.x - this.start.x) +
+ (other.y - this.start.y) * (this.end.y - this.start.y) +
+ (other.z - this.start.z) * (this.end.z - this.start.z)) / distance;
+
+ t = Math.max(0, Math.min(1, t));
+
+ return other.distance(new Vector3f(
+ (float) (this.start.x + t * (this.end.x - this.start.x)),
+ (float) (this.start.y + t * (this.end.y - this.start.y)),
+ (float) (this.start.z + t * (this.end.z - this.start.z))
+ ));
}
/**
diff --git a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/Point3D.java b/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/Point3D.java
deleted file mode 100644
index de14c78..0000000
--- a/code/src/Fitbot/app/src/main/java/com/example/fitbot/util/path/Point3D.java
+++ /dev/null
@@ -1,258 +0,0 @@
-package com.example.fitbot.util.path;
-
-import java.util.Arrays;
-import java.util.Comparator;
-
-public class Point3D {
-
- public double x, y, z;
-
- /**
- * Constructor for creating a new vector.
- *
- * @param x The X component of the vector.
- * @param y The Y component of the vector.
- * @param z The Z component of the vector.
- */
- public Point3D(double x, double y, double z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- /**
- * Copy the vector.
- *
- * @return A new vector with the same values.
- */
- public Point3D copy() {
- return new Point3D(this.x, this.y, this.z);
- }
-
- /**
- * Get the zero vector.
- *
- * @return The zero vector.
- */
- public static Point3D zero() {
- return new Point3D(0, 0, 0);
- }
-
- /**
- * Get the magnitude of the vector.
- *
- * @return The magnitude of the vector.
- */
- public double magnitude() {
- return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
- }
-
- /**
- * Normalize the vector.
- *
- * @return The normalized vector.
- */
- public Point3D normalize() {
- double mag = this.magnitude();
- if (mag == 0) throw new IllegalArgumentException("Cannot normalize the zero vector.");
- return new Point3D(this.x / mag, this.y / mag, this.z / mag);
- }
-
- /**
- * Subtract the vector from another vector.
- *
- * @param other The other vector to subtract.
- * @return The new vector.
- */
- public Point3D subtract(Point3D other) {
- return new Point3D(this.x - other.x, this.y - other.y, this.z - other.z);
- }
-
- /**
- * Add the vector to another vector.
- *
- * @param other The other vector to add.
- * @return The new vector.
- */
- public Point3D add(Point3D other) {
- return new Point3D(this.x + other.x, this.y + other.y, this.z + other.z);
- }
-
- /**
- * Multiply the vector by a scalar.
- *
- * @param scalar The scalar to multiply by.
- * @return The multiplied vector.
- */
- public Point3D multiply(double scalar) {
- return new Point3D(this.x * scalar, this.y * scalar, this.z * scalar);
- }
-
- /**
- * Divide the vector by a scalar.
- *
- * @param scalar The scalar to divide by.
- * @return The divided vector.
- */
- public Point3D divide(double scalar) {
- if (scalar == 0) throw new IllegalArgumentException("Cannot divide by zero.");
- return new Point3D(this.x / scalar, this.y / scalar, this.z / scalar);
- }
-
- /**
- * Negate the vector.
- *
- * @return The negated vector.
- */
- public Point3D negate() {
- return new Point3D(-this.x, -this.y, -this.z);
- }
-
- /**
- * Rotate the vector around the X, Y, and Z axes.
- *
- * @param radX Rotation around the X axis in radians.
- * @param radY Rotation around the Y axis in radians.
- * @param radZ Rotation around the Z axis in radians.
- * @return The rotated vector.
- */
- public Point3D rotate(double radX, double radY, double radZ) {
- double cosX = Math.cos(radX);
- double cosY = Math.cos(radY);
- double cosZ = Math.cos(radZ);
- double sinX = Math.sin(radX);
- double sinY = Math.sin(radY);
- double sinZ = Math.sin(radZ);
- double newX = x * cosY * cosZ + y * cosY * sinZ - z * sinY;
- double newY = x * (sinX * sinY * cosZ - cosX * sinZ) + y * (sinX * sinY * sinZ + cosX * cosZ) + z * sinX * cosY;
- double newZ = x * (cosX * sinY * cosZ + sinX * sinZ) + y * (cosX * sinY * sinZ - sinX * cosZ) + z * cosX * cosY;
- return new Point3D(newX, newY, newZ);
- }
-
- /**
- * Rotate the vector around the X, Y, and Z axes.
- *
- * @param rotation The rotation vector.
- * @return The rotated vector.
- */
- public Point3D rotate(Point3D rotation) {
- return rotate(rotation.x, rotation.y, rotation.z);
- }
-
- /**
- * Rotate the vector around the X axis.
- *
- * @param angle Rotation around the X axis in radians.
- * @return The rotated vector.
- */
- public Point3D rotateX(double angle) {
- double sinTheta = Math.sin(angle);
- double cosTheta = Math.cos(angle);
- return new Point3D(
- x,
- y * cosTheta - z * sinTheta,
- y * sinTheta + z * cosTheta
- );
- }
-
- /**
- * Rotate the vector around the Y axis.
- *
- * @param angle Rotation around the Y axis in radians.
- * @return The rotated vector.
- */
- public Point3D rotateY(double angle) {
- double sinTheta = Math.sin(angle);
- double cosTheta = Math.cos(angle);
- return new Point3D(
- x * cosTheta + z * sinTheta,
- y,
- -x * sinTheta + z * cosTheta
- );
- }
-
- /**
- * Rotate the vector around the Z axis.
- *
- * @param angle Rotation around the Z axis in radians.
- * @return The rotated vector.
- */
- public Point3D rotateZ(double angle) {
- double sinTheta = Math.sin(angle);
- double cosTheta = Math.cos(angle);
- return new Point3D(
- x * cosTheta - y * sinTheta,
- x * sinTheta + y * cosTheta,
- z
- );
- }
-
- /**
- * Get the squared distance between this vector and another vector.
- *
- * @param compare The other vector.
- * @return The squared distance between the two vectors.
- */
- public double distanceSq(Point3D compare) {
- return Math.pow(compare.x - x, 2) + Math.pow(compare.y - y, 2) + Math.pow(compare.z - z, 2);
- }
-
- /**
- * Get the distance between this vector and another vector.
- *
- * @param compare The other vector.
- * @return The distance between the two vectors.
- */
- public double distance(Point3D compare) {
- return Math.sqrt(distanceSq(compare));
- }
-
- /**
- * Calculate the distance to a line defined by two points.
- *
- * @param lineStart The starting point of the line.
- * @param lineEnd The ending point of the line.
- * @return The distance to the line.
- */
- public double distanceToLine(Point3D lineStart, Point3D lineEnd) {
- double lineDistance = lineStart.distanceSq(lineEnd);
- if (lineDistance == 0)
- return this.distanceSq(lineStart);
-
- double t = ((this.x - lineStart.x) * (lineEnd.x - lineStart.x) +
- (this.y - lineStart.y) * (lineEnd.y - lineStart.y) +
- (this.z - lineStart.z) * (lineEnd.z - lineStart.z)) / lineDistance;
-
- t = Math.max(0, Math.min(1, t));
-
- return this.distanceSq(new Point3D(
- lineStart.x + t * (lineEnd.x - lineStart.x),
- lineStart.y + t * (lineEnd.y - lineStart.y),
- lineStart.z + t * (lineEnd.z - lineStart.z))
- );
- }
-
- /**
- * Retrieve the closest vector to this one given a list of vectors.
- *
- * @param vectors The list of vectors to compare.
- * @return The closest vector.
- */
- public Point3D closest(Point3D... vectors) {
- return Arrays.stream(vectors).min(Comparator.comparingDouble(this::distanceSq)).orElse(null);
- }
-
- public Point3D map(VectorMapFunction function) {
- return function.apply(this);
- }
-
- public interface VectorMapFunction {
- Point3D apply(Point3D vector);
- }
-
- @Override
- public String toString()
- {
- return "Vector3(" + this.x + ", " + this.y + ", " + this.z + ")";
- }
-}
diff --git a/code/src/Fitbot/app/src/main/res/layout/activity_fitness.xml b/code/src/Fitbot/app/src/main/res/layout/activity_fitness.xml
new file mode 100644
index 0000000..35990c8
--- /dev/null
+++ b/code/src/Fitbot/app/src/main/res/layout/activity_fitness.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file