diff --git a/src/main/java/de/neemann/digital/draw/graphics/VectorFloat.java b/src/main/java/de/neemann/digital/draw/graphics/VectorFloat.java
index 220b26410..d6467a7d7 100644
--- a/src/main/java/de/neemann/digital/draw/graphics/VectorFloat.java
+++ b/src/main/java/de/neemann/digital/draw/graphics/VectorFloat.java
@@ -131,6 +131,12 @@ public class VectorFloat implements VectorInterface {
return Objects.hash(x, y);
}
+ @Override
+ public String toString() {
+ return "(x=" + x
+ + ", y=" + y
+ + ')';
+ }
@Override
public Vector round() {
diff --git a/src/main/java/de/neemann/digital/fsm/FSMDemos.java b/src/main/java/de/neemann/digital/fsm/FSMDemos.java
index ae91fa4bd..49334116e 100644
--- a/src/main/java/de/neemann/digital/fsm/FSMDemos.java
+++ b/src/main/java/de/neemann/digital/fsm/FSMDemos.java
@@ -13,6 +13,20 @@ public final class FSMDemos {
private FSMDemos() {
}
+
+ /**
+ * Blink
+ *
+ * @return the fsm
+ */
+ public static FSM blink() {
+ State off = new State("off");
+ State on = new State("on");
+ return new FSM(off, on)
+ .transition(on, off, null)
+ .transition(off, on, null);
+ }
+
/**
* Creates a debounced rotary switch decoder
*
diff --git a/src/main/java/de/neemann/digital/fsm/Movable.java b/src/main/java/de/neemann/digital/fsm/Movable.java
index d853f9b7b..e707747e3 100644
--- a/src/main/java/de/neemann/digital/fsm/Movable.java
+++ b/src/main/java/de/neemann/digital/fsm/Movable.java
@@ -13,6 +13,11 @@ import de.neemann.digital.draw.graphics.VectorFloat;
* @param the type of the implementing class
*/
public class Movable {
+ private static final float MASS = 50f;
+ private static final float FRICTION = 0.8f;
+ private static final float MAX_FORCE = 100000f;
+ private static final float MAX_FORCE_CHECK = (float) (MAX_FORCE / Math.sqrt(2));
+
private String values = "";
private VectorFloat position;
private transient VectorFloat speed;
@@ -25,7 +30,7 @@ public class Movable {
public Movable() {
force = new VectorFloat(0, 0);
speed = new VectorFloat(0, 0);
- position = new VectorFloat((float) Math.random() - 0.5f, (float) Math.random() - 0.5f).mul(100);
+ position = new VectorFloat(0, 0);
}
/**
@@ -129,15 +134,20 @@ public class Movable {
/**
* Moves the element
*
- * @param dt the time step
+ * @param dt the time step in ms
*/
public void move(int dt) {
+ if (Math.abs(force.getXFloat()) > MAX_FORCE_CHECK || Math.abs(force.getYFloat()) > MAX_FORCE_CHECK) {
+ double len = force.len();
+ if (len > MAX_FORCE)
+ force = force.norm().mul(MAX_FORCE);
+ }
if (speed == null)
- speed = force.mul(dt / 200f);
+ speed = force.mul(dt / MASS);
else
- speed = speed.add(force.mul(dt / 200f));
+ speed = speed.add(force.mul(dt / MASS));
setPos(position.add(speed.mul(dt / 1000f)));
- speed = speed.mul(0.7f);
+ speed = speed.mul(FRICTION);
}
void setFSM(FSM fsm) {
diff --git a/src/main/java/de/neemann/digital/fsm/Transition.java b/src/main/java/de/neemann/digital/fsm/Transition.java
index 14a32c715..6fc480b55 100644
--- a/src/main/java/de/neemann/digital/fsm/Transition.java
+++ b/src/main/java/de/neemann/digital/fsm/Transition.java
@@ -93,12 +93,15 @@ public class Transition extends Movable {
public void setPos(VectorFloat position) {
if (fromState != toState) {
VectorFloat dist = fromState.getPos().sub(toState.getPos());
- VectorFloat p = position.sub(fromState.getPos());
- VectorFloat n = dist.getOrthogonal().norm();
- float l = p.mul(n);
- super.setPos(fromState.getPos().sub(dist.mul(0.5f)).add(n.mul(l)));
- } else
- super.setPos(position);
+ if (dist.getXFloat() != 0 || dist.getYFloat() != 0) {
+ VectorFloat p = position.sub(fromState.getPos());
+ VectorFloat n = dist.getOrthogonal().norm();
+ float l = p.mul(n);
+ super.setPos(fromState.getPos().sub(dist.mul(0.5f)).add(n.mul(l)));
+ return;
+ }
+ }
+ super.setPos(position);
}
/**
@@ -152,7 +155,7 @@ public class Transition extends Movable {
*/
void initPos() {
setPos(fromState.getPos().add(toState.getPos()).mul(0.5f)
- .add(new VectorFloat((float) Math.random() - 0.5f, (float) Math.random() - 0.5f).mul(30)));
+ .add(new VectorFloat((float) Math.random() - 0.5f, (float) Math.random() - 0.5f).mul(2)));
}
/**