diff --git a/src/yugecin/opsudance/movers/CircleMover.java b/src/yugecin/opsudance/movers/CircleMover.java
new file mode 100644
index 00000000..fc94c505
--- /dev/null
+++ b/src/yugecin/opsudance/movers/CircleMover.java
@@ -0,0 +1,93 @@
+/*
+ * opsu!dance - fork of opsu! with cursordance auto
+ * Copyright (C) 2016 yugecin
+ *
+ * opsu!dance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * opsu! is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with opsu!dance. If not, see .
+ */
+package yugecin.opsudance.movers;
+
+import itdelatrisu.opsu.Container;
+import itdelatrisu.opsu.Utils;
+import itdelatrisu.opsu.objects.GameObject;
+
+public class CircleMover extends Mover {
+
+ private double radius;
+ private double SOME_CONSTANT;
+ private double middlexoffset;
+ private double middleyoffset;
+ private double ang;
+
+ public CircleMover(GameObject start, GameObject end, int dir) {
+ super(start, end, dir);
+ if (startX - endX == 0 && startY - endY == 0) {
+ int quadr = Utils.getQuadrant(startX, startY);
+ switch (quadr) {
+ case 1: ang = 135d / 180d * Math.PI; break;
+ case 2: ang = 45d / 180d * Math.PI; break;
+ case 3: ang = -45d / 180d * Math.PI; break;
+ case 4: ang = -135d / 180d * Math.PI; break;
+ }
+ } else {
+ ang = Math.atan2(startY - endY, startX - endX);
+ }
+ SOME_CONSTANT = dir * 2d * Math.PI;
+ // TODO: circle into slider?
+ radius = end.getTime() - start.getEndTime();
+ if (start.isSpinner() || end.isSpinner()) {
+ middlexoffset = -Math.cos(ang) * radius;
+ middleyoffset = -Math.sin(ang) * radius;
+ } else {
+ calcMaxRadius();
+ }
+ }
+
+ private void calcMaxRadius() {
+ double[] pos = new double[2];
+ for (int tries = 0; tries < 7; tries++) {
+ middlexoffset = -Math.cos(ang) * radius;
+ middleyoffset = -Math.sin(ang) * radius;
+ boolean pass = true;
+ for (double t = 0d; t < 1d; t += 0.1d) {
+ double a = ang + SOME_CONSTANT * t;
+ pos[0] = (startX + (endX - startX) * t) - middlexoffset - Math.cos(a) * radius;
+ pos[1] = (startY + (endY - startY) * t) - middleyoffset - Math.sin(a) * radius;
+ if (pos[0] < 0 || Container.width < pos[0] || pos[1] < 0 || Container.height < pos[1]) {
+ pass = false;
+ break;
+ }
+ }
+ if (pass) {
+ return;
+ }
+ radius *= 0.8d;
+ }
+ }
+
+ @Override
+ public double[] getPointAt(int time) {
+ double t = getT(time);
+ double ang = this.ang + SOME_CONSTANT * t;
+ return new double[] {
+ (startX + (endX - startX) * t) - middlexoffset - Math.cos(ang) * radius,
+ (startY + (endY - startY) * t) - middleyoffset - Math.sin(ang) * radius
+ };
+ }
+
+ @Override
+ public String getName() {
+ return "Circle";
+ }
+
+}
diff --git a/src/yugecin/opsudance/movers/HalfCircleMover.java b/src/yugecin/opsudance/movers/HalfCircleMover.java
new file mode 100644
index 00000000..e0a4bc75
--- /dev/null
+++ b/src/yugecin/opsudance/movers/HalfCircleMover.java
@@ -0,0 +1,52 @@
+/*
+ * opsu!dance - fork of opsu! with cursordance auto
+ * Copyright (C) 2016 yugecin
+ *
+ * opsu!dance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * opsu! is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with opsu!dance. If not, see .
+ */
+package yugecin.opsudance.movers;
+
+import itdelatrisu.opsu.Utils;
+import itdelatrisu.opsu.objects.GameObject;
+
+public class HalfCircleMover extends Mover {
+
+ private double middlex;
+ private double middley;
+ private double radius;
+ private double ang;
+
+ public HalfCircleMover(GameObject start, GameObject end, int dir) {
+ super(start, end, dir);
+ middlex = (startX + endX) / 2d;
+ middley = (startY + endY) / 2d;
+ radius = Utils.distance(middlex, middley, startX, startY);
+ ang = Math.atan2(startY - middley, startX - middlex);
+ }
+
+ @Override
+ public double[] getPointAt(int time) {
+ double ang = this.ang + Math.PI * getT(time) * dir;
+ return new double[] {
+ middlex + Math.cos(ang) * radius,
+ middley + Math.sin(ang) * radius
+ };
+ }
+
+ @Override
+ public String getName() {
+ return "Half circle";
+ }
+
+}
diff --git a/src/yugecin/opsudance/movers/HalfEllipseMover.java b/src/yugecin/opsudance/movers/HalfEllipseMover.java
new file mode 100644
index 00000000..7dff4803
--- /dev/null
+++ b/src/yugecin/opsudance/movers/HalfEllipseMover.java
@@ -0,0 +1,67 @@
+/*
+ * opsu!dance - fork of opsu! with cursordance auto
+ * Copyright (C) 2016 yugecin
+ *
+ * opsu!dance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * opsu! is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with opsu!dance. If not, see .
+ */
+package yugecin.opsudance.movers;
+
+import itdelatrisu.opsu.Utils;
+import itdelatrisu.opsu.objects.GameObject;
+
+public class HalfEllipseMover extends Mover {
+
+ private double middlex;
+ private double middley;
+ private double radius;
+ private double ang;
+ private double mod;
+
+ public HalfEllipseMover(GameObject start, GameObject end, int dir) {
+ super(start, end, dir);
+ middlex = (startX - endX) / 2d;
+ middley = (startY - endY) / 2d;
+ radius = Utils.distance(middlex, middley, startX, startY);
+ ang = Math.atan2(startY - middley, startX - middlex);
+ mod = 2d;
+ }
+
+ public void setMod(double mod) {
+ this.mod = mod;
+ }
+
+ @Override
+ public double[] getPointAt(int time) {
+ double Tangle = Math.PI * getT(time) * dir;
+ double x = middlex + Math.cos(Tangle) * radius;
+ double y = middley + Math.sin(Tangle) * radius;
+ double dx = middlex - x;
+ double dy = middley - y;
+
+ double d = Math.sqrt(dx * dx + dy * dy);
+ double a = Math.atan2(dy, dx);
+ double my = a - ang;
+
+ return new double[] {
+ middlex - Math.cos(my) * d,
+ middley - Math.sin(my) * d
+ };
+ }
+
+ @Override
+ public String getName() {
+ return "Half ellipse " + mod;
+ }
+
+}
diff --git a/src/yugecin/opsudance/movers/JumpMover.java b/src/yugecin/opsudance/movers/JumpMover.java
new file mode 100644
index 00000000..78c8e814
--- /dev/null
+++ b/src/yugecin/opsudance/movers/JumpMover.java
@@ -0,0 +1,44 @@
+/*
+ * opsu!dance - fork of opsu! with cursordance auto
+ * Copyright (C) 2016 yugecin
+ *
+ * opsu!dance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * opsu! is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with opsu!dance. If not, see .
+ */
+package yugecin.opsudance.movers;
+
+import itdelatrisu.opsu.objects.GameObject;
+
+public class JumpMover extends Mover {
+
+ private double[] pos;
+
+ public JumpMover(GameObject start, GameObject end, int dir) {
+ super(start, end, dir);
+ this.pos = new double[] {
+ end.start.x,
+ end.start.y
+ };
+ }
+
+ @Override
+ public double[] getPointAt(int time) {
+ return pos;
+ }
+
+ @Override
+ public String getName() {
+ return "Jump";
+ }
+
+}
diff --git a/src/yugecin/opsudance/movers/LinearMover.java b/src/yugecin/opsudance/movers/LinearMover.java
new file mode 100644
index 00000000..d44086d0
--- /dev/null
+++ b/src/yugecin/opsudance/movers/LinearMover.java
@@ -0,0 +1,42 @@
+/*
+ * opsu!dance - fork of opsu! with cursordance auto
+ * Copyright (C) 2016 yugecin
+ *
+ * opsu!dance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * opsu! is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with opsu!dance. If not, see .
+ */
+package yugecin.opsudance.movers;
+
+import itdelatrisu.opsu.objects.GameObject;
+
+public class LinearMover extends Mover {
+
+ public LinearMover(GameObject start, GameObject end, int dir) {
+ super(start, end, dir);
+ }
+
+ @Override
+ public double[] getPointAt(int time) {
+ double t = getT(time);
+ return new double[] {
+ startX + (endX - startX) * t,
+ startY + (endY - startY) * t
+ };
+ }
+
+ @Override
+ public String getName() {
+ return "Linear";
+ }
+
+}
diff --git a/src/yugecin/opsudance/movers/Mover.java b/src/yugecin/opsudance/movers/Mover.java
new file mode 100644
index 00000000..248d8281
--- /dev/null
+++ b/src/yugecin/opsudance/movers/Mover.java
@@ -0,0 +1,52 @@
+/*
+ * opsu!dance - fork of opsu! with cursordance auto
+ * Copyright (C) 2016 yugecin
+ *
+ * opsu!dance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * opsu! is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with opsu!dance. If not, see .
+ */
+package yugecin.opsudance.movers;
+
+import itdelatrisu.opsu.objects.GameObject;
+
+public abstract class Mover {
+
+ protected int dir;
+
+ private int startT;
+ private int totalT;
+
+ protected double startX;
+ protected double startY;
+
+ protected double endX;
+ protected double endY;
+
+ public Mover(GameObject start, GameObject end, int dir) {
+ this.dir = dir;
+ this.startX = start.end.x;
+ this.startY = start.end.y;
+ this.endX = end.start.x;
+ this.endY = end.start.y;
+ this.startT = start.getEndTime();
+ this.totalT = end.getTime() - startT;
+ }
+
+ protected final double getT(int time) {
+ return (time - startT) / totalT;
+ }
+
+ public abstract double[] getPointAt(int time);
+ public abstract String getName();
+
+}
diff --git a/src/yugecin/opsudance/movers/QuartCircleMover.java b/src/yugecin/opsudance/movers/QuartCircleMover.java
new file mode 100644
index 00000000..10527579
--- /dev/null
+++ b/src/yugecin/opsudance/movers/QuartCircleMover.java
@@ -0,0 +1,57 @@
+/*
+ * opsu!dance - fork of opsu! with cursordance auto
+ * Copyright (C) 2016 yugecin
+ *
+ * opsu!dance is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * opsu! is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with opsu!dance. If not, see .
+ */
+package yugecin.opsudance.movers;
+
+import itdelatrisu.opsu.Utils;
+import itdelatrisu.opsu.objects.GameObject;
+
+public class QuartCircleMover extends Mover {
+
+ private double middlex;
+ private double middley;
+ private double radius;
+ private double ang;
+
+ public QuartCircleMover(GameObject start, GameObject end, int dir) {
+ super(start, end, dir);
+ middlex = (startX - endX) / 2d;
+ middley = (startY - endY) / 2d;
+ radius = Utils.distance(middlex, middley, startX, startY);
+ ang = Math.atan2(startY - middley, startX - middlex) + Math.PI / 2d * dir;
+ middlex = middlex + Math.cos(ang) * radius;
+ middley = middley + Math.sin(ang) * radius;
+ radius = Utils.distance(middlex, middley, startX, startY);
+ ang = Math.atan2(startY - middley, startX - middlex);
+ }
+
+ @Override
+ public double[] getPointAt(int time) {
+ double ang = this.ang - Math.PI / 2d * getT(time) * dir;
+
+ return new double[] {
+ middlex + Math.cos(ang) * radius,
+ middlex + Math.sin(ang) * radius
+ };
+ }
+
+ @Override
+ public String getName() {
+ return "1/4th circle";
+ }
+
+}