Compare commits
9 Commits
53-als-geb
...
35-als-geb
Author | SHA1 | Date | |
---|---|---|---|
|
13fca50d6f | ||
|
7442d1fca4 | ||
|
cfcbe7d51c | ||
|
3edab82535 | ||
|
3fe90ce547 | ||
|
59c374eb02 | ||
03b056811d | |||
58f1b14ab6 | |||
ab73c5012b |
2
code/src/Fitbot/.gitignore
vendored
2
code/src/Fitbot/.gitignore
vendored
@@ -13,3 +13,5 @@
|
|||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
.cxx
|
.cxx
|
||||||
local.properties
|
local.properties
|
||||||
|
.idea
|
||||||
|
.vscode
|
@@ -35,7 +35,11 @@ dependencies {
|
|||||||
implementation 'com.android.support:cardview-v7:28.0.0'
|
implementation 'com.android.support:cardview-v7:28.0.0'
|
||||||
implementation 'com.android.support:design:28.0.0'
|
implementation 'com.android.support:design:28.0.0'
|
||||||
implementation 'org.joml:joml:1.10.5'
|
implementation 'org.joml:joml:1.10.5'
|
||||||
|
implementation 'com.google.code.gson:gson:2.8.6'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
|
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||||
|
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||||
|
testImplementation 'org.junit.jupiter:junit-jupiter'
|
||||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||||
implementation 'com.aldebaran:qisdk:1.7.5'
|
implementation 'com.aldebaran:qisdk:1.7.5'
|
||||||
|
@@ -15,6 +15,9 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Fitbot" >
|
android:theme="@style/Theme.Fitbot" >
|
||||||
|
<activity
|
||||||
|
android:name=".ui.activities.FitnessActivity"
|
||||||
|
android:exported="true" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activities.MainActivity"
|
android:name=".ui.activities.MainActivity"
|
||||||
android:exported="true" >
|
android:exported="true" >
|
||||||
|
@@ -0,0 +1,104 @@
|
|||||||
|
package com.example.fitbot.exercise;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.example.fitbot.util.path.GesturePath;
|
||||||
|
import com.example.fitbot.util.server.IWebSocketHandler;
|
||||||
|
import com.example.fitbot.util.server.WebSocket;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public abstract class AbstractExercise implements IWebSocketHandler {
|
||||||
|
|
||||||
|
private EMuscleGroup muscleGroup;
|
||||||
|
private GesturePath path;
|
||||||
|
|
||||||
|
// Static fields.
|
||||||
|
private static WebSocket webSocket;
|
||||||
|
private static AbstractExercise currentExercise = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the AbstractExercise class.
|
||||||
|
*
|
||||||
|
* @param muscleGroup The muscle group of the exercise.
|
||||||
|
* @param path The path of the exercise.
|
||||||
|
*/
|
||||||
|
public AbstractExercise(EMuscleGroup muscleGroup, GesturePath path) {
|
||||||
|
this.muscleGroup = muscleGroup;
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the exercise.
|
||||||
|
* This method starts a WebSocket server
|
||||||
|
*/
|
||||||
|
public final void startExercise() {
|
||||||
|
|
||||||
|
// Ensure no other exercise is active.
|
||||||
|
if (currentExercise != null && currentExercise != this) {
|
||||||
|
currentExercise.__stopExercise();
|
||||||
|
Log.i("Exercises", "Another exercise was started when another was still running.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a WebSocket server is already running, change the event handler to be this class.
|
||||||
|
if (webSocket != null && webSocket.isConnected()) {
|
||||||
|
webSocket.setEventHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
webSocket = WebSocket.createServer();
|
||||||
|
Objects.requireNonNull(webSocket, "WebSocket server could not be created.");
|
||||||
|
|
||||||
|
webSocket.startListening();
|
||||||
|
webSocket.setEventHandler(this);
|
||||||
|
currentExercise = this;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method for ending this exercise and returning the grade of the performance
|
||||||
|
* of this activity.
|
||||||
|
*/
|
||||||
|
public final double finishExercise() {
|
||||||
|
this.__stopExercise();
|
||||||
|
|
||||||
|
// TODO: Implement grade calculation
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the exercise.
|
||||||
|
* This method stops the WebSocket server.
|
||||||
|
*/
|
||||||
|
private void __stopExercise() {
|
||||||
|
if (webSocket != null && webSocket.isConnected()) {
|
||||||
|
webSocket.stop();
|
||||||
|
webSocket = null;
|
||||||
|
}
|
||||||
|
currentExercise = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the current exercise is the current activity.
|
||||||
|
*/
|
||||||
|
public final boolean isCurrentActivity() {
|
||||||
|
return currentExercise == this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the muscle group of the exercise.
|
||||||
|
*/
|
||||||
|
public EMuscleGroup getMuscleGroup() {
|
||||||
|
return muscleGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the path of the exercise.
|
||||||
|
*/
|
||||||
|
public GesturePath getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
package com.example.fitbot.exercise;
|
||||||
|
|
||||||
|
public enum EMuscleGroup {
|
||||||
|
// TODO: Implement
|
||||||
|
|
||||||
|
TORSO(0),
|
||||||
|
ARMS(1),
|
||||||
|
LEGS(2),
|
||||||
|
BALANCE(3);
|
||||||
|
|
||||||
|
int muscleGroupIdentifier;
|
||||||
|
|
||||||
|
EMuscleGroup(int identifier) {
|
||||||
|
this.muscleGroupIdentifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIdentifier() {
|
||||||
|
return this.muscleGroupIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EMuscleGroup parse(int identifier) {
|
||||||
|
for (EMuscleGroup muscleGroup : EMuscleGroup.values()) {
|
||||||
|
if (muscleGroup.getIdentifier() == identifier) {
|
||||||
|
return muscleGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,53 @@
|
|||||||
|
package com.example.fitbot.exercise;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ExerciseUser class represents a user of the exercise application.
|
||||||
|
* This contains all necessary information of the current user.
|
||||||
|
*/
|
||||||
|
public class ExerciseUser {
|
||||||
|
|
||||||
|
public float upperArmLength;
|
||||||
|
public float lowerArmLength;
|
||||||
|
public float upperLegLength;
|
||||||
|
public float lowerLegLength;
|
||||||
|
public float height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the ExerciseUser class.
|
||||||
|
* @param upperArmLength The length of the upper arm.
|
||||||
|
* @param lowerArmLength The length of the lower arm.
|
||||||
|
* @param height The height of the user.
|
||||||
|
* @param upperLegLength The length of the upper leg.
|
||||||
|
* @param lowerLegLength The length of the lower leg.
|
||||||
|
*/
|
||||||
|
public ExerciseUser(float upperArmLength, float lowerArmLength, float height, float upperLegLength, float lowerLegLength) {
|
||||||
|
this.upperArmLength = upperArmLength;
|
||||||
|
this.lowerArmLength = lowerArmLength;
|
||||||
|
this.upperLegLength = upperLegLength;
|
||||||
|
this.lowerLegLength = lowerLegLength;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the ExerciseUser class.
|
||||||
|
* @param height The height of the user.
|
||||||
|
*/
|
||||||
|
public ExerciseUser(float height) {
|
||||||
|
this.height = height;
|
||||||
|
this.upperArmLength = height * 0.2f;
|
||||||
|
this.lowerArmLength = height * 0.2f;
|
||||||
|
this.upperLegLength = height * 0.3f;
|
||||||
|
this.lowerLegLength = height * 0.3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor for the ExerciseUser class.
|
||||||
|
* This sets the default height to 180.0f. (1.80m)
|
||||||
|
*/
|
||||||
|
public ExerciseUser() {
|
||||||
|
this(180.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,113 @@
|
|||||||
|
package com.example.fitbot.exercise;
|
||||||
|
|
||||||
|
import com.example.fitbot.util.path.GesturePath;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
|
||||||
|
public class FitnessManager {
|
||||||
|
|
||||||
|
private static final String HOST_ADDRESS = "http://145.92.8.132";
|
||||||
|
|
||||||
|
private static final String PROPERTY_DESC = "description";
|
||||||
|
private static final String PROPERTY_VECTORS = "vector_data";
|
||||||
|
private static final String PROPERTY_NAME = "name";
|
||||||
|
private static final String PROPERTY_MUSCLE_GROUP = "muscle_group";
|
||||||
|
|
||||||
|
private static String sendHTTP(String url, String method, String contentType, String body) {
|
||||||
|
try {
|
||||||
|
URLConnection connection = new URL(url).openConnection();
|
||||||
|
connection.addRequestProperty("Content-Type", contentType);
|
||||||
|
connection.addRequestProperty("Request-Method", method);
|
||||||
|
connection.getOutputStream().write(body.getBytes());
|
||||||
|
connection.connect();
|
||||||
|
InputStream stream = connection.getInputStream();
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
builder.append(line);
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function for retrieving an exercise from the Raspberry Pi Database.
|
||||||
|
*
|
||||||
|
* @param uniqueIdentifier The unique identifier of the exercise
|
||||||
|
* @return The exercise, if it exists on the server. Otherwise null.
|
||||||
|
*/
|
||||||
|
public static <T extends AbstractExercise> AbstractExercise acquireExercise(String uniqueIdentifier, Class<T> referenceClass) {
|
||||||
|
String response = sendHTTP(
|
||||||
|
HOST_ADDRESS + "/acquire", "GET", "application/json", "{\"kind\":\"" + uniqueIdentifier + "\"}"
|
||||||
|
);
|
||||||
|
// Validate the response
|
||||||
|
if (response != null) {
|
||||||
|
try {
|
||||||
|
JsonObject content = JsonParser.parseString(response).getAsJsonObject();
|
||||||
|
Constructor<T> constructor = referenceClass.getConstructor(referenceClass);
|
||||||
|
T instance = null;
|
||||||
|
try {
|
||||||
|
instance = constructor.newInstance(
|
||||||
|
EMuscleGroup.parse(content.get(PROPERTY_MUSCLE_GROUP).getAsInt()),
|
||||||
|
gesturePathFromString(content.get(PROPERTY_VECTORS).getAsString())
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function for converting a string to a GesturePath object.
|
||||||
|
* The input string bytes will be directly converted into 3d vectors.
|
||||||
|
* Every coordinate is composed of 32 bits, so four characters per coordinate.
|
||||||
|
*
|
||||||
|
* @param input The string to convert
|
||||||
|
* @return The GesturePath object
|
||||||
|
*/
|
||||||
|
private static GesturePath gesturePathFromString(String input) {
|
||||||
|
byte[] bytes = input.getBytes();
|
||||||
|
|
||||||
|
// Check if the input string contains a valid amount of bytes (12 bytes per vector)
|
||||||
|
if (input.length() % 12 != 0) {
|
||||||
|
throw new IllegalArgumentException("Invalid input string length");
|
||||||
|
}
|
||||||
|
GesturePath.Builder builder = new GesturePath.Builder();
|
||||||
|
|
||||||
|
float[] xyz = new float[3];
|
||||||
|
for (int i = 0; i < bytes.length; i += 12) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
xyz[j] = Float.intBitsToFloat(
|
||||||
|
(bytes[i + j * 4] & 0xFF) << 24 |
|
||||||
|
(bytes[i + j * 4 + 1] & 0xFF) << 16 |
|
||||||
|
(bytes[i + j * 4 + 2] & 0xFF) << 8 |
|
||||||
|
(bytes[i + j * 4 + 3] & 0xFF)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
builder.addVector(new Vector3f(
|
||||||
|
xyz[0], xyz[1], xyz[2]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,18 +0,0 @@
|
|||||||
package com.example.fitbot.sports;
|
|
||||||
|
|
||||||
public enum ESportType {
|
|
||||||
|
|
||||||
FITNESS("Fitness"),
|
|
||||||
POWER("Krachttrening");
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
ESportType(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,6 +1,7 @@
|
|||||||
package com.example.fitbot.ui.activities;
|
package com.example.fitbot.ui.activities;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.design.widget.NavigationView;
|
import android.support.design.widget.NavigationView;
|
||||||
import android.support.v4.view.GravityCompat;
|
import android.support.v4.view.GravityCompat;
|
||||||
@@ -8,6 +9,8 @@ import android.support.v4.widget.DrawerLayout;
|
|||||||
import android.support.v7.app.ActionBarDrawerToggle;
|
import android.support.v7.app.ActionBarDrawerToggle;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
import com.example.fitbot.R;
|
import com.example.fitbot.R;
|
||||||
|
|
||||||
@@ -17,17 +20,26 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
DrawerLayout drawerLayout;
|
DrawerLayout drawerLayout;
|
||||||
NavigationView navigationView;
|
NavigationView navigationView;
|
||||||
Toolbar toolbar;
|
Toolbar toolbar;
|
||||||
|
Button startButton;
|
||||||
|
|
||||||
@SuppressLint("WrongViewCast")
|
@SuppressLint("WrongViewCast")
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate (Bundle savedInstanceState) {
|
protected void onCreate (Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main );
|
||||||
|
|
||||||
/*---Hooks---*/
|
/*---Hooks---*/
|
||||||
drawerLayout = findViewById(R.id.drawer_layout);
|
drawerLayout = findViewById(R.id.drawer_layout);
|
||||||
navigationView = findViewById(R.id.nav_view);
|
navigationView = findViewById(R.id.nav_view);
|
||||||
toolbar = findViewById(R.id.toolbar);
|
toolbar = findViewById(R.id.toolbar);
|
||||||
|
startButton = findViewById(R.id.startButton);
|
||||||
|
|
||||||
|
startButton.setOnClickListener(v -> {
|
||||||
|
// Switch to fitness activity
|
||||||
|
Log.i("MainActivity", "Switching to FitnessActivity");
|
||||||
|
Intent intent = new Intent(MainActivity.this, FitnessActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
});
|
||||||
|
|
||||||
/*---Tool Bar---*/
|
/*---Tool Bar---*/
|
||||||
// setSupportActionBar(toolbar);
|
// setSupportActionBar(toolbar);
|
||||||
|
@@ -4,6 +4,7 @@ import android.content.Context;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.example.fitbot.util.path.GesturePath;
|
import com.example.fitbot.util.path.GesturePath;
|
||||||
@@ -24,6 +25,8 @@ public class PersonalMotionPreviewElement extends View {
|
|||||||
private Path referencePath, performingPath;
|
private Path referencePath, performingPath;
|
||||||
private Paint referencePaint, performingPaint;
|
private Paint referencePaint, performingPaint;
|
||||||
|
|
||||||
|
private Paint backgroundColor = new Paint();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants for the preview path projection.
|
* Constants for the preview path projection.
|
||||||
*/
|
*/
|
||||||
@@ -42,6 +45,9 @@ public class PersonalMotionPreviewElement extends View {
|
|||||||
*/
|
*/
|
||||||
public PersonalMotionPreviewElement(Context context, GesturePath path) {
|
public PersonalMotionPreviewElement(Context context, GesturePath path) {
|
||||||
super(context);
|
super(context);
|
||||||
|
Log.i("PersonalMotionPreviewElement", "Creating new PersonalMotionPreviewElement.");
|
||||||
|
this.backgroundColor = new Paint();
|
||||||
|
this.backgroundColor.setColor(0xFF000000); // Black
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.motionProcessor = new MotionProcessor();
|
this.motionProcessor = new MotionProcessor();
|
||||||
this.motionProcessor.startListening();
|
this.motionProcessor.startListening();
|
||||||
@@ -158,6 +164,7 @@ public class PersonalMotionPreviewElement extends View {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDraw(Canvas canvas) {
|
public void onDraw(Canvas canvas) {
|
||||||
|
canvas.drawRect(0, 0, getWidth(), getHeight(), backgroundColor);
|
||||||
// Draw the sport preview canvas
|
// Draw the sport preview canvas
|
||||||
canvas.drawPath(referencePath, referencePaint);
|
canvas.drawPath(referencePath, referencePaint);
|
||||||
canvas.drawPath(performingPath, performingPaint);
|
canvas.drawPath(performingPath, performingPaint);
|
||||||
|
@@ -10,7 +10,6 @@ public class GesturePath {
|
|||||||
|
|
||||||
// The vectors that make up the path.
|
// The vectors that make up the path.
|
||||||
private final PathSegment[] segments;
|
private final PathSegment[] segments;
|
||||||
private double curvature;
|
|
||||||
|
|
||||||
public GesturePath(Vector3f[] vectors) {
|
public GesturePath(Vector3f[] vectors) {
|
||||||
this(vectors, 0.0D);
|
this(vectors, 0.0D);
|
||||||
@@ -27,7 +26,6 @@ public class GesturePath {
|
|||||||
if ( vectors.length < 2)
|
if ( vectors.length < 2)
|
||||||
throw new IllegalArgumentException("A path must have at least two points.");
|
throw new IllegalArgumentException("A path must have at least two points.");
|
||||||
|
|
||||||
this.curvature = curvature;
|
|
||||||
this.segments = new PathSegment[vectors.length - 1];
|
this.segments = new PathSegment[vectors.length - 1];
|
||||||
for ( int i = 0; i < vectors.length - 1; i++)
|
for ( int i = 0; i < vectors.length - 1; i++)
|
||||||
segments[i] = new PathSegment(vectors[i], vectors[i + 1]);
|
segments[i] = new PathSegment(vectors[i], vectors[i + 1]);
|
||||||
@@ -39,7 +37,6 @@ public class GesturePath {
|
|||||||
*/
|
*/
|
||||||
public GesturePath(PathSegment... segments) {
|
public GesturePath(PathSegment... segments) {
|
||||||
this.segments = segments;
|
this.segments = segments;
|
||||||
this.curvature = 0.0d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -25,10 +25,9 @@ public class PathSegment {
|
|||||||
* depending on the curvature of the curve. If the curvature is unset, or set to 0
|
* depending on the curvature of the curve. If the curvature is unset, or set to 0
|
||||||
* then this method will use linear interpolation. Otherwise, it will use a curve.
|
* then this method will use linear interpolation. Otherwise, it will use a curve.
|
||||||
*
|
*
|
||||||
* @param dst The destination vector to interpolate to.
|
|
||||||
* @param t The interpolation value between 0 and 1.
|
* @param t The interpolation value between 0 and 1.
|
||||||
*/
|
*/
|
||||||
public Vector3f interpolate(Vector3f dst, double t) {
|
public Vector3f interpolate(double t) {
|
||||||
return new Vector3f(this.start)
|
return new Vector3f(this.start)
|
||||||
.lerp(this.end, (float) Math.min(1.0F, Math.max(0.0F, t)));
|
.lerp(this.end, (float) Math.min(1.0F, Math.max(0.0F, t)));
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,25 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/drawer_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#232323"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
tools:context=".ui.activities.FitnessActivity"
|
||||||
|
tools:openDrawer="start">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.example.fitbot.ui.components.PersonalMotionPreviewElement
|
<com.example.fitbot.ui.components.PersonalMotionPreviewElement
|
||||||
|
android:id="@+id/personalMotionPreviewElement"
|
||||||
|
android:visibility="visible"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
</android.support.v4.widget.DrawerLayout>
|
@@ -0,0 +1,37 @@
|
|||||||
|
package com.example.fitbot;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import com.example.fitbot.util.path.GesturePath;
|
||||||
|
import com.example.fitbot.util.path.PathSegment;
|
||||||
|
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class PathSegmentTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPathSegment() {
|
||||||
|
// Test the PathSegment class
|
||||||
|
Vector3f[] vectors = new Vector3f[2];
|
||||||
|
vectors[0] = new Vector3f(0, 0, 0);
|
||||||
|
vectors[1] = new Vector3f(1, 1, 1);
|
||||||
|
GesturePath path = new GesturePath(vectors);
|
||||||
|
PathSegment[] segments = path.getSegments();
|
||||||
|
assertEquals(1, segments.length);
|
||||||
|
assertEquals(new Vector3f(0, 0, 0), segments[0].getStart());
|
||||||
|
assertEquals(new Vector3f(1, 1, 1), segments[0].getEnd());
|
||||||
|
assertEquals(new Vector3f(0.5f, 0.5f, 0.5f), segments[0].interpolate(0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_pathSegmentInterpolation() {
|
||||||
|
Vector3f start = new Vector3f(0, 0, 0);
|
||||||
|
Vector3f end = new Vector3f(1, 1, 1);
|
||||||
|
PathSegment segment = new PathSegment(start, end);
|
||||||
|
assertEquals(new Vector3f(0.5f, 0.5f, 0.5f), segment.interpolate(0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
109
docs/documentation/android/javaClasses.md
Normal file
109
docs/documentation/android/javaClasses.md
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
# Java class modifiers
|
||||||
|
|
||||||
|
## How are classes build in java?
|
||||||
|
There are a lot of classes with a lot of parameters
|
||||||
|
|
||||||
|
A class always begins with either the public or default or abstract access modifier. Then comes the class name
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```java
|
||||||
|
public class MyClass {
|
||||||
|
//methods and atributes
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
Then in a class you can have Methods or Atributes where the actual code is.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart
|
||||||
|
a[Access Modifiers] --> b[class] --> c[Class name]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Constructor
|
||||||
|
A constructor in Java is a special method that is used to initialize objects. The constructor is called when an object of a class is created. It can be used to set initial values for object attributes.
|
||||||
|
|
||||||
|
The constructor Method is the first method that is called when a class is created. It has the same name as the class and no return type. It is automaticly called when a class is created.
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
A method is a block of code which only runs when it is called. You can pass data, known as parameters, into a method. Methods are used to perform certain actions, and they are also known as functions.
|
||||||
|
|
||||||
|
Methods are build like this
|
||||||
|
```mermaid
|
||||||
|
flowchart
|
||||||
|
A[Access Modifiers] --> B[Method Modifier] --> C[Return Type] --> D[Method Name] --> E[Parameters] --> F[Method Body]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```java
|
||||||
|
public class MyClass {
|
||||||
|
// Method
|
||||||
|
static void myMethod() {
|
||||||
|
// print Hello World!
|
||||||
|
System.out.println("Hello World!");
|
||||||
|
}
|
||||||
|
// Main method
|
||||||
|
//access modifier, Method Modifier, return type, method name, parameters, method body
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// Call the method
|
||||||
|
myMethod();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Atributes
|
||||||
|
Attributes are variables within a class. When an object is created from a class, the object will have these attributes.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```java
|
||||||
|
public class MyClass {
|
||||||
|
int x = 5;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Classes
|
||||||
|
### Class modifiers
|
||||||
|
|
||||||
|
#### Non-access modifiers
|
||||||
|
| Modifier | Description | | | |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| final | The class cannot be inherited by other classes (You will learn more about inheritance in the Inheritance chapter) | | | |
|
||||||
|
| abstract | The class cannot be used to create objects (To access an abstract class, it must be inherited from another class. You will learn more about inheritance and abstraction in the Inheritance and Abstraction chapters) | | | |
|
||||||
|
||||
|
||||||
|
|
||||||
|
#### Access modifiers
|
||||||
|
| Modifier | Description | | | |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| public | The code is accessible for all classes | | | |
|
||||||
|
| private | The code is only accessible within the declared class | | | |
|
||||||
|
| default | The code is only accessible in the same package. This is used when you don't specify a modifier. You will learn more about packages in the Packages chapter | | | |
|
||||||
|
| protected | The code is accessible in the same package and subclasses. You will learn more about subclasses and superclasses in the Inheritance chapter | | | |
|
||||||
|
| | | | | |
|
||||||
|
|
||||||
|
|
||||||
|
## Methods and attributes
|
||||||
|
#### non access modifiers
|
||||||
|
| Modifier | Description | | | |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| final | Attributes and methods cannot be overridden/modified | | | |
|
||||||
|
| static | Attributes and methods belongs to the class, rather than an object. You don't really wanna use this one. | | | |
|
||||||
|
| abstract | Can only be used in an abstract class, and can only be used on methods. The method does not have a body, for example abstract void run();. The body is provided by the subclass (inherited from). You will learn more about inheritance and abstraction in the Inheritance and Abstraction chapters | | | |
|
||||||
|
| transient | Attributes and methods are skipped when serializing the object containing them | | | |
|
||||||
|
| synchronized | Methods can only be accessed by one thread at a time | | | |
|
||||||
|
| volatile | The value of an attribute is not cached thread-locally, and is always read from the "main memory" | | | |
|
||||||
|
||||
|
||||||
|
|
||||||
|
#### Access modifiers
|
||||||
|
| Modifier | Description | | | |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| public | The code is accessible for all classes | | | |
|
||||||
|
| private | The code is only accessible within the declared class | | | |
|
||||||
|
| default | The code is only accessible in the same package. This is used when you don't specify a modifier. You will learn more about packages in the Packages chapter | | | |
|
||||||
|
| protected | The code is accessible in the same package and subclasses. You will learn more about subclasses and superclasses in the Inheritance chapter | | | |
|
||||||
|
| | | | | |
|
||||||
|
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
* https://www.w3schools.com/java/java_modifiers.asp
|
Reference in New Issue
Block a user