diff --git a/src/mightypork/gamecore/audio/DeferredAudio.java b/src/mightypork/gamecore/audio/DeferredAudio.java index b78eadc..78e3893 100644 --- a/src/mightypork/gamecore/audio/DeferredAudio.java +++ b/src/mightypork/gamecore/audio/DeferredAudio.java @@ -6,7 +6,7 @@ import java.io.IOException; import mightypork.gamecore.loading.DeferredResource; import mightypork.utils.files.FileUtils; import mightypork.utils.logging.LoggedName; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.coord.Vec; import org.newdawn.slick.openal.Audio; import org.newdawn.slick.openal.SoundStore; @@ -204,7 +204,7 @@ public class DeferredAudio extends DeferredResource { * @param pos coord * @return source id */ - public int playAsEffect(double pitch, double gain, boolean loop, Coord pos) + public int playAsEffect(double pitch, double gain, boolean loop, Vec pos) { if (!ensureLoaded()) return -1; diff --git a/src/mightypork/gamecore/audio/SoundSystem.java b/src/mightypork/gamecore/audio/SoundSystem.java index 94ae6c6..c42c878 100644 --- a/src/mightypork/gamecore/audio/SoundSystem.java +++ b/src/mightypork/gamecore/audio/SoundSystem.java @@ -12,7 +12,10 @@ import mightypork.gamecore.control.bus.clients.RootBusNode; import mightypork.gamecore.control.bus.events.ResourceLoadRequest; import mightypork.gamecore.control.timing.Updateable; import mightypork.utils.math.Calc.Buffers; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.coord.MutableCoord; +import mightypork.utils.math.coord.Vec; +import mightypork.utils.math.coord.VecMutable; +import mightypork.utils.math.coord.VecView; import org.lwjgl.openal.AL; import org.lwjgl.openal.AL10; @@ -26,10 +29,10 @@ import org.newdawn.slick.openal.SoundStore; */ public class SoundSystem extends RootBusNode implements Updateable { - private static final Coord INITIAL_LISTENER_POS = Coord.ZERO; + private static final Vec INITIAL_LISTENER_POS = Vec.ZERO; private static final int MAX_SOURCES = 256; - private static Coord listener = new Coord(); + private static VecMutable listener = new MutableCoord(0,0,0); private static boolean inited; @@ -39,7 +42,7 @@ public class SoundSystem extends RootBusNode implements Updateable { * * @param pos */ - public static void setListener(Coord pos) + public static void setListener(Vec pos) { listener.setTo(pos); FloatBuffer buf3 = Buffers.alloc(3); @@ -60,9 +63,9 @@ public class SoundSystem extends RootBusNode implements Updateable { /** * @return listener coordinate */ - public static Coord getListener() + public static VecView getListener() { - return listener; + return listener.view(); } // -- instance -- diff --git a/src/mightypork/gamecore/audio/players/EffectPlayer.java b/src/mightypork/gamecore/audio/players/EffectPlayer.java index 0c2f4c0..bbe94e5 100644 --- a/src/mightypork/gamecore/audio/players/EffectPlayer.java +++ b/src/mightypork/gamecore/audio/players/EffectPlayer.java @@ -3,7 +3,7 @@ package mightypork.gamecore.audio.players; import mightypork.gamecore.audio.DeferredAudio; import mightypork.gamecore.audio.Volume; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.coord.Vec; /** @@ -59,7 +59,7 @@ public class EffectPlayer extends BaseAudioPlayer { * @param pos play position * @return source id */ - public int play(double pitch, double gain, Coord pos) + public int play(double pitch, double gain, Vec pos) { if (!hasAudio()) return -1; diff --git a/src/mightypork/gamecore/control/bus/events/MouseButtonEvent.java b/src/mightypork/gamecore/control/bus/events/MouseButtonEvent.java index 00c7579..a435991 100644 --- a/src/mightypork/gamecore/control/bus/events/MouseButtonEvent.java +++ b/src/mightypork/gamecore/control/bus/events/MouseButtonEvent.java @@ -1,8 +1,9 @@ package mightypork.gamecore.control.bus.events; -import mightypork.gamecore.gui.constraints.RectConstraint; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.constraints.RectConstraint; +import mightypork.utils.math.coord.Vec; +import mightypork.utils.math.coord.VecView; /** @@ -18,7 +19,7 @@ public class MouseButtonEvent implements Event { private final int button; private final int wheeld; - private final Coord pos; + private final Vec pos; private final boolean down; @@ -30,7 +31,7 @@ public class MouseButtonEvent implements Event { * @param down button pressed * @param wheeld wheel change */ - public MouseButtonEvent(Coord pos, int button, boolean down, int wheeld) { + public MouseButtonEvent(Vec pos, int button, boolean down, int wheeld) { this.button = button; this.down = down; this.pos = pos; @@ -77,9 +78,9 @@ public class MouseButtonEvent implements Event { /** * @return mouse position when the event occurred */ - public Coord getPos() + public VecView getPos() { - return pos; + return pos.view(); } @@ -109,7 +110,7 @@ public class MouseButtonEvent implements Event { */ public boolean isOver(RectConstraint rect) { - return pos.isInRect(rect.getRect()); + return rect.getRect().contains(pos); } diff --git a/src/mightypork/gamecore/control/bus/events/MouseMotionEvent.java b/src/mightypork/gamecore/control/bus/events/MouseMotionEvent.java index a401f45..e69a8ff 100644 --- a/src/mightypork/gamecore/control/bus/events/MouseMotionEvent.java +++ b/src/mightypork/gamecore/control/bus/events/MouseMotionEvent.java @@ -2,7 +2,8 @@ package mightypork.gamecore.control.bus.events; import mightypork.gamecore.control.bus.events.types.UnloggedEvent; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.coord.Vec; +import mightypork.utils.math.coord.VecView; /** @@ -13,15 +14,15 @@ import mightypork.utils.math.coord.Coord; @UnloggedEvent public class MouseMotionEvent implements Event { - private final Coord move; - private final Coord pos; + private final Vec move; + private final Vec pos; /** * @param pos end pos * @param move move vector */ - public MouseMotionEvent(Coord pos, Coord move) { + public MouseMotionEvent(Vec pos, Vec move) { this.move = move; this.pos = pos; } @@ -30,18 +31,18 @@ public class MouseMotionEvent implements Event { /** * @return movement since last {@link MouseMotionEvent} */ - public Coord getMove() + public VecView getMove() { - return move; + return move.view(); } /** * @return current mouse position */ - public Coord getPos() + public VecView getPos() { - return pos; + return pos.view(); } diff --git a/src/mightypork/gamecore/control/bus/events/ScreenChangeEvent.java b/src/mightypork/gamecore/control/bus/events/ScreenChangeEvent.java index c550fce..eb5dbc1 100644 --- a/src/mightypork/gamecore/control/bus/events/ScreenChangeEvent.java +++ b/src/mightypork/gamecore/control/bus/events/ScreenChangeEvent.java @@ -1,7 +1,8 @@ package mightypork.gamecore.control.bus.events; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.coord.Vec; +import mightypork.utils.math.coord.VecView; /** @@ -12,7 +13,7 @@ import mightypork.utils.math.coord.Coord; public class ScreenChangeEvent implements Event { private final boolean fullscreen; - private final Coord screenSize; + private final Vec screenSize; private final boolean fsChanged; @@ -21,7 +22,7 @@ public class ScreenChangeEvent implements Event { * @param fullscreen is now fullscreen * @param size new screen size */ - public ScreenChangeEvent(boolean fsChanged, boolean fullscreen, Coord size) { + public ScreenChangeEvent(boolean fsChanged, boolean fullscreen, Vec size) { this.fullscreen = fullscreen; this.screenSize = size; this.fsChanged = fsChanged; @@ -49,9 +50,9 @@ public class ScreenChangeEvent implements Event { /** * @return new screen size */ - public Coord getScreenSize() + public VecView getScreenSize() { - return screenSize; + return screenSize.view(); } diff --git a/src/mightypork/gamecore/control/timing/Poller.java b/src/mightypork/gamecore/control/timing/Poller.java index 8469363..2a8996b 100644 --- a/src/mightypork/gamecore/control/timing/Poller.java +++ b/src/mightypork/gamecore/control/timing/Poller.java @@ -4,7 +4,7 @@ package mightypork.gamecore.control.timing; import java.util.LinkedHashSet; import java.util.Set; -import mightypork.gamecore.gui.constraints.RectCache; +import mightypork.utils.math.constraints.RectCache; /** diff --git a/src/mightypork/gamecore/gui/components/PluggableRenderable.java b/src/mightypork/gamecore/gui/components/PluggableRenderable.java index 12b42d5..6091ca8 100644 --- a/src/mightypork/gamecore/gui/components/PluggableRenderable.java +++ b/src/mightypork/gamecore/gui/components/PluggableRenderable.java @@ -1,9 +1,9 @@ package mightypork.gamecore.gui.components; -import mightypork.gamecore.gui.constraints.PluggableContext; -import mightypork.gamecore.gui.constraints.RectConstraint; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.constraints.PluggableContext; +import mightypork.utils.math.constraints.RectConstraint; +import mightypork.utils.math.rect.Rect; /** diff --git a/src/mightypork/gamecore/gui/components/PluggableRenderer.java b/src/mightypork/gamecore/gui/components/PluggableRenderer.java index 93ccf36..5298bee 100644 --- a/src/mightypork/gamecore/gui/components/PluggableRenderer.java +++ b/src/mightypork/gamecore/gui/components/PluggableRenderer.java @@ -1,9 +1,9 @@ package mightypork.gamecore.gui.components; -import mightypork.gamecore.gui.constraints.ContextAdapter; -import mightypork.gamecore.gui.constraints.RectConstraint; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.constraints.ContextAdapter; +import mightypork.utils.math.constraints.RectConstraint; +import mightypork.utils.math.rect.Rect; /** diff --git a/src/mightypork/gamecore/gui/components/layout/ColumnHolder.java b/src/mightypork/gamecore/gui/components/layout/ColumnHolder.java index 7933761..b3897df 100644 --- a/src/mightypork/gamecore/gui/components/layout/ColumnHolder.java +++ b/src/mightypork/gamecore/gui/components/layout/ColumnHolder.java @@ -1,10 +1,10 @@ package mightypork.gamecore.gui.components.layout; -import static mightypork.gamecore.gui.constraints.Constraints.*; +import static mightypork.utils.math.constraints.Constraints.*; import mightypork.gamecore.control.AppAccess; import mightypork.gamecore.gui.components.PluggableRenderable; -import mightypork.gamecore.gui.constraints.RectConstraint; +import mightypork.utils.math.constraints.RectConstraint; /** diff --git a/src/mightypork/gamecore/gui/components/layout/ElementHolder.java b/src/mightypork/gamecore/gui/components/layout/ElementHolder.java index 9c73540..c7866fa 100644 --- a/src/mightypork/gamecore/gui/components/layout/ElementHolder.java +++ b/src/mightypork/gamecore/gui/components/layout/ElementHolder.java @@ -9,8 +9,8 @@ import mightypork.gamecore.control.bus.clients.BusNode; import mightypork.gamecore.gui.components.PluggableRenderable; import mightypork.gamecore.gui.components.PluggableRenderer; import mightypork.gamecore.gui.components.Renderable; -import mightypork.gamecore.gui.constraints.RectConstraint; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.constraints.RectConstraint; +import mightypork.utils.math.rect.Rect; /** diff --git a/src/mightypork/gamecore/gui/components/layout/RowHolder.java b/src/mightypork/gamecore/gui/components/layout/RowHolder.java index 3041153..5a548ed 100644 --- a/src/mightypork/gamecore/gui/components/layout/RowHolder.java +++ b/src/mightypork/gamecore/gui/components/layout/RowHolder.java @@ -1,10 +1,10 @@ package mightypork.gamecore.gui.components.layout; -import static mightypork.gamecore.gui.constraints.Constraints.*; +import static mightypork.utils.math.constraints.Constraints.*; import mightypork.gamecore.control.AppAccess; import mightypork.gamecore.gui.components.PluggableRenderable; -import mightypork.gamecore.gui.constraints.RectConstraint; +import mightypork.utils.math.constraints.RectConstraint; /** diff --git a/src/mightypork/gamecore/gui/components/painters/TextPainter.java b/src/mightypork/gamecore/gui/components/painters/TextPainter.java index 26d4c24..e1729dd 100644 --- a/src/mightypork/gamecore/gui/components/painters/TextPainter.java +++ b/src/mightypork/gamecore/gui/components/painters/TextPainter.java @@ -6,8 +6,11 @@ import mightypork.gamecore.render.fonts.FontRenderer; import mightypork.gamecore.render.fonts.FontRenderer.Align; import mightypork.gamecore.render.fonts.GLFont; import mightypork.utils.math.color.RGB; -import mightypork.utils.math.coord.Coord; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.coord.CoordValue; +import mightypork.utils.math.coord.MutableCoord; +import mightypork.utils.math.coord.Vec; +import mightypork.utils.math.coord.VecMutable; +import mightypork.utils.math.rect.Rect; import mightypork.utils.string.StringProvider; import mightypork.utils.string.StringProvider.StringWrapper; @@ -28,7 +31,7 @@ public class TextPainter extends PluggableRenderer { private boolean shadow; private RGB shadowColor = RGB.BLACK; - private Coord shadowOffset = Coord.one(); + private VecMutable shadowOffset = new MutableCoord(1, 1); /** @@ -87,13 +90,13 @@ public class TextPainter extends PluggableRenderer { final Rect rect = getRect(); if (shadow) { - font.draw(str, rect.add(shadowOffset), align, shadowColor); + font.draw(str, rect.move(shadowOffset), align, shadowColor); } font.draw(str, rect, align, color); } - public void setShadow(RGB color, Coord offset) + public void setShadow(RGB color, Vec offset) { setShadow(true); setShadowColor(color); @@ -113,9 +116,9 @@ public class TextPainter extends PluggableRenderer { } - public void setShadowOffset(Coord shadowOffset) + public void setShadowOffset(Vec shadowOffset) { - this.shadowOffset = shadowOffset; + this.shadowOffset.setTo(shadowOffset); } diff --git a/src/mightypork/gamecore/gui/constraints/Constraints.java b/src/mightypork/gamecore/gui/constraints/Constraints.java deleted file mode 100644 index a12f201..0000000 --- a/src/mightypork/gamecore/gui/constraints/Constraints.java +++ /dev/null @@ -1,854 +0,0 @@ -package mightypork.gamecore.gui.constraints; - - -import mightypork.gamecore.control.timing.Poller; -import mightypork.gamecore.input.InputSystem; -import mightypork.gamecore.render.DisplaySystem; -import mightypork.utils.math.coord.Coord; -import mightypork.utils.math.coord.Rect; - - -/** - * Constraint factory.
- * Import statically for best experience. - * - * @author MightyPork - */ -public class Constraints { - - /* ================= Variables ================= */ - - public static final NumberConstraint _mouseX = new NumberConstraint() { - - @Override - public double getValue() - { - return InputSystem.getMousePos().x(); - } - }; - - public static final NumberConstraint _mouseY = new NumberConstraint() { - - @Override - public double getValue() - { - return InputSystem.getMousePos().y(); - } - }; - - public static final NumberConstraint _screenW = new NumberConstraint() { - - @Override - public double getValue() - { - return DisplaySystem.getWidth(); - } - }; - - public static final NumberConstraint _screenH = new NumberConstraint() { - - @Override - public double getValue() - { - return DisplaySystem.getHeight(); - } - }; - - - /* ================= Arithmetics ================= */ - - public static NumberConstraint _min(final Object a, final Object b) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return Math.min(_nv(a), _nv(b)); - } - }; - } - - - public static NumberConstraint _max(final Object a, final Object b) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return Math.max(_nv(a), _nv(b)); - } - }; - } - - - public static NumberConstraint _abs(final NumberConstraint a) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return Math.abs(a.getValue()); - } - }; - } - - - public static NumberConstraint _half(final NumberConstraint a) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return a.getValue() / 2; - } - }; - } - - - public static NumberConstraint _round(final NumberConstraint a) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return Math.round(a.getValue()); - } - }; - } - - - public static RectConstraint _round(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().round(); - } - }; - } - - - public static NumberConstraint _ceil(final NumberConstraint a) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return Math.ceil(a.getValue()); - } - }; - } - - - public static NumberConstraint _floor(final NumberConstraint a) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return Math.floor(a.getValue()); - } - }; - } - - - public static NumberConstraint _neg(final NumberConstraint a) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return -a.getValue(); - } - }; - } - - - public static NumberConstraint _add(final Object a, final Object b) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return _nv(a) + _nv(b); - } - }; - } - - - public static NumberConstraint _sub(final Object a, final Object b) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return _nv(a) - _nv(b); - } - }; - } - - - public static NumberConstraint _mul(final Object a, final Object b) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return _nv(a) * _nv(b); - } - }; - } - - - public static NumberConstraint _div(final Object a, final Object b) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return _nv(a) / _nv(b); - } - }; - } - - - public static NumberConstraint _percent(final Object whole, final Object percent) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return _nv(whole) * (_nv(percent) / 100); - } - }; - } - - - public static NumberConstraint _width(final RectConstraint r) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return r.getRect().getSize().x(); - } - }; - } - - - public static NumberConstraint _height(final RectConstraint r) - { - return new NumberConstraint() { - - @Override - public double getValue() - { - return r.getRect().getSize().y(); - } - }; - } - - - /* ================= Layout utilities ================= */ - - public static RectConstraint _row(final RectConstraint r, final int rows, final int index) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - final double height = r.getRect().getSize().y(); - final double perRow = height / rows; - - final Coord origin = r.getRect().getOrigin().add(0, perRow * index); - final Coord size = r.getRect().getSize().setY(perRow); - - return Rect.fromSize(origin, size); - } - }; - } - - - public static RectConstraint _column(final RectConstraint r, final int columns, final int index) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - final double width = r.getRect().getSize().x(); - final double perCol = width / columns; - - final Coord origin = r.getRect().getOrigin().add(perCol * index, 0); - final Coord size = r.getRect().getSize().setX(perCol); - - return Rect.fromSize(origin, size); - } - }; - } - - - public static RectConstraint _tile(final RectConstraint r, final int rows, final int cols, final int left, final int top) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - final double height = r.getRect().getSize().y(); - final double width = r.getRect().getSize().y(); - final double perRow = height / rows; - final double perCol = width / cols; - - final Coord origin = r.getRect().getOrigin().add(perCol * left, perRow * (rows - top - 1)); - - return Rect.fromSize(origin, perCol, perRow); - } - }; - } - - - /* ================= Rect manipulation ================= */ - - public static RectConstraint _shrink(RectConstraint r, Object shrink) - { - final NumberConstraint n = _n(shrink); - return _shrink(r, n, n, n, n); - } - - - public static RectConstraint _shrink(RectConstraint context, Object horiz, Object vert) - { - return _shrink(context, horiz, vert, horiz, vert); - } - - - public static RectConstraint _shrink(final RectConstraint r, final Object xmin, final Object ymin, final Object xmax, final Object ymax) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().shrink(_nv(xmin), _nv(ymin), _nv(xmax), _nv(ymax)); - } - }; - } - - - public static RectConstraint _shrink_top(final RectConstraint r, final Object shrink) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().shrink(0, _nv(shrink), 0, 0); - } - }; - } - - - public static RectConstraint _shrink_bottom(final RectConstraint r, final Object shrink) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().shrink(0, 0, 0, _nv(shrink)); - } - }; - } - - - public static RectConstraint _shrink_left(final RectConstraint r, final Object shrink) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().shrink(_nv(shrink), 0, 0, 0); - } - }; - } - - - public static RectConstraint _shrink_right(final RectConstraint r, final Object shrink) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().shrink(0, 0, _nv(shrink), 0); - } - }; - } - - - public static RectConstraint _grow(RectConstraint r, Object grow) - { - final NumberConstraint n = _n(grow); - return _grow(r, n, n, n, n); - } - - - public static RectConstraint _grow(RectConstraint r, Object horiz, Object vert) - { - return _grow(r, horiz, vert, horiz, vert); - } - - - public static RectConstraint _grow(final RectConstraint r, final Object xmin, final Object ymin, final Object xmax, final Object ymax) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().grow(_nv(xmin), _nv(ymin), _nv(xmax), _nv(ymax)); - } - }; - } - - - public static RectConstraint _grow_up(final RectConstraint r, final Object grow) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().grow(0, _nv(grow), 0, 0); - } - }; - } - - - public static RectConstraint _grow_down(final RectConstraint r, final Object grow) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().grow(0, 0, 0, _nv(grow)); - } - }; - } - - - public static RectConstraint _grow_left(final RectConstraint r, final Object grow) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().grow(_nv(grow), 0, 0, 0); - } - }; - } - - - public static RectConstraint _grow_right(final RectConstraint r, final Object grow) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().grow(0, 0, _nv(grow), 0); - } - }; - } - - - /* ================= Box creation ================= */ - - public static RectConstraint _box(final Object side) - { - return _box(side, side); - } - - - public static RectConstraint _box(final Object width, final Object height) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - //@formatter:off - return Rect.fromSize( - 0, - 0, - _nv(width), - _nv(height) - ); - //@formatter:on - } - }; - } - - - public static RectConstraint _box(final RectConstraint r, final Object width, final Object height) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - final Coord origin = r.getRect().getOrigin(); - - //@formatter:off - return Rect.fromSize( - origin.x(), - origin.y(), - _nv(width), - _nv(height) - ); - //@formatter:on - } - }; - } - - - public static RectConstraint _box(final RectConstraint r, final Object x, final Object y, final Object width, final Object height) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - final Coord origin = r.getRect().getOrigin(); - - //@formatter:off - return Rect.fromSize( - origin.x() + _nv(x), - origin.y() + _nv(y), - _nv(width), - _nv(height) - ); - //@formatter:on - } - }; - } - - - public static RectConstraint _box_abs(final RectConstraint r, final Object xmin, final Object ymin, final Object xmax, final Object ymax) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - final Coord origin = r.getRect().getOrigin(); - - //@formatter:off - return new Rect(origin.add(_nv(xmin), _nv(ymin)), origin.add(_nv(xmax), _nv(ymax))); - //@formatter:on - } - }; - } - - - public static RectConstraint _centered(final RectConstraint r, final RectConstraint centerTo) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - final Coord size = r.getRect().getSize(); - final Coord center = centerTo.getRect().getCenter(); - - return Rect.fromSize(center.x() - size.x() / 2D, center.y() - size.y() / 2D, size.x(), size.y()); - } - }; - } - - - /** - * Center rect around given coords - * - * @param r rect - * @param x - * @param y - * @return centered - */ - public static RectConstraint _centered(final RectConstraint r, final Object x, final Object y) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - final Coord size = r.getRect().getSize(); - - return Rect.fromSize(_nv(x) - size.x() / 2D, _nv(y) - size.y() / 2D, size.x(), size.y()); - } - }; - } - - - public static RectConstraint _move(final RectConstraint r, final Object x, final Object y) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().add(_nv(x), _nv(y)); - } - }; - } - - - /* ================= Rect bounds ================= */ - - /** - * Get zero-sized rect at the center - * - * @param r context - * @return center - */ - public static RectConstraint _center(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return Rect.fromSize(r.getRect().getCenter(), 0, 0); - } - }; - } - - - public static RectConstraint _left_edge(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().shrink(0, 0, r.getRect().getWidth(), 0); - } - }; - } - - - public static RectConstraint _top_edge(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().shrink(0, 0, 0, r.getRect().getHeight()); - } - }; - } - - - public static RectConstraint _right_edge(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().shrink(r.getRect().getWidth(), 0, 0, 0); - } - }; - } - - - public static RectConstraint _bottom_edge(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return r.getRect().shrink(0, r.getRect().getHeight(), 0, 0); - } - }; - } - - - public static RectConstraint _left_top(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return Rect.fromSize(r.getRect().getHMinVMin(), 0, 0); - } - }; - } - - - public static RectConstraint _left_bottom(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return Rect.fromSize(r.getRect().getHMinVMax(), 0, 0); - } - }; - } - - - public static RectConstraint _right_top(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return Rect.fromSize(r.getRect().getHMaxVMin(), 0, 0); - } - }; - } - - - public static RectConstraint _right_bottom(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return Rect.fromSize(r.getRect().getHMaxVMax(), 0, 0); - } - }; - } - - - public static RectConstraint _center_top(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return Rect.fromSize(r.getRect().getCenterVMin(), 0, 0); - } - }; - } - - - public static RectConstraint _center_bottom(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return Rect.fromSize(r.getRect().getCenterVMax(), 0, 0); - } - }; - } - - - public static RectConstraint _center_left(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return Rect.fromSize(r.getRect().getCenterHMin(), 0, 0); - } - }; - } - - - public static RectConstraint _center_right(final RectConstraint r) - { - return new RectConstraint() { - - @Override - public Rect getRect() - { - return Rect.fromSize(r.getRect().getCenterHMax(), 0, 0); - } - }; - } - - - /* ================= Helpers ================= */ - - public static RectCache _cache(final RectConstraint rc) - { - return new RectCache(rc); - } - - - public static RectCache _cache(final Poller poller, final RectConstraint rc) - { - return new RectCache(poller, rc); - } - - - /** - * Convert {@link Number} to {@link NumberConstraint} if needed - * - * @param o unknown numeric value - * @return converted - */ - public static NumberConstraint _n(final Object o) - { - - if (o instanceof NumberConstraint) return (NumberConstraint) o; - - if (o instanceof Number) return new NumberConstraint() { - - @Override - public double getValue() - { - return ((Number) o).doubleValue(); - } - }; - - throw new IllegalArgumentException("Invalid numeric type."); - } - - - /** - * Convert {@link Number} or {@link NumberConstraint} to double (current - * value) - * - * @param o unknown numeric value - * @return double value - */ - public static double _nv(final Object o) - { - return _n(o).getValue(); - } - -} diff --git a/src/mightypork/gamecore/gui/constraints/NumberConstraint.java b/src/mightypork/gamecore/gui/constraints/NumberConstraint.java deleted file mode 100644 index 1d0d778..0000000 --- a/src/mightypork/gamecore/gui/constraints/NumberConstraint.java +++ /dev/null @@ -1,16 +0,0 @@ -package mightypork.gamecore.gui.constraints; - - -/** - * Numeric constraint - * - * @author MightyPork - */ -public interface NumberConstraint { - - /** - * @return current value - */ - double getValue(); - -} diff --git a/src/mightypork/gamecore/gui/screens/LayeredScreen.java b/src/mightypork/gamecore/gui/screens/LayeredScreen.java index 9b395ff..faacf70 100644 --- a/src/mightypork/gamecore/gui/screens/LayeredScreen.java +++ b/src/mightypork/gamecore/gui/screens/LayeredScreen.java @@ -5,7 +5,7 @@ import java.util.Collection; import java.util.TreeSet; import mightypork.gamecore.control.AppAccess; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.coord.Vec; /** @@ -79,7 +79,7 @@ public abstract class LayeredScreen extends Screen { @Override - protected void onSizeChanged(Coord size) + protected void onSizeChanged(Vec size) { for (final ScreenLayer layer : layers) { layer.onSizeChanged(size); diff --git a/src/mightypork/gamecore/gui/screens/Screen.java b/src/mightypork/gamecore/gui/screens/Screen.java index 87274ee..324a70b 100644 --- a/src/mightypork/gamecore/gui/screens/Screen.java +++ b/src/mightypork/gamecore/gui/screens/Screen.java @@ -6,13 +6,13 @@ import mightypork.gamecore.control.AppSubModule; import mightypork.gamecore.control.bus.events.ScreenChangeEvent; import mightypork.gamecore.control.interf.DefaultImpl; import mightypork.gamecore.gui.components.Renderable; -import mightypork.gamecore.gui.constraints.RectConstraint; import mightypork.gamecore.input.KeyBinder; import mightypork.gamecore.input.KeyBindingPool; import mightypork.gamecore.input.KeyStroke; import mightypork.gamecore.render.Render; -import mightypork.utils.math.coord.Coord; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.constraints.RectConstraint; +import mightypork.utils.math.coord.Vec; +import mightypork.utils.math.rect.Rect; /** @@ -153,7 +153,7 @@ public abstract class Screen extends AppSubModule implements Renderable, KeyBind * @param size screen size */ @DefaultImpl - protected void onSizeChanged(Coord size) + protected void onSizeChanged(Vec size) { // } diff --git a/src/mightypork/gamecore/gui/screens/ScreenLayer.java b/src/mightypork/gamecore/gui/screens/ScreenLayer.java index 5a47c5e..4023283 100644 --- a/src/mightypork/gamecore/gui/screens/ScreenLayer.java +++ b/src/mightypork/gamecore/gui/screens/ScreenLayer.java @@ -1,15 +1,16 @@ package mightypork.gamecore.gui.screens; +import mightypork.gamecore.control.AppAccess; import mightypork.gamecore.control.AppSubModule; import mightypork.gamecore.control.interf.DefaultImpl; import mightypork.gamecore.gui.components.Renderable; -import mightypork.gamecore.gui.constraints.RectConstraint; import mightypork.gamecore.input.KeyBinder; import mightypork.gamecore.input.KeyBindingPool; import mightypork.gamecore.input.KeyStroke; -import mightypork.utils.math.coord.Coord; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.constraints.RectConstraint; +import mightypork.utils.math.coord.Vec; +import mightypork.utils.math.rect.Rect; /** @@ -98,7 +99,7 @@ public abstract class ScreenLayer extends AppSubModule implements Comparable { + private class CoordProperty extends Property { - public CoordProperty(String key, Coord defaultValue, String comment) { + public CoordProperty(String key, Vec defaultValue, String comment) { super(key, defaultValue, comment); } @@ -339,6 +340,30 @@ public class PropertyManager { } + /** + * Get range property + * + * @param n key + * @return the range found, or null + */ + public Range getRange(String n) + { + return Convert.toRange(get(n).value); + } + + + /** + * Get coord property + * + * @param n key + * @return the coord found, or null + */ + public VecView getCoord(String n) + { + return Convert.toCoord(get(n).value); + } + + /** * Add a boolean property * @@ -398,7 +423,7 @@ public class PropertyManager { * @param d default value * @param comment the in-file comment */ - public void putCoord(String n, Coord d, String comment) + public void putCoord(String n, Vec d, String comment) { entries.put(n, new CoordProperty(n, d, comment)); } diff --git a/src/mightypork/utils/files/FileUtils.java b/src/mightypork/utils/files/FileUtils.java index 73d1bda..89116a2 100644 --- a/src/mightypork/utils/files/FileUtils.java +++ b/src/mightypork/utils/files/FileUtils.java @@ -198,7 +198,7 @@ public class FileUtils { final List list = new ArrayList<>(); try { - for (final File f : dir.listFiles(filter)) { + for (File f : dir.listFiles(filter)) { list.add(f); } } catch (final Exception e) { diff --git a/src/mightypork/utils/math/Calc.java b/src/mightypork/utils/math/Calc.java index 62f7d6f..b8199cf 100644 --- a/src/mightypork/utils/math/Calc.java +++ b/src/mightypork/utils/math/Calc.java @@ -7,7 +7,7 @@ import java.util.List; import java.util.Random; import mightypork.utils.math.animation.Easing; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.coord.Vec; import org.lwjgl.BufferUtils; @@ -31,7 +31,7 @@ public class Calc { * @param point point coordinate * @return distance */ - public static double linePointDist(Coord lineDirVec, Coord linePoint, Coord point) + public static double linePointDist(Vec lineDirVec, Vec linePoint, Vec point) { // line point L[lx,ly] final double lx = linePoint.x(); diff --git a/src/mightypork/utils/math/Polar.java b/src/mightypork/utils/math/Polar.java index 2d8d70f..aa4f62a 100644 --- a/src/mightypork/utils/math/Polar.java +++ b/src/mightypork/utils/math/Polar.java @@ -3,7 +3,10 @@ package mightypork.utils.math; import mightypork.utils.math.Calc.Deg; import mightypork.utils.math.Calc.Rad; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.constraints.NumberConstraint; +import mightypork.utils.math.coord.ConstraintCoord; +import mightypork.utils.math.coord.CoordProxy; +import mightypork.utils.math.coord.Vec; /** @@ -19,6 +22,8 @@ public class Polar { /** distance in units */ private double radius = 0; + private ConstraintCoord coord = null; + /** * Create a polar @@ -104,7 +109,7 @@ public class Polar { * @param coord coord * @return polar */ - public static Polar fromCoord(Coord coord) + public static Polar fromCoord(Vec coord) { return Polar.fromCoord(coord.x(), coord.y()); @@ -132,9 +137,28 @@ public class Polar { * * @return coord */ - public Coord toCoord() + public CoordProxy toCoord() { - return new Coord(radius * Math.cos(angle), radius * Math.sin(angle)); + // lazy init + if (coord == null) { + coord = new ConstraintCoord(new NumberConstraint() { + + @Override + public double getValue() + { + return radius * Math.cos(angle); + } + }, new NumberConstraint() { + + @Override + public double getValue() + { + return radius * Math.sin(angle); + } + }); + } + + return coord.view(); } diff --git a/src/mightypork/utils/math/Range.java b/src/mightypork/utils/math/Range.java index 80f1558..860e016 100644 --- a/src/mightypork/utils/math/Range.java +++ b/src/mightypork/utils/math/Range.java @@ -24,6 +24,7 @@ public class Range { } + /** * Create new range * @@ -31,13 +32,9 @@ public class Range { * @param max max number */ public Range(double min, double max) { - if (min > max) { - final double t = min; - min = max; - max = t; - } this.min = min; this.max = max; + norm(); } @@ -51,6 +48,17 @@ public class Range { this.max = minmax; } + /** + * Make sure min is <= max + */ + private void norm() { + if (min > max) { + final double t = min; + min = max; + max = t; + } + } + /** * Get random integer from range @@ -96,28 +104,6 @@ public class Range { } - /** - * Get min - * - * @return min number - */ - public int getMinI() - { - return (int) min; - } - - - /** - * Get max - * - * @return max number - */ - public int getMaxI() - { - return (int) max; - } - - /** * Set min * @@ -126,6 +112,7 @@ public class Range { public void setMin(double min) { this.min = min; + norm(); } @@ -137,13 +124,14 @@ public class Range { public void setMax(double max) { this.max = max; + norm(); } @Override public String toString() { - return "Range(" + min + ";" + max + ")"; + return String.format("( %.2f : %.2f )", min, max); } @@ -168,12 +156,7 @@ public class Range { if (other == null) return; min = other.min; max = other.max; - - if (min > max) { - final double t = min; - min = max; - max = t; - } + norm(); } @@ -184,15 +167,10 @@ public class Range { * @param max max value */ public void setTo(double min, double max) - { - if (min > max) { - final double t = min; - min = max; - max = t; - } - + { this.min = min; this.max = max; + norm(); } } diff --git a/src/mightypork/utils/math/animation/AnimDouble.java b/src/mightypork/utils/math/animation/AnimDouble.java index d5aab6e..de54cc3 100644 --- a/src/mightypork/utils/math/animation/AnimDouble.java +++ b/src/mightypork/utils/math/animation/AnimDouble.java @@ -3,8 +3,8 @@ package mightypork.utils.math.animation; import mightypork.gamecore.control.timing.Pauseable; import mightypork.gamecore.control.timing.Updateable; -import mightypork.gamecore.gui.constraints.NumberConstraint; import mightypork.utils.math.Calc; +import mightypork.utils.math.constraints.NumberConstraint; /** @@ -88,7 +88,7 @@ public class AnimDouble implements Updateable, Pauseable, NumberConstraint { * * @return number */ - public double getFrom() + public double getGetStart() { return from; } @@ -99,7 +99,7 @@ public class AnimDouble implements Updateable, Pauseable, NumberConstraint { * * @return number */ - public double getTo() + public double getEnd() { return to; } @@ -117,6 +117,13 @@ public class AnimDouble implements Updateable, Pauseable, NumberConstraint { } + @Override + public double getValue() + { + return now(); + } + + /** * Get how much of the animation is already finished * @@ -230,16 +237,16 @@ public class AnimDouble implements Updateable, Pauseable, NumberConstraint { /** - * Animate to a value from curretn value + * Animate to a value from current value * * @param to target state - * @param time animation time (secs) + * @param duration animation duration (speeds) */ - public void fadeTo(double to, double time) + public void animate(double to, double duration) { this.from = now(); this.to = to; - this.duration = time; + this.duration = duration; this.elapsedTime = 0; } @@ -271,7 +278,7 @@ public class AnimDouble implements Updateable, Pauseable, NumberConstraint { * * @return copy */ - public Pauseable getCopy() + public AnimDouble copy() { return new AnimDouble(this); } @@ -326,11 +333,4 @@ public class AnimDouble implements Updateable, Pauseable, NumberConstraint { { return paused; } - - - @Override - public double getValue() - { - return now(); - } } diff --git a/src/mightypork/utils/math/constraints/Constraints.java b/src/mightypork/utils/math/constraints/Constraints.java new file mode 100644 index 0000000..8624f2b --- /dev/null +++ b/src/mightypork/utils/math/constraints/Constraints.java @@ -0,0 +1,1383 @@ +package mightypork.utils.math.constraints; + + +import mightypork.gamecore.control.timing.Poller; +import mightypork.gamecore.input.InputSystem; +import mightypork.gamecore.render.DisplaySystem; +import mightypork.utils.math.coord.*; +import mightypork.utils.math.rect.Rect; + + +/** + * Constraint factory.
+ * Import statically for best experience. + * + * @author MightyPork + */ +public class Constraints { + + /* ================= Variables ================= */ + + public static final NumberConstraint _mouseX = new NumberConstraint() { + + @Override + public double getValue() + { + return InputSystem.getMousePos().x(); + } + }; + + public static final NumberConstraint _mouseY = new NumberConstraint() { + + @Override + public double getValue() + { + return InputSystem.getMousePos().y(); + } + }; + public static final NumberConstraint _mousePos = new NumberConstraint() { + + @Override + public double getValue() + { + return InputSystem.getMousePos().y(); + } + }; + + public static final NumberConstraint _screenW = new NumberConstraint() { + + @Override + public double getValue() + { + return DisplaySystem.getWidth(); + } + }; + + public static final NumberConstraint _screenH = new NumberConstraint() { + + @Override + public double getValue() + { + return DisplaySystem.getHeight(); + } + }; + + + /* ================= Arithmetics ================= */ + + public static NumberConstraint _min(final Object a, final Object b) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return Math.min(num(a), num(b)); + } + }; + } + + + public static NumberConstraint _max(final Object a, final Object b) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return Math.max(num(a), num(b)); + } + }; + } + + + public static NumberConstraint _abs(final NumberConstraint a) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return Math.abs(a.getValue()); + } + }; + } + + + public static NumberConstraint _half(final NumberConstraint a) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return a.getValue() / 2; + } + }; + } + + + public static NumberConstraint _round(final NumberConstraint a) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return Math.round(a.getValue()); + } + }; + } + + + public static RectConstraint _round(final RectConstraint r) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).round(); + } + }; + } + + + public static NumberConstraint _ceil(final NumberConstraint a) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return Math.ceil(a.getValue()); + } + }; + } + + + public static NumberConstraint _floor(final NumberConstraint a) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return Math.floor(a.getValue()); + } + }; + } + + + public static NumberConstraint _neg(final NumberConstraint a) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return -a.getValue(); + } + }; + } + + + public static NumberConstraint _add(final Object a, final Object b) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return num(a) + num(b); + } + }; + } + + + public static NumberConstraint _sub(final Object a, final Object b) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return num(a) - num(b); + } + }; + } + + + public static NumberConstraint _mul(final Object a, final Object b) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return num(a) * num(b); + } + }; + } + + + public static NumberConstraint _half(final Object a) + { + return _mul(a, 0.5); + } + + + public static NumberConstraint _div(final Object a, final Object b) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return num(a) / num(b); + } + }; + } + + + public static NumberConstraint _percent(final Object whole, final Object percent) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return num(whole) * (num(percent) / 100); + } + }; + } + + + /* ================= Layout utilities ================= */ + + public static RectConstraint _row(final RectConstraint r, final int rows, final int index) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + final double height = rect(r).getHeight(); + final double perRow = height / rows; + + final Vec origin = rect(r).getOrigin().add(0, perRow * index); + final Vec size = rect(r).getSize().setY(perRow); + + return new Rect(origin, size); + } + }; + } + + + public static RectConstraint _column(final RectConstraint r, final int columns, final int index) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + final double width = rect(r).getWidth(); + final double perCol = width / columns; + + final Vec origin = rect(r).getOrigin().add(perCol * index, 0); + final Vec size = rect(r).getSize().setX(perCol); + + return new Rect(origin, size); + } + }; + } + + + public static RectConstraint _tile(final RectConstraint r, final int rows, final int cols, final int left, final int top) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + final double height = rect(r).getHeight(); + final double width = rect(r).getHeight(); + final double perRow = height / rows; + final double perCol = width / cols; + + final Vec origin = rect(r).getOrigin().add(perCol * left, perRow * (rows - top - 1)); + + return new Rect(origin, perCol, perRow); + } + }; + } + + + /* ================= Rect manipulation ================= */ + + public static RectConstraint _shrink(RectConstraint r, Object shrink) + { + final NumberConstraint n = _n(shrink); + return _shrink(r, n, n, n, n); + } + + + public static RectConstraint _shrink(RectConstraint context, Object horiz, Object vert) + { + return _shrink(context, horiz, vert, horiz, vert); + } + + + public static RectConstraint _shrink(final RectConstraint r, final Object left, final Object top, final Object right, final Object bottom) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).shrink(num(left), num(top), num(right), num(bottom)); + } + }; + } + + + public static RectConstraint _shrink_top(final RectConstraint r, final Object shrink) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).shrink(0, num(shrink), 0, 0); + } + }; + } + + + public static RectConstraint _shrink_bottom(final RectConstraint r, final Object shrink) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).shrink(0, 0, 0, num(shrink)); + } + }; + } + + + public static RectConstraint _shrink_left(final RectConstraint r, final Object shrink) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).shrink(num(shrink), 0, 0, 0); + } + }; + } + + + public static RectConstraint _shrink_right(final RectConstraint r, final Object shrink) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).shrink(0, 0, num(shrink), 0); + } + }; + } + + + public static RectConstraint _grow(RectConstraint r, Object grow) + { + final NumberConstraint n = _n(grow); + return _grow(r, n, n, n, n); + } + + + public static RectConstraint _grow(RectConstraint r, Object horiz, Object vert) + { + return _grow(r, horiz, vert, horiz, vert); + } + + + public static RectConstraint _grow(final RectConstraint r, final Object left, final Object top, final Object right, final Object bottom) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).grow(num(left), num(top), num(right), num(bottom)); + } + }; + } + + + public static RectConstraint _grow_up(final RectConstraint r, final Object grow) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).grow(0, num(grow), 0, 0); + } + }; + } + + + public static RectConstraint _grow_down(final RectConstraint r, final Object grow) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).grow(0, 0, 0, num(grow)); + } + }; + } + + + public static RectConstraint _grow_left(final RectConstraint r, final Object grow) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).grow(num(grow), 0, 0, 0); + } + }; + } + + + public static RectConstraint _grow_right(final RectConstraint r, final Object grow) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).grow(0, 0, num(grow), 0); + } + }; + } + + + /* ================= Box creation ================= */ + + public static RectConstraint _box(final Object side) + { + return _box(side, side); + } + + + public static RectConstraint _box(final VecConstraint origin, final Object width, final Object height) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return new Rect(vec(origin), num(width), num(height)); + } + }; + } + + + public static RectConstraint _box(final Object width, final Object height) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return new Rect(0, 0, num(width), num(height)); + } + }; + } + + + public static RectConstraint _box(final RectConstraint r, final Object width, final Object height) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + final Vec origin = rect(r).getOrigin(); + + return new Rect(origin.x(), origin.y(), num(width), num(height)); + } + }; + } + + + public static RectConstraint _box(final RectConstraint r, final Object x, final Object y, final Object width, final Object height) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + final Vec origin = rect(r).getOrigin(); + + return new Rect(origin.x() + num(x), origin.y() + num(y), num(width), num(height)); + } + }; + } + + + public static RectConstraint _box_abs(final RectConstraint r, final Object left, final Object top, final Object right, final Object bottom) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + final VecView origin = rect(r).getOrigin(); + + return new Rect(origin.add(num(left), num(top)), origin.add(num(right), num(bottom))); + } + }; + } + + + public static RectConstraint _align(final RectConstraint r, final RectConstraint centerTo) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + final VecView size = rect(r).getSize(); + final VecView center = centerTo.getRect().getCenter(); + + return new Rect(center.sub(size.half()), size); + } + }; + } + + + public static RectConstraint _align(final RectConstraint r, final VecConstraint centerTo) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + VecView size = rect(r).getSize(); + + return new Rect(vec(centerTo).sub(size.half()), size); + } + }; + } + + public static RectConstraint _align(final RectConstraint r, final Vec centerTo) + { + return _align(r, new VecWrapper(centerTo)); + } + + + public static RectConstraint _align(final RectConstraint r, final Object x, final Object y) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + final VecView size = rect(r).getSize(); + final VecView v = new CoordValue(num(x), num(y)); + + return new Rect(v.sub(size.half()), size); + } + }; + } + + + public static RectConstraint _move(final RectConstraint r, final VecConstraint move) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + Vec v = move.getVec(); + + return rect(r).move(v); + } + }; + } + + + public static RectConstraint _move(final RectConstraint r, final Object x, final Object y) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).move(num(x), num(y)); + } + }; + } + + + /* ================= Rect bounds ================= */ + + public static RectConstraint _left_edge(final RectConstraint r) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).shrink(0, 0, rect(r).getWidth(), 0); + } + }; + } + + + public static RectConstraint _top_edge(final RectConstraint r) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).shrink(0, 0, 0, rect(r).getHeight()); + } + }; + } + + + public static RectConstraint _right_edge(final RectConstraint r) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).shrink(rect(r).getWidth(), 0, 0, 0); + } + }; + } + + + public static RectConstraint _bottom_edge(final RectConstraint r) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + return rect(r).shrink(0, rect(r).getHeight(), 0, 0); + } + }; + } + + + /* ================= Coords ================= */ + + public static NumberConstraint _x(final VecConstraint c) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return vec(c).x(); + } + }; + } + + + public static NumberConstraint _y(final VecConstraint c) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return vec(c).y(); + } + }; + } + + + public static NumberConstraint _z(final VecConstraint c) + { + return new NumberConstraint() { + + @Override + public double getValue() + { + return vec(c).z(); + } + }; + } + + + public static VecConstraint _neg(final VecConstraint c) + { + return _mul(c, -1); + } + + + public static VecConstraint _half(final VecConstraint c) + { + return _mul(c, 0.5); + } + + + // --- add --- + + public static VecConstraint _add(final VecConstraint c1, final VecConstraint c2) + { + return new VecWrapper(new SynthCoord3D() { + + @Override + public double x() + { + return vec(c1).x() + vec(c2).x(); + } + + + @Override + public double y() + { + return vec(c1).y() + vec(c2).y(); + } + + + @Override + public double z() + { + return vec(c1).z() + vec(c2).z(); + } + + }); + } + + + public static VecConstraint _add(final VecConstraint c, final Object x, final Object y) + { + return _add(c, x, y, 0); + } + + + public static VecConstraint _add(final VecConstraint c, final Object x, final Object y, final Object z) + { + return new VecWrapper(new SynthCoord3D() { + + @Override + public double x() + { + return vec(c).x() + num(x); + } + + + @Override + public double y() + { + return vec(c).y() + num(y); + } + + + @Override + public double z() + { + return vec(c).z() + num(z); + } + + }); + } + + + // --- sub --- + + public static VecConstraint _sub(final VecConstraint c1, final VecConstraint c2) + { + return new VecWrapper(new SynthCoord3D() { + + @Override + public double x() + { + return vec(c1).x() - vec(c2).x(); + } + + + @Override + public double y() + { + return vec(c1).y() - vec(c2).y(); + } + + + @Override + public double z() + { + return vec(c1).z() - vec(c2).z(); + } + + }); + } + + + public static VecConstraint _sub(final VecConstraint c, final Object x, final Object y) + { + return _add(c, x, y, 0); + } + + + public static VecConstraint _sub(final VecConstraint c, final Object x, final Object y, final Object z) + { + return new VecWrapper(new SynthCoord3D() { + + @Override + public double x() + { + return vec(c).x() - num(x); + } + + + @Override + public double y() + { + return vec(c).y() - num(y); + } + + + @Override + public double z() + { + return vec(c).z() - num(z); + } + + }); + } + + + // --- mul --- + + public static VecConstraint _mul(final VecConstraint c, final Object mul) + { + return new VecWrapper(new SynthCoord3D() { + + @Override + public double x() + { + return vec(c).x() * num(mul); + } + + + @Override + public double y() + { + return vec(c).y() * num(mul); + } + + + @Override + public double z() + { + return vec(c).z() * num(mul); + } + + }); + } + + + // --- rects --- + + public static VecConstraint _origin(final RectConstraint r) + { + return new VecConstraint() { + + @Override + public VecView getVec() + { + return rect(r).getOrigin(); + } + }; + } + + + public static VecConstraint _size(final RectConstraint r) + { + return new VecConstraint() { + + @Override + public VecView getVec() + { + return rect(r).getSize(); + } + }; + } + + + public static NumberConstraint _width(final RectConstraint r) + { + return _x(_size(r)); + } + + + public static NumberConstraint _height(final RectConstraint r) + { + return _y(_size(r)); + } + + + public static VecConstraint _center(final RectConstraint r) + { + return _add(_origin(r), _half(_size(r))); + } + + + public static VecConstraint _top_left(final RectConstraint r) + { + return _origin(r); + } + + + public static VecConstraint _top_right(final RectConstraint r) + { + return _add(_origin(r), _width(r), 0); + } + + + public static VecConstraint _bottom_left(final RectConstraint r) + { + return _add(_origin(r), 0, _height(r)); + } + + + public static VecConstraint _bottom_right(final RectConstraint r) + { + return _add(_origin(r), _size(r)); + } + + + public static VecConstraint _center_top(final RectConstraint r) + { + return _add(_origin(r), _half(_width(r)), 0); + } + + + public static VecConstraint _center_bottom(final RectConstraint r) + { + return _add(_origin(r), _half(_width(r)), _height(r)); + } + + + public static VecConstraint _center_left(final RectConstraint r) + { + return _add(_origin(r), 0, _half(_height(r))); + } + + + public static VecConstraint _center_right(final RectConstraint r) + { + return _add(_origin(r), _width(r), _half(_height(r))); + } + + + /** + * Zero-sized rect at given coord + * + * @param c coord + * @return rect + */ + public static RectConstraint _rect(final VecConstraint c) + { + return new RectConstraint() { + + @Override + public Rect getRect() + { + Vec v = vec(c); + + return new Rect(v.x(), v.y(), 0, 0); + } + }; + } + + + /** + * Get proxy for {@link VecConstraint} + * + * @param v vec coord + * @return proxy vec + */ + public static VecView _vec(final VecConstraint v) + { + return new SynthCoord3D() { + + @Override + public double x() + { + return vec(v).x(); + } + + + @Override + public double y() + { + return vec(v).y(); + } + + + @Override + public double z() + { + return vec(v).z(); + } + }; + } + /* ================= Coords ================= */ + + public static NumberConstraint _x(final Vec c) + { + return c.xc(); + } + + + public static NumberConstraint _y(final Vec c) + { + return c.yc(); + } + + + public static NumberConstraint _z(final Vec c) + { + return c.zc(); + } + + + public static VecView _neg(final Vec c) + { + return _mul(c, -1); + } + + + public static VecView _half(final Vec c) + { + return _mul(c, 0.5); + } + + + // --- add --- + + public static VecView _add(final Vec c1, final Vec c2) + { + return new SynthCoord3D() { + + @Override + public double x() + { + return c1.x() + c2.x(); + } + + + @Override + public double y() + { + return c1.y() + c2.y(); + } + + + @Override + public double z() + { + return c1.z() + c2.z(); + } + + }; + } + + + public static VecView _add(final Vec c, final Object x, final Object y) + { + return _add(c, x, y, 0); + } + + + public static VecView _add(final Vec c, final Object x, final Object y, final Object z) + { + return new SynthCoord3D() { + + @Override + public double x() + { + return c.x() + num(x); + } + + + @Override + public double y() + { + return c.y() + num(y); + } + + + @Override + public double z() + { + return c.z() + num(z); + } + + }; + } + + + // --- sub --- + + public static VecView _sub(final Vec c1, final Vec c2) + { + return new SynthCoord3D() { + + @Override + public double x() + { + return c1.x() - c2.x(); + } + + + @Override + public double y() + { + return c1.y() - c2.y(); + } + + + @Override + public double z() + { + return c1.z() - c2.z(); + } + + }; + } + + + public static VecView _sub(final Vec c, final Object x, final Object y) + { + return _add(c, x, y, 0); + } + + + public static VecView _sub(final Vec c, final Object x, final Object y, final Object z) + { + return new SynthCoord3D() { + + @Override + public double x() + { + return c.x() - num(x); + } + + + @Override + public double y() + { + return c.y() - num(y); + } + + + @Override + public double z() + { + return c.z() - num(z); + } + + }; + } + + + // --- mul --- + + public static VecView _mul(final Vec c, final Object mul) + { + return new SynthCoord3D() { + + @Override + public double x() + { + return c.x() * num(mul); + } + + + @Override + public double y() + { + return c.y() * num(mul); + } + + + @Override + public double z() + { + return c.z() * num(mul); + } + + }; + } + + public static VecView _origin(final Rect r) + { + return r.getOrigin().view(); + } + + + public static VecView _size(final Rect r) + { + return r.getSize().view(); + } + + + public static NumberConstraint _width(final Rect r) + { + return _x(_size(r)); + } + + + public static NumberConstraint _height(final Rect r) + { + return _y(_size(r)); + } + + + public static VecView _center(final Rect r) + { + return _add(_origin(r), _half(_size(r))); + } + + + public static VecView _top_left(final Rect r) + { + return _origin(r); + } + + + public static VecView _top_right(final Rect r) + { + return _add(_origin(r), _width(r), 0); + } + + + public static VecView _bottom_left(final Rect r) + { + return _add(_origin(r), 0, _height(r)); + } + + + public static VecView _bottom_right(final Rect r) + { + return _add(_origin(r), _size(r)); + } + + + public static VecView _center_top(final Rect r) + { + return _add(_origin(r), _half(_width(r)), 0); + } + + + public static VecView _center_bottom(final Rect r) + { + return _add(_origin(r), _half(_width(r)), _height(r)); + } + + + public static VecView _center_left(final Rect r) + { + return _add(_origin(r), 0, _half(_height(r))); + } + + + public static VecView _center_right(final Rect r) + { + return _add(_origin(r), _width(r), _half(_height(r))); + } + + /* ================= Helpers ================= */ + + public static RectCache _cache(final RectConstraint rc) + { + return new RectCache(rc); + } + + + public static RectCache _cache(final Poller poller, final RectConstraint rc) + { + return new RectCache(poller, rc); + } + + + /** + * Convert {@link Number} to {@link NumberConstraint} if needed + * + * @param o unknown numeric value + * @return converted + */ + public static NumberConstraint _n(final Object o) + { + if (o instanceof NumberConstraint) return (NumberConstraint) o; + + if (o instanceof Number) return new NumberConstraint() { + + @Override + public double getValue() + { + return ((Number) o).doubleValue(); + } + }; + + throw new IllegalArgumentException("Invalid numeric type."); + } + + + /** + * Convert {@link Number} or {@link NumberConstraint} to double (current + * value) + * + * @param o unknown numeric value + * @return double value + */ + private static double num(final Object o) + { + return _n(o).getValue(); + } + + + /** + * Convert {@link VecConstraint} to {@link VecArith}. + * + * @param o unknown numeric value + * @return double value + */ + private static VecView vec(final VecConstraint o) + { + return o.getVec(); + } + + + /** + * Convert {@link RectConstraint} to {@link Rect}. + * + * @param o unknown numeric value + * @return double value + */ + private static Rect rect(final RectConstraint o) + { + return o.getRect(); + } + +} diff --git a/src/mightypork/gamecore/gui/constraints/ContextAdapter.java b/src/mightypork/utils/math/constraints/ContextAdapter.java similarity index 80% rename from src/mightypork/gamecore/gui/constraints/ContextAdapter.java rename to src/mightypork/utils/math/constraints/ContextAdapter.java index 87f005c..bae71e8 100644 --- a/src/mightypork/gamecore/gui/constraints/ContextAdapter.java +++ b/src/mightypork/utils/math/constraints/ContextAdapter.java @@ -1,7 +1,7 @@ -package mightypork.gamecore.gui.constraints; +package mightypork.utils.math.constraints; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.rect.Rect; /** diff --git a/src/mightypork/utils/math/constraints/NumberConstraint.java b/src/mightypork/utils/math/constraints/NumberConstraint.java new file mode 100644 index 0000000..137e564 --- /dev/null +++ b/src/mightypork/utils/math/constraints/NumberConstraint.java @@ -0,0 +1,34 @@ +package mightypork.utils.math.constraints; + + +/** + * Numeric constraint + * + * @author MightyPork + */ +public interface NumberConstraint { + + public static final NumberConstraint ZERO = new NumberConstraint() { + + @Override + public double getValue() + { + return 0; + } + }; + + public static final NumberConstraint ONE = new NumberConstraint() { + + @Override + public double getValue() + { + return 0; + } + }; + + /** + * @return current value + */ + double getValue(); + +} diff --git a/src/mightypork/gamecore/gui/constraints/PluggableContext.java b/src/mightypork/utils/math/constraints/PluggableContext.java similarity index 77% rename from src/mightypork/gamecore/gui/constraints/PluggableContext.java rename to src/mightypork/utils/math/constraints/PluggableContext.java index 72af20b..869b5ad 100644 --- a/src/mightypork/gamecore/gui/constraints/PluggableContext.java +++ b/src/mightypork/utils/math/constraints/PluggableContext.java @@ -1,7 +1,7 @@ -package mightypork.gamecore.gui.constraints; +package mightypork.utils.math.constraints; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.rect.Rect; /** diff --git a/src/mightypork/gamecore/gui/constraints/RectCache.java b/src/mightypork/utils/math/constraints/RectCache.java similarity index 91% rename from src/mightypork/gamecore/gui/constraints/RectCache.java rename to src/mightypork/utils/math/constraints/RectCache.java index 4015aa9..51feefb 100644 --- a/src/mightypork/gamecore/gui/constraints/RectCache.java +++ b/src/mightypork/utils/math/constraints/RectCache.java @@ -1,9 +1,9 @@ -package mightypork.gamecore.gui.constraints; +package mightypork.utils.math.constraints; import mightypork.gamecore.control.timing.Pollable; import mightypork.gamecore.control.timing.Poller; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.rect.Rect; /** diff --git a/src/mightypork/gamecore/gui/constraints/RectConstraint.java b/src/mightypork/utils/math/constraints/RectConstraint.java similarity index 64% rename from src/mightypork/gamecore/gui/constraints/RectConstraint.java rename to src/mightypork/utils/math/constraints/RectConstraint.java index 5b311b1..961082a 100644 --- a/src/mightypork/gamecore/gui/constraints/RectConstraint.java +++ b/src/mightypork/utils/math/constraints/RectConstraint.java @@ -1,7 +1,7 @@ -package mightypork.gamecore.gui.constraints; +package mightypork.utils.math.constraints; -import mightypork.utils.math.coord.Rect; +import mightypork.utils.math.rect.Rect; /** diff --git a/src/mightypork/utils/math/constraints/VecConstraint.java b/src/mightypork/utils/math/constraints/VecConstraint.java new file mode 100644 index 0000000..3113e4e --- /dev/null +++ b/src/mightypork/utils/math/constraints/VecConstraint.java @@ -0,0 +1,8 @@ +package mightypork.utils.math.constraints; + +import mightypork.utils.math.coord.VecView; + + +public interface VecConstraint { + VecView getVec(); +} diff --git a/src/mightypork/utils/math/constraints/VecWrapper.java b/src/mightypork/utils/math/constraints/VecWrapper.java new file mode 100644 index 0000000..aa43635 --- /dev/null +++ b/src/mightypork/utils/math/constraints/VecWrapper.java @@ -0,0 +1,23 @@ +package mightypork.utils.math.constraints; + + +import mightypork.utils.math.coord.Vec; +import mightypork.utils.math.coord.VecView; + + +public class VecWrapper implements VecConstraint { + + private final Vec wrapped; + + + public VecWrapper(Vec wrapped) { + this.wrapped = wrapped; + } + + + @Override + public VecView getVec() + { + return wrapped.view(); + } +} diff --git a/src/mightypork/utils/math/coord/AnimCoord.java b/src/mightypork/utils/math/coord/AnimCoord.java new file mode 100644 index 0000000..683191a --- /dev/null +++ b/src/mightypork/utils/math/coord/AnimCoord.java @@ -0,0 +1,129 @@ +package mightypork.utils.math.coord; + + +import mightypork.gamecore.control.timing.Pauseable; +import mightypork.gamecore.control.timing.Updateable; +import mightypork.utils.math.animation.AnimDouble; +import mightypork.utils.math.animation.Easing; + + +/** + * 3D coordinated with support for transitions, mutable. + * + * @author MightyPork + */ +public class AnimCoord extends VecMutableImpl implements Pauseable, Updateable { + + private final AnimDouble x, y, z; + + + public AnimCoord(AnimDouble x, AnimDouble y, AnimDouble z) { + this.x = x; + this.y = y; + this.z = z; + } + + + public AnimCoord(Vec start, Easing easing) { + x = new AnimDouble(start.x(), easing); + y = new AnimDouble(start.y(), easing); + z = new AnimDouble(start.z(), easing); + } + + + @Override + public double x() + { + return x.now(); + } + + + @Override + public double y() + { + return y.now(); + } + + + @Override + public double z() + { + return z.now(); + } + + + @Override + public AnimCoord result(double x, double y, double z) + { + this.x.setTo(x); + this.y.setTo(y); + this.z.setTo(z); + + return this; + } + + + public AnimCoord add(VecArith offset, double speed) + { + animate(offset.add(this), speed); + return this; + } + + + public AnimCoord animate(Vec target, double duration) + { + x.animate(target.x(), duration); + y.animate(target.y(), duration); + z.animate(target.z(), duration); + return this; + } + + + public void animateWithSpeed(Vec target, double unitsPerSecond) + { + double dist = distTo(target); + double duration = dist / unitsPerSecond; + animate(target, duration); + } + + + @Override + public void update(double delta) + { + x.update(delta); + y.update(delta); + z.update(delta); + } + + + @Override + public void pause() + { + x.pause(); + y.pause(); + z.pause(); + } + + + @Override + public void resume() + { + x.resume(); + y.resume(); + z.resume(); + } + + + @Override + public boolean isPaused() + { + return x.isPaused(); // BUNO + } + + + public boolean isFinished() + { + return x.isFinished(); // BUNO + } + +} diff --git a/src/mightypork/utils/math/coord/ConstraintCoord.java b/src/mightypork/utils/math/coord/ConstraintCoord.java new file mode 100644 index 0000000..7624be0 --- /dev/null +++ b/src/mightypork/utils/math/coord/ConstraintCoord.java @@ -0,0 +1,55 @@ +package mightypork.utils.math.coord; + + +import mightypork.utils.math.constraints.NumberConstraint; + + +/** + * Coord view composed of given {@link NumberConstraint}s, using their current + * values.
+ * Operations yield a new {@link MutableCoord} with the result. + * + * @author MightyPork + */ +public class ConstraintCoord extends VecView { + + private final NumberConstraint constrX; + private final NumberConstraint constrY; + private final NumberConstraint constrZ; + + + public ConstraintCoord(NumberConstraint x, NumberConstraint y, NumberConstraint z) { + this.constrX = x; + this.constrY = y; + this.constrZ = z; + } + + + public ConstraintCoord(NumberConstraint x, NumberConstraint y) { + this.constrX = x; + this.constrY = y; + this.constrZ = NumberConstraint.ZERO; + } + + + @Override + public double x() + { + return constrX.getValue(); + } + + + @Override + public double y() + { + return constrY.getValue(); + } + + + @Override + public double z() + { + return constrZ.getValue(); + } + +} diff --git a/src/mightypork/utils/math/coord/ConstraintCoordView.java b/src/mightypork/utils/math/coord/ConstraintCoordView.java deleted file mode 100644 index 75394c6..0000000 --- a/src/mightypork/utils/math/coord/ConstraintCoordView.java +++ /dev/null @@ -1,42 +0,0 @@ -package mightypork.utils.math.coord; - - -import mightypork.gamecore.gui.constraints.NumberConstraint; - - -public class ConstraintCoordView extends CoordView { - - private final NumberConstraint xc; - private final NumberConstraint yc; - private final NumberConstraint zc; - - - public ConstraintCoordView(NumberConstraint x, NumberConstraint y, NumberConstraint z) { - super(null); - this.xc = x; - this.yc = y; - this.zc = z; - } - - - @Override - public double x() - { - return xc == null ? 0 : xc.getValue(); - } - - - @Override - public double y() - { - return yc == null ? 0 : yc.getValue(); - } - - - @Override - public double z() - { - return zc == null ? 0 : zc.getValue(); - } - -} diff --git a/src/mightypork/utils/math/coord/Coord.java b/src/mightypork/utils/math/coord/Coord.java deleted file mode 100644 index bc06c29..0000000 --- a/src/mightypork/utils/math/coord/Coord.java +++ /dev/null @@ -1,1135 +0,0 @@ -package mightypork.utils.math.coord; - - -import java.util.Random; - -import mightypork.gamecore.gui.constraints.NumberConstraint; -import mightypork.gamecore.gui.constraints.RectConstraint; -import mightypork.utils.math.Calc; - - -/** - * Coordinate in 3D space, or a vector of three {@link Double}s
- * - * @author MightyPork - */ -public class Coord implements CoordValue { - - protected static Random rand = new Random(); - - public static final Coord ONE = new Coord(1).freeze(); - public static final Coord ZERO = new Coord(0).freeze(); - - - /** - * Get distance to other point - * - * @param a point a - * @param b point b - * @return distance in units - */ - public static double dist(Coord a, Coord b) - { - return a.distTo(b); - } - - /** X coordinate */ - private double x = 0; - - /** Y coordinate */ - private double y = 0; - - /** Z coordinate */ - private double z = 0; - - private Coord view = null; - - private boolean frozen = false; - - private NumberConstraint xc, yc, zc; - - - public static Coord at(double x, double y) - { - return new Coord(x, y); - } - - - public static Coord at(double x, double y, double z) - { - return new Coord(x, y, z); - } - - - /** - * Create zero coord - */ - public Coord() { - } - - - /** - * Create coord as a copy of another - * - * @param copied copied coord - */ - public Coord(Coord copied) { - setTo(copied); - } - - - /** - * Create a coord with all three coordinates the same - * - * @param d coord value - */ - public Coord(double d) { - setTo(d, d, d); - } - - - /** - * Create 2D coord - * - * @param x x coordinate - * @param y y coordinate - */ - public Coord(double x, double y) { - setTo(x, y); - } - - - /** - * Create 3D coord - * - * @param x x coordinate - * @param y y coordinate - * @param z z coordinate - */ - public Coord(double x, double y, double z) { - setTo(x, y, z); - } - - - /** - * Freeze current coordinate values. - * - * @return this - */ - public Coord freeze() - { - frozen = true; - return this; - } - - - /** - * Get view at this coord - * - * @return the view - */ - public Coord view() - { - // cache last used view - if (view == null) view = new CoordView(this); - - return view; - } - - - /** - * @return true if this coord is writable - */ - public boolean isWritable() - { - return !frozen && !isView(); - } - - - /** - * @return true if this coord is a view at another - */ - public boolean isView() - { - return false; - } - - - protected void assertWritable() - { - if (!isWritable()) { - throw new UnsupportedOperationException("This Coord is not writable."); - } - } - - - /** - * Add a vector, in a copy - * - * @param vec offset - * @return changed copy - */ - public Coord add(Coord vec) - { - return copy().add_ip(vec); - } - - - /** - * Add a vector, in place - * - * @param vec offset - * @return this - */ - public Coord add_ip(Coord vec) - { - return add_ip(vec.x(), vec.y(), vec.z()); - } - - - /** - * Add to each component, in a copy.
- * Z is unchanged. - * - * @param x x offset - * @param y y offset - * @return changed copy - */ - public Coord add(double x, double y) - { - return copy().add_ip(x, y); - } - - - /** - * Add to each component, in place.
- * Z is unchanged. - * - * @param x x offset - * @param y y offset - * @return this - */ - public Coord add_ip(double x, double y) - { - return add_ip(x, y, 0); - } - - - /** - * Add to each component, in a copy. - * - * @param x x offset - * @param y y offset - * @param z z offset - * @return changed copy - */ - public Coord add(double x, double y, double z) - { - return copy().add_ip(x, y, z); - } - - - /** - * Add to each component, in place. - * - * @param x x offset - * @param y y offset - * @param z z offset - * @return this - */ - public Coord add_ip(double x, double y, double z) - { - assertWritable(); - this.x += x; - this.y += y; - this.z += z; - return this; - } - - - /** - * Make a copy - * - * @return a copy - */ - public Coord copy() - { - return new Coord(this); - } - - - /** - * Get distance to other point - * - * @param point other point - * @return distance in units - */ - public double distTo(Coord point) - { - final double dx = (point.x() - this.x()); - final double dy = (point.y() - this.y()); - final double dz = (point.z() - this.z()); - - return Math.sqrt(dx * dx + dy * dy + dz * dz); - } - - - /** - * Check if this rectangle in inside a rectangular zone - * - * @param rect checked rect. - * @return is inside - */ - public boolean isInRect(RectConstraint rect) - { - final Rect r = rect.getRect(); - return isInRect(r.getMin(), r.getMax()); - } - - - /** - * Check if this rectangle in inside a rectangular zone - * - * @param min min coord - * @param max max coord - * @return is inside - */ - public boolean isInRect(Coord min, Coord max) - { - if (!Calc.inRange(x(), min.x(), max.x())) return false; - if (!Calc.inRange(y(), min.y(), max.y())) return false; - if (!Calc.inRange(z(), min.z(), max.z())) return false; - - return true; - } - - - /** - * Get middle of line to other point - * - * @param other other point - * @return middle - */ - public Coord midTo(Coord other) - { - return add(vecTo(other).half_ip()); - } - - - /** - * Get copy divided by two - * - * @return copy halved - */ - public Coord half() - { - return copy().half_ip(); - } - - - /** - * Divide in place by two - * - * @return this - */ - public Coord half_ip() - { - mul_ip(0.5); - return this; - } - - - /** - * Multiply each component, in a copy. - * - * @param d multiplier - * @return changed copy - */ - public Coord mul(double d) - { - return copy().mul_ip(d); - } - - - /** - * Multiply each component, in a copy. - * - * @param vec vector of multipliers - * @return changed copy - */ - public Coord mul(Coord vec) - { - return copy().mul_ip(vec); - } - - - /** - * Multiply each component, in a copy.
- * Z is unchanged. - * - * @param x x multiplier - * @param y y multiplier - * @return changed copy - */ - public Coord mul(double x, double y) - { - return copy().mul_ip(x, y); - } - - - /** - * Multiply each component, in place. - * - * @param d multiplier - * @return this - */ - public Coord mul_ip(double d) - { - return mul_ip(d, d, d); - } - - - /** - * Multiply each component, in a copy. - * - * @param x x multiplier - * @param y y multiplier - * @param z z multiplier - * @return changed copy - */ - public Coord mul(double x, double y, double z) - { - return copy().mul_ip(x, y, z); - } - - - /** - * Multiply each component, in place.
- * Z is unchanged. - * - * @param x x multiplier - * @param y y multiplier - * @return this - */ - public Coord mul_ip(double x, double y) - { - return mul_ip(x, y, 1); - } - - - /** - * Multiply each component, in place. - * - * @param vec vector of multipliers - * @return this - */ - public Coord mul_ip(Coord vec) - { - return mul_ip(vec.x(), vec.y(), vec.z()); - } - - - /** - * Multiply each component, in place. - * - * @param x x multiplier - * @param y y multiplier - * @param z z multiplier - * @return this - */ - public Coord mul_ip(double x, double y, double z) - { - assertWritable(); - this.x *= x; - this.y *= y; - this.z *= z; - return this; - } - - - public Coord random_offset(double max) - { - return copy().random_offset_ip(max); - } - - - /** - * offset randomly - * - * @param min min offset - * @param max max offset - * @return offset coord - */ - public Coord random_offset(double min, double max) - { - return copy().random_offset_ip(min, max); - } - - - /** - * offset randomly in place - * - * @param max max +- offset - * @return this - */ - public Coord random_offset_ip(double max) - { - return add_ip(random(1).norm_ip(rand.nextDouble() * max)); - } - - - /** - * offset randomly in place - * - * @param min min offset - * @param max max offset - * @return this - */ - public Coord random_offset_ip(double min, double max) - { - add_ip(random(min, max)); - return this; - } - - - /** - * Get a copy with rounded coords - * - * @return rounded copy - */ - public Coord round() - { - return copy().round_ip(); - } - - - /** - * Round in place - * - * @return this - */ - public Coord round_ip() - { - assertWritable(); - x = Math.round(x); - y = Math.round(y); - z = Math.round(z); - return this; - } - - - /** - * Set to max values of this and other coord - * - * @param other other coord - */ - public void setToMax(Coord other) - { - assertWritable(); - x = Math.max(x, other.x()); - y = Math.max(y, other.y()); - z = Math.max(z, other.z()); - } - - - /** - * Set to min values of this and other coord - * - * @param other other coord - */ - public void setToMin(Coord other) - { - assertWritable(); - x = Math.min(x, other.x()); - y = Math.min(y, other.y()); - z = Math.min(z, other.z()); - } - - - /** - * Set coordinates to match other coord - * - * @param copied coord whose coordinates are used - * @return this - */ - public Coord setTo(Coord copied) - { - return setTo(copied.x(), copied.y(), copied.z()); - } - - - /** - * Set 2D coordinates to - * - * @param x x coordinate - * @param y y coordinate - * @return this - */ - public Coord setTo(double x, double y) - { - return setTo(x, y, 0); - } - - - /** - * Set 3D coordinates to - * - * @param x x coordinate - * @param y y coordinate - * @param z z coordinate - * @return this - */ - public Coord setTo(double x, double y, double z) - { - assertWritable(); - this.x = x; - this.y = y; - this.z = z; - return this; - } - - - /** - * Set X coordinate in a copy - * - * @param x x coordinate - * @return copy with set coordinate - */ - public Coord setX(double x) - { - return copy().setX_ip(x); - } - - - /** - * Set Y coordinate in a copy - * - * @param y y coordinate - * @return copy with set coordinate - */ - public Coord setY(double y) - { - return copy().setY_ip(y); - } - - - /** - * Set Z coordinate in a copy - * - * @param z z coordinate - * @return copy with set coordinate - */ - public Coord setZ(double z) - { - return copy().setZ_ip(z); - } - - - /** - * Set X coordinate in place - * - * @param x x coordinate - * @return this - */ - public Coord setX_ip(double x) - { - assertWritable(); - this.x = x; - return this; - } - - - /** - * Set Y coordinate in place - * - * @param y y coordinate - * @return this - */ - public Coord setY_ip(double y) - { - assertWritable(); - this.y = y; - return this; - } - - - /** - * Set Z coordinate in place - * - * @param z z coordinate - * @return this - */ - public Coord setZ_ip(double z) - { - assertWritable(); - this.z = z; - return this; - } - - - /** - * Get a copy subtracted by vector - * - * @param vec offset - * @return the offset copy - */ - public Coord sub(Coord vec) - { - return copy().sub_ip(vec); - } - - - /** - * Get a copy subtracted by 2D coordinate - * - * @param x x offset - * @param y y offset - * @return the offset copy - */ - public Coord sub(double x, double y) - { - return copy().sub_ip(x, y); - } - - - /** - * Get a copy subtracted by 3D coordinate - * - * @param x x offset - * @param y y offset - * @param z z offset - * @return the offset copy - */ - public Coord sub(double x, double y, double z) - { - return copy().sub_ip(x, y, z); - } - - - /** - * Offset by vector in place - * - * @param vec offset - * @return this - */ - public Coord sub_ip(Coord vec) - { - return sub_ip(vec.x(), vec.y(), vec.z()); - } - - - /** - * Offset by 2D coordinate in place - * - * @param x x offset - * @param y y offset - * @return this - */ - public Coord sub_ip(double x, double y) - { - return sub_ip(x, y, 0); - } - - - /** - * Offset by 3D coordinate in place - * - * @param x x offset - * @param y y offset - * @param z z offset - * @return this - */ - public Coord sub_ip(double x, double y, double z) - { - assertWritable(); - this.x -= x; - this.y -= y; - this.z -= z; - return this; - } - - - /** - * Create vector from this point to other point - * - * @param point second point - * @return vector - */ - public Coord vecTo(Coord point) - { - return point.sub(this); - } - - - /** - * @return X as double - */ - @Override - public double x() - { - return x; - } - - - /** - * @return Y as double - */ - @Override - public double y() - { - return y; - } - - - /** - * @return Z as double - */ - @Override - public double z() - { - return z; - } - - - /** - * @return X as constraint view - */ - @Override - public final NumberConstraint xc() - { - return xc != null ? xc : new NumberConstraint() { - - @Override - public double getValue() - { - return x(); - } - }; - } - - - /** - * @return Y as constraint view - */ - @Override - public final NumberConstraint yc() - { - return yc != null ? yc : new NumberConstraint() { - - @Override - public double getValue() - { - return y(); - } - }; - } - - - /** - * @return Z as constraint view - */ - @Override - public final NumberConstraint zc() - { - return zc != null ? zc : new NumberConstraint() { - - @Override - public double getValue() - { - return z(); - } - }; - } - - - /** - * @return X as float - */ - public final float xf() - { - return (float) x(); - } - - - /** - * @return Y as float - */ - public final float yf() - { - return (float) y(); - } - - - /** - * @return Z as float - */ - public final float zf() - { - return (float) z(); - } - - - /** - * @return X as int - */ - public final int xi() - { - return (int) Math.round(x()); - } - - - /** - * @return Y as int - */ - public final int yi() - { - return (int) Math.round(y()); - } - - - /** - * @return Z as int - */ - public final int zi() - { - return (int) Math.round(z()); - } - - - /** - * Get cross product of two vectors - * - * @param a 1st vector - * @param b 2nd vector - * @return cross product - */ - public static Coord cross(Coord a, Coord b) - { - return a.cross(b); - } - - - /** - * Get dot product of two vectors - * - * @param a 1st vector - * @param b 2nd vector - * @return dot product - */ - public static double dot(Coord a, Coord b) - { - return a.dot(b); - } - - - /** - * Multiply by other vector, vector multiplication - * - * @param vec other vector - * @return changed copy - */ - public Coord cross(Coord vec) - { - return copy().cross_ip(vec); - } - - - /** - * Multiply by other vector, vector multiplication; in place - * - * @param vec other vector - * @return this - */ - public Coord cross_ip(Coord vec) - { - //@formatter:off - setTo( - y * vec.z() - z * vec.y(), - z * vec.x() - x * vec.z(), - x * vec.y() - y * vec.x() - ); - //@formatter:on - return this; - } - - - /** - * Get dot product - * - * @param vec other vector - * @return dot product - */ - public double dot(Coord vec) - { - return x() * vec.x() + y() * vec.y() + z() * vec.z(); - } - - - /** - * Negate all coordinates (* -1) - * - * @return negated copy - */ - public Coord neg() - { - return copy().neg_ip(); - } - - - /** - * Negate all coordinates (* -1), in place - * - * @return this - */ - public Coord neg_ip() - { - mul_ip(-1); - return this; - } - - - /** - * Scale vector to given size - * - * @param size size we need - * @return scaled vector - */ - public Coord norm(double size) - { - return copy().norm_ip(size); - } - - - /** - * Scale vector to given size, in place.
- * Zero vector remains zero. - * - * @param size size we need - * @return scaled vector - */ - public Coord norm_ip(double size) - { - if (isZero()) return this; - - final double k = size / size(); - return mul_ip(k); - } - - - /** - * Get vector size - * - * @return size in units - */ - public double size() - { - if (isZero()) return 0; - - return Math.sqrt(x() * x() + y() * y() + z() * z()); - } - - - /** - * @return true if this coord is a zero coord - */ - public boolean isZero() - { - return x() == 0 && y() == 0 && z() == 0; - } - - - @Override - public String toString() - { - return String.format("( %.2f, %.2f, %.2f )", x(), y(), z()); - } - - - @Override - public int hashCode() - { - final int prime = 31; - int result = 1; - long temp; - temp = Double.doubleToLongBits(x()); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(y()); - result = prime * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(z()); - result = prime * result + (int) (temp ^ (temp >>> 32)); - return result; - } - - - @Override - public boolean equals(Object obj) - { - if (this == obj) return true; - if (obj == null) return false; - if (!(obj instanceof Coord)) return false; - final Coord other = (Coord) obj; - if (Double.doubleToLongBits(x()) != Double.doubleToLongBits(other.x())) return false; - if (Double.doubleToLongBits(y()) != Double.doubleToLongBits(other.y())) return false; - if (Double.doubleToLongBits(z()) != Double.doubleToLongBits(other.z())) return false; - return true; - } - - - /** - * Generate a zero coordinate - * - * @return coord of all zeros - */ - public static Coord zero() - { - return ZERO.copy(); - } - - - /** - * Generate a unit coordinate - * - * @return coord of all ones - */ - public static Coord one() - { - return ONE.copy(); - } - - - /** - * Generate random coord (gaussian) - * - * @param max max distance from 0 - * @return new coord - */ - public static Coord random(double max) - { - //@formatter:off - return new Coord( - Calc.clampd(rand.nextGaussian() * max, -max * 2, max * 2), - Calc.clampd(rand.nextGaussian() * max, -max * 2, max * 2), - Calc.clampd(rand.nextGaussian() * max, -max * 2, max * 2) - ); - //@formatter:on - } - - - /** - * Generate random coord (min-max) - * - * @param min min offset - * @param max max offset - * @return new coord - */ - public static Coord random(double min, double max) - { - //@formatter:off - return new Coord( - (rand.nextBoolean() ? -1 : 1) * (min + rand.nextDouble() * (max - min)), - (rand.nextBoolean() ? -1 : 1) * (min + rand.nextDouble() * (max - min)), - (rand.nextBoolean() ? -1 : 1) * (min + rand.nextDouble() * (max - min)) - ); - //@formatter:on - } -} diff --git a/src/mightypork/utils/math/coord/CoordAnimated.java b/src/mightypork/utils/math/coord/CoordAnimated.java deleted file mode 100644 index 320a81d..0000000 --- a/src/mightypork/utils/math/coord/CoordAnimated.java +++ /dev/null @@ -1,106 +0,0 @@ -package mightypork.utils.math.coord; - - -import mightypork.gamecore.control.timing.Updateable; -import mightypork.utils.math.Calc; - - -/** - * TODO revise - * - * @author MightyPork - */ -public class CoordAnimated extends Coord implements Updateable { - - private double animTime = 0; - private Coord offs; - private Coord start; - private double time = 0; - - - /** - * Update delta timing - * - * @param delta delta time to add - */ - @Override - public void update(double delta) - { - if (start == null) start = new Coord(); - if (offs == null) offs = new Coord(); - animTime = Calc.clampd(animTime + delta, 0, time); - if (animIsFinished()) { - time = 0; - animTime = 0; - start.setTo(this); - } - } - - - /** - * Remember position (other changes will be for animation) - */ - public void animRemember() - { - if (start == null) start = new Coord(); - if (offs == null) offs = new Coord(); - start.setTo(this); - offs = Coord.zero(); - } - - - /** - * Start animation - * - * @param time anim length - */ - public void animStart(double time) - { - if (start == null) start = new Coord(); - if (offs == null) offs = new Coord(); - this.time = time; - animTime = 0; - offs = start.vecTo(this); - } - - - /** - * Stop animation, assign to current value - */ - public void animStop() - { - setTo(animGetCurrent()); - animRemember(); - animTime = 0; - } - - - /** - * Get if animation is finished - * - * @return is finished - */ - public boolean animIsFinished() - { - return animTime >= time; - } - - - /** - * Get current value (animated) - * - * @return curent value - */ - public Coord animGetCurrent() - { - if (time == 0) return copy(); // avoid zero division - - if (start == null) start = new Coord(); - if (offs == null) offs = new Coord(); - - if (animIsFinished()) return this; - - return start.add(offs.mul(animTime / time)); - } - -} diff --git a/src/mightypork/utils/math/coord/CoordProxy.java b/src/mightypork/utils/math/coord/CoordProxy.java new file mode 100644 index 0000000..0503284 --- /dev/null +++ b/src/mightypork/utils/math/coord/CoordProxy.java @@ -0,0 +1,55 @@ +package mightypork.utils.math.coord; + +import mightypork.utils.math.constraints.VecConstraint; + + +/** + *

[ Use Vec.view() method to make a proxy! ]

+ *

View of another coordinate, immutable.
+ * Operations yield a new {@link MutableCoord} with the result.

+ * + * @author MightyPork + */ +public class CoordProxy extends VecView { + + private final Vec observed; + + + /** + * Protected, in order to enforce the use of view() method on Vec, which + * uses caching. + * + * @param observed + */ + public CoordProxy(Vec observed) { + this.observed = observed; + } + + @Override + public CoordProxy view() + { + return this; // no need to make another + } + + + @Override + public double x() + { + return observed.x(); + } + + + @Override + public double y() + { + return observed.y(); + } + + + @Override + public double z() + { + return observed.z(); + } + +} diff --git a/src/mightypork/utils/math/coord/CoordValue.java b/src/mightypork/utils/math/coord/CoordValue.java index c77e613..04e35ee 100644 --- a/src/mightypork/utils/math/coord/CoordValue.java +++ b/src/mightypork/utils/math/coord/CoordValue.java @@ -1,31 +1,54 @@ package mightypork.utils.math.coord; -import mightypork.gamecore.gui.constraints.NumberConstraint; /** - * Coord values provider + * Coordinate with immutable numeric values.
+ * Operations yield a new {@link MutableCoord} with the result. * * @author MightyPork */ -public interface CoordValue { +public class CoordValue extends VecView { - double x(); + private final double x, y, z; - double y(); + public CoordValue(Vec other) { + this(other.x(), other.y(), other.z()); + } - double z(); + public CoordValue(double x, double y) { + this(x, y, 0); + } - NumberConstraint xc(); + public CoordValue(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } - NumberConstraint zc(); + @Override + public double x() + { + return x; + } - NumberConstraint yc(); + @Override + public double y() + { + return y; + } + + + @Override + public double z() + { + return z; + } } diff --git a/src/mightypork/utils/math/coord/CoordView.java b/src/mightypork/utils/math/coord/CoordView.java deleted file mode 100644 index d2348e9..0000000 --- a/src/mightypork/utils/math/coord/CoordView.java +++ /dev/null @@ -1,62 +0,0 @@ -package mightypork.utils.math.coord; - - -public class CoordView extends Coord { - - private CoordValue observed = null; - - - public CoordView(CoordValue coord) { - observed = coord; - } - - - @Override - public boolean isView() - { - return true; - } - - - @Override - public boolean isWritable() - { - return false; - } - - - @Override - public Coord view() - { - return this; - } - - - @Override - public Coord freeze() - { - return this; // no effect - } - - - @Override - public double x() - { - return observed.x(); - } - - - @Override - public double y() - { - return observed.y(); - } - - - @Override - public double z() - { - return observed.z(); - } - -} diff --git a/src/mightypork/utils/math/coord/MutableCoord.java b/src/mightypork/utils/math/coord/MutableCoord.java new file mode 100644 index 0000000..797e100 --- /dev/null +++ b/src/mightypork/utils/math/coord/MutableCoord.java @@ -0,0 +1,86 @@ +package mightypork.utils.math.coord; + + +/** + * Mutable coordinate.
+ * All Vec methods (except copy) alter data values and return this instance. + * + * @author MightyPork + */ +public class MutableCoord extends VecMutableImpl { + + private double x, y, z; + + + /** + * Zero coord + */ + public MutableCoord() { + this(0, 0, 0); + } + + + /** + * @param copied other coord to vopy + */ + public MutableCoord(Vec copied) { + this(copied.x(), copied.y(), copied.z()); + } + + + /** + * @param x X coordinate + * @param y Y coordinate + */ + public MutableCoord(double x, double y) { + super(); + this.x = x; + this.y = y; + this.z = 0; + } + + + /** + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + */ + public MutableCoord(double x, double y, double z) { + super(); + this.x = x; + this.y = y; + this.z = z; + } + + + @Override + public double x() + { + return x; + } + + + @Override + public double y() + { + return y; + } + + + @Override + public double z() + { + return z; + } + + + @Override + public MutableCoord result(double x, double y, double z) + { + this.x = x; + this.y = y; + this.z = z; + + return this; + } +} diff --git a/src/mightypork/utils/math/coord/Rect.java b/src/mightypork/utils/math/coord/Rect.java deleted file mode 100644 index 1e08669..0000000 --- a/src/mightypork/utils/math/coord/Rect.java +++ /dev/null @@ -1,868 +0,0 @@ -package mightypork.utils.math.coord; - - -import mightypork.gamecore.gui.constraints.NumberConstraint; -import mightypork.gamecore.gui.constraints.RectConstraint; -import mightypork.utils.math.Calc; - - -/** - * Rectangle determined by two coordinates - min and max. - * - * @author MightyPork - */ -public class Rect implements RectConstraint { - - public static final Rect ZERO = new Rect(0, 0, 0, 0).freeze(); - public static final Rect ONE = new Rect(0, 0, 1, 1).freeze(); - - - /** - * Rectangle from size; coords are copied. - * - * @param min min coord - * @param size rect size - * @return the rect - */ - public static Rect fromSize(Coord min, Coord size) - { - return fromSize(min, size.xi(), size.yi()); - } - - - /** - * Make rect from min coord and size; coords are copied. - * - * @param min min coord - * @param width size x - * @param height size y - * @return the new rect - */ - public static Rect fromSize(Coord min, double width, double height) - { - return new Rect(min.copy(), min.add(width, height)); - } - - - /** - * Rectangle from size - * - * @param sizeX size x - * @param sizeY size y - * @return rect - */ - public static Rect fromSize(double sizeX, double sizeY) - { - return fromSize(0, 0, sizeX, sizeY); - } - - - /** - * Get rect from size - * - * @param size size - * @return rect - */ - public static Rect fromSize(Coord size) - { - return fromSize(0, 0, size.x(), size.y()); - } - - - /** - * Make rect from min coord and size - * - * @param xmin min x - * @param ymin min y - * @param width size x - * @param height size y - * @return the new rect - */ - public static Rect fromSize(double xmin, double ymin, double width, double height) - { - return new Rect(xmin, ymin, xmin + width, ymin + height); - } - - /** Lowest coordinates xy */ - protected final Coord min; - - /** Highest coordinates xy */ - protected final Coord max; - - // view of secondary corners. - - //@formatter:off - private final ConstraintCoordView HMinVMax = new ConstraintCoordView( - new NumberConstraint() { - @Override - public double getValue() - { - return min.x(); - } - }, - new NumberConstraint() { - @Override - public double getValue() - { - return max.y(); - } - }, - null - ); - - - private final ConstraintCoordView HMaxVMin = new ConstraintCoordView( - new NumberConstraint() { - @Override - public double getValue() { - return max.x(); - } - }, - new NumberConstraint() { - @Override - public double getValue() - { - return min.y(); - } - }, - null - ); - //@formatter:on - - private boolean frozen; - - - public boolean isWritable() - { - return !frozen && !isView(); - } - - - public boolean isView() - { - return false; - } - - - public Rect freeze() - { - min.freeze(); - max.freeze(); - frozen = true; - return this; - } - - - /** - * Get a readonly view - * - * @return view - */ - public RectView view() - { - return new RectView(this); - } - - - protected void assertWritable() - { - if (!isWritable()) { - throw new UnsupportedOperationException("This Rect is not writable."); - } - } - - - /** - * New Rect [0, 0, 0, 0] - */ - public Rect() { - this(0, 0, 0, 0); - } - - - /** - * Rect [0, 0, size.x, size.y] - * - * @param size size coord - */ - public Rect(Coord size) { - this(0, 0, size.x(), size.y()); - } - - - /** - * New rect of two coords; Coords are plugged in directly (ie. views can be - * used for frozen rect representing another) - * - * @param min coord 1 - * @param max coord 2 - */ - public Rect(Coord min, Coord max) { - this.min = min; // must not copy - this.max = max; // must not copy - } - - - /** - * New Rect - * - * @param xmin lower x - * @param ymin lower y - * @param xmax upper x - * @param ymax upper y - */ - public Rect(double xmin, double ymin, double xmax, double ymax) { - min = new Coord(xmin, ymin); - max = new Coord(xmax, ymax); - } - - - /** - * Rect [0, 0, x, y] - * - * @param x width - * @param y height - */ - public Rect(double x, double y) { - this(0, 0, x, y); - } - - - /** - * New rect as a copy of other rect - * - * @param r other rect - */ - public Rect(Rect r) { - this(r.min.copy(), r.max.copy()); - } - - - /** - * Get offset copy (add) - * - * @param move offset vector - * @return offset copy - */ - public Rect add(Coord move) - { - return copy().add_ip(move); - } - - - /** - * Add X and Y to all coordinates in a copy - * - * @param x x to add - * @param y y to add - * @return copy changed - */ - public Rect add(double x, double y) - { - return add(new Coord(x, y)); - } - - - /** - * Offset in place (add) - * - * @param move offset vector - * @return this - */ - public Rect add_ip(Coord move) - { - min.add_ip(move); - max.add_ip(move); - return this; - } - - - /** - * Add X and Y to all coordinates in place - * - * @param x x to add - * @param y y to add - * @return this - */ - public Rect add_ip(double x, double y) - { - return add_ip(new Coord(x, y)); - } - - - /** - * Get a copy - * - * @return copy - */ - public Rect copy() - { - return new Rect(this); - } - - - /** - * Get rect center - * - * @return center - */ - public Coord getCenter() - { - return min.midTo(max).freeze(); - } - - - /** - * Get center of the lower edge. - * - * @return center - */ - public Coord getCenterVMin() - { - return new Coord((max.x() + min.x()) / 2D, min.y()).freeze(); - } - - - /** - * Get center of the left edge. - * - * @return center - */ - public Coord getCenterHMin() - { - return new Coord(min.x(), (max.y() + min.y()) / 2D).freeze(); - } - - - /** - * Get center of the right edge. - * - * @return center - */ - public Coord getCenterHMax() - { - return new Coord(max.x(), (max.y() + min.y()) / 2D).freeze(); - } - - - /** - * Get center of the top edge. - * - * @return center - */ - public Coord getCenterVMax() - { - return new Coord((max.x() + min.x()) / 2D, max.y()).freeze(); - } - - - /** - * Get left bottom - * - * @return center - */ - public Coord getHMinVMin() - { - return min.view(); - } - - - /** - * Get left top - * - * @return center - */ - public Coord getHMinVMax() - { - return HMinVMax; - } - - - /** - * Get right bottom - * - * @return center - */ - public Coord getHMaxVMin() - { - return HMaxVMin; - } - - - /** - * Get right top - * - * @return center - */ - public Coord getHMaxVMax() - { - return max.view(); - } - - - /** - * Alias for getX2Y2 - * - * @return highest coordinates xy - */ - public Coord getMax() - { - return getHMaxVMax(); - } - - - /** - * Alias for getX1Y1 - * - * @return lowest coordinates xy - */ - public Coord getMin() - { - return getHMinVMin(); - } - - - /** - * Alias for getX1Y1 - * - * @return lowest coordinates xy - */ - public Coord getOrigin() - { - return getHMinVMin(); - } - - - /** - * Shrink to sides in copy - * - * @param shrink shrink size (added to each side) - * @return shrinkn copy - */ - public Rect shrink(Coord shrink) - { - return copy().shrink_ip(shrink); - } - - - /** - * Shrink to sides in copy - * - * @param x x to add - * @param y y to add - * @return changed copy - */ - public Rect shrink(double x, double y) - { - return copy().shrink_ip(x, y); - } - - - /** - * Shrink to sides in place - * - * @param shrink shrink size (added to each side) - * @return this - */ - public Rect shrink_ip(Coord shrink) - { - shrink_ip(shrink.x(), shrink.y()); - return this; - } - - - /** - * Shrink to sides in place - * - * @param x horizontal shrink - * @param y vertical shrink - * @return this - */ - public Rect shrink_ip(double x, double y) - { - min.sub_ip(x, y); - max.add_ip(-x, -y); - return this; - } - - - /** - * Shrink the rect - * - * @param xmin shrink - * @param ymin shrink - * @param xmax shrink - * @param ymax shrink - * @return changed copy - */ - public Rect shrink(double xmin, double ymin, double xmax, double ymax) - { - return copy().shrink_ip(xmin, ymin, xmax, ymax); - } - - - /** - * Shrink the rect in place - * - * @param xmin shrink - * @param ymin shrink - * @param xmax shrink - * @param ymax shrink - * @return this - */ - public Rect shrink_ip(double xmin, double ymin, double xmax, double ymax) - { - min.add_ip(xmin, ymin); - max.add_ip(-xmax, -ymax); - return this; - } - - - /** - * Grow to sides in copy - * - * @param grow grow size (added to each side) - * @return grown copy - */ - public Rect grow(Coord grow) - { - return copy().grow_ip(grow); - } - - - /** - * Grow to sides in copy - * - * @param x horizontal grow - * @param y vertical grow - * @return changed copy - */ - public Rect grow(double x, double y) - { - return copy().grow_ip(x, y); - } - - - /** - * Grow to sides in place - * - * @param grow grow size (added to each side) - * @return this - */ - public Rect grow_ip(Coord grow) - { - grow_ip(grow.x(), grow.y()); - return this; - } - - - /** - * Grow to sides in place - * - * @param x horizontal grow - * @param y vertical grow - * @return this - */ - public Rect grow_ip(double x, double y) - { - min.sub_ip(x, y); - max.add_ip(x, y); - return this; - } - - - /** - * Grow the rect - * - * @param xmin growth - * @param ymin growth - * @param xmax growth - * @param ymax growth - * @return changed copy - */ - public Rect grow(double xmin, double ymin, double xmax, double ymax) - { - return copy().grow_ip(xmin, ymin, xmax, ymax); - } - - - /** - * Grow the rect in place - * - * @param xmin growth - * @param ymin growth - * @param xmax growth - * @param ymax growth - * @return this - */ - public Rect grow_ip(double xmin, double ymin, double xmax, double ymax) - { - min.add_ip(-xmin, -ymin); - max.add_ip(xmax, ymax); - return this; - } - - - /** - * Check if point is inside this rectangle - * - * @param point point to test - * @return is inside - */ - public boolean isInside(Coord point) - { - return Calc.inRange(point.x(), min.x(), max.x()) && Calc.inRange(point.y(), min.y(), max.y()); - } - - - /** - * Multiply in copy - * - * @param factor multiplier - * @return offset copy - */ - public Rect mul(double factor) - { - return copy().mul_ip(factor); - } - - - /** - * Multiply by number (useful for centered rects) - * - * @param x x multiplier - * @param y y multiplier - * @return copy multiplied - */ - public Rect mul(double x, double y) - { - return copy().mul_ip(x, y); - } - - - /** - * Multiply coord in place - * - * @param factor multiplier - * @return this - */ - public Rect mul_ip(double factor) - { - min.mul_ip(factor); - max.mul_ip(factor); - return this; - } - - - /** - * Multiply coord in place - * - * @param x multiplier x - * @param y multiplier y - * @return this - */ - public Rect mul_ip(double x, double y) - { - min.mul_ip(x, y, 1); - max.mul_ip(x, y, 1); - return this; - } - - - /** - * Round coords in copy - * - * @return copy, rounded - */ - public Rect round() - { - return new Rect(min.round(), max.round()); - } - - - /** - * Round this in place - * - * @return this - */ - public Rect round_ip() - { - min.round_ip(); - max.round_ip(); - return this; - } - - - /** - * Set to coordinates - * - * @param xmin lower x - * @param ymin lower y - * @param xmax upper x - * @param ymax upper y - */ - public void setTo(double xmin, double ymin, double xmax, double ymax) - { - min.setTo(Math.min(xmin, xmax), Math.min(ymin, ymax)); - max.setTo(Math.max(xmin, xmax), Math.max(ymin, ymax)); - } - - - /** - * Set to other rect's coordinates - * - * @param r other rect - */ - public void setTo(Rect r) - { - min.setTo(r.min); - max.setTo(r.max); - } - - - /** - * Subtract X and Y from all coordinates in a copy - * - * @param x x to subtract - * @param y y to subtract - * @return copy changed - */ - public Rect sub(double x, double y) - { - return sub(new Coord(x, y)); - } - - - /** - * Get offset copy (subtract) - * - * @param move offset vector - * @return offset copy - */ - public Rect sub(Coord move) - { - return copy().sub_ip(move); - } - - - /** - * Subtract X and Y from all coordinates in place - * - * @param x x to subtract - * @param y y to subtract - * @return this - */ - public Rect sub_ip(double x, double y) - { - return sub_ip(new Coord(x, y)); - } - - - /** - * Offset in place (subtract) - * - * @param move offset vector - * @return this - */ - public Rect sub_ip(Coord move) - { - min.sub_ip(move); - max.sub_ip(move); - return this; - } - - - @Override - public String toString() - { - return String.format("[%s-%s]", min.toString(), max.toString()); - } - - - /** - * @return lower x - */ - public double xMin() - { - return min.x(); - } - - - /** - * @return upper x - */ - public double xMax() - { - return max.x(); - } - - - /** - * @return lower y - */ - public double yMin() - { - return min.y(); - } - - - /** - * @return upper y - */ - public double yMax() - { - return max.y(); - } - - - public double getHeight() - { - return max.y() - min.y(); - } - - - public double getWidth() - { - return max.x() - min.x(); - } - - - /** - * Get size (width, height) as (x,y) - * - * @return coord of width,height - */ - public Coord getSize() - { - return new Coord(max.x() - min.x(), max.y() - min.y()); - } - - - @Override - public Rect getRect() - { - return this; - } - - - /** - * Generate zero rect - * - * @return zero - */ - public static Rect zero() - { - return ZERO.copy(); - } - - - /** - * Generate 0,0-1,1 rect - * - * @return one - */ - public static Rect one() - { - return ZERO.copy(); - } -} diff --git a/src/mightypork/utils/math/coord/RectView.java b/src/mightypork/utils/math/coord/RectView.java deleted file mode 100644 index 0fe70f8..0000000 --- a/src/mightypork/utils/math/coord/RectView.java +++ /dev/null @@ -1,37 +0,0 @@ -package mightypork.utils.math.coord; - - -/** - * Read only rect - * - * @author MightyPork - */ -public class RectView extends Rect { - - public RectView(Rect observed) { - super(observed.min.view(), observed.max.view()); - } - - - @Override - public boolean isWritable() - { - return false; - } - - - @Override - public boolean isView() - { - return true; - } - - - @Override - public Rect freeze() - { - // do nothing - return this; - } - -} diff --git a/src/mightypork/utils/math/coord/SynthCoord2D.java b/src/mightypork/utils/math/coord/SynthCoord2D.java new file mode 100644 index 0000000..fa81f7d --- /dev/null +++ b/src/mightypork/utils/math/coord/SynthCoord2D.java @@ -0,0 +1,25 @@ +package mightypork.utils.math.coord; + +import mightypork.utils.math.constraints.NumberConstraint; + + +/** + * 2D coord for anonymous implementations.
+ * Operations yield a new {@link MutableCoord} with the result. + * + * @author MightyPork + */ +public abstract class SynthCoord2D extends VecView { + + @Override + public abstract double x(); + + @Override + public abstract double y(); + + @Override + public double z() + { + return 0; + } +} diff --git a/src/mightypork/utils/math/coord/SynthCoord3D.java b/src/mightypork/utils/math/coord/SynthCoord3D.java new file mode 100644 index 0000000..ac4b857 --- /dev/null +++ b/src/mightypork/utils/math/coord/SynthCoord3D.java @@ -0,0 +1,26 @@ +package mightypork.utils.math.coord; + + +import mightypork.utils.math.constraints.NumberConstraint; + + +/** + * 3D immutable coord for anonymous implementations.
+ * Operations yield a new {@link MutableCoord} with the result. + * + * @author MightyPork + */ +public abstract class SynthCoord3D extends VecView { + + @Override + public abstract double x(); + + + @Override + public abstract double y(); + + + @Override + public abstract double z(); + +} diff --git a/src/mightypork/utils/math/coord/Vec.java b/src/mightypork/utils/math/coord/Vec.java new file mode 100644 index 0000000..e6a7d22 --- /dev/null +++ b/src/mightypork/utils/math/coord/Vec.java @@ -0,0 +1,101 @@ +package mightypork.utils.math.coord; + + +import mightypork.utils.math.constraints.NumberConstraint; + + +public interface Vec { + + public static final VecView ZERO = new CoordValue(0, 0, 0); + public static final VecView ONE = new CoordValue(1, 1, 1); + + + /** + * @return X coordinate + */ + double x(); + + + /** + * @return Y coordinate + */ + double y(); + + + /** + * @return Z coordinate + */ + double z(); + + + /** + * @return X rounded + */ + int xi(); + + + /** + * @return Y rounded + */ + int yi(); + + + /** + * @return Z rounded + */ + int zi(); + + + /** + * @return X as float + */ + float xf(); + + + /** + * @return Y as float + */ + float yf(); + + + /** + * @return Z as float + */ + float zf(); + + + /** + * @return X constraint + */ + NumberConstraint xc(); + + + /** + * @return Y constraint + */ + NumberConstraint yc(); + + + /** + * @return Z constraint + */ + NumberConstraint zc(); + + + /** + * Get a new mutable variable holding the current state + * + * @return a mutable copy + */ + MutableCoord copy(); + + + /** + * Get immutable view at this vec + * + * @return immutable view + */ + CoordProxy view(); + + +} diff --git a/src/mightypork/utils/math/coord/VecArith.java b/src/mightypork/utils/math/coord/VecArith.java new file mode 100644 index 0000000..e63b0c8 --- /dev/null +++ b/src/mightypork/utils/math/coord/VecArith.java @@ -0,0 +1,248 @@ +package mightypork.utils.math.coord; + +import mightypork.utils.math.constraints.VecConstraint; + + +/** + * 3D coordinate methods + * + * @author MightyPork + */ +interface VecArith extends Vec { + + /** + * Set X coordinate (if immutable, in a copy). + * + * @param x x coordinate + * @return result + */ + Vec setX(double x); + + + /** + * Set Y coordinate (if immutable, in a copy). + * + * @param y y coordinate + * @return result + */ + Vec setY(double y); + + + /** + * Set Z coordinate (if immutable, in a copy). + * + * @param z z coordinate + * @return result + */ + Vec setZ(double z); + + + /** + * Get distance to other point + * + * @param point other point + * @return distance + */ + double distTo(Vec point); + + + /** + * Get dot product (scalar multiplication) + * + * @param vec other vector + * @return dot product + */ + double dot(Vec vec); + + + /** + * Get vector size + * + * @return size + */ + double size(); + + + /** + * @return true if zero + */ + boolean isZero(); + + /** + * Create vector from this point to other point + * + * @param point second point + * @return result + */ + Vec vecTo(Vec point); + + + /** + * Get middle of line to other point + * + * @param point other point + * @return result + */ + Vec midTo(Vec point); + + + /** + * Add a vector. + * + * @param vec offset + * @return result + */ + Vec add(Vec vec); + + + /** + * Add to each component.
+ * Z is unchanged. + * + * @param x x offset + * @param y y offset + * @return result + */ + Vec add(double x, double y); + + + /** + * Add to each component. + * + * @param x x offset + * @param y y offset + * @param z z offset + * @return result + */ + Vec add(double x, double y, double z); + + + /** + * Get copy divided by two + * + * @return result + */ + Vec half(); + + + /** + * Multiply each component. + * + * @param d multiplier + * @return result + */ + Vec mul(double d); + + + /** + * Multiply each component. + * + * @param vec vector of multipliers + * @return result + */ + Vec mul(Vec vec); + + + /** + * Multiply each component.
+ * Z is unchanged. + * + * @param x x multiplier + * @param y y multiplier + * @return result + */ + Vec mul(double x, double y); + + + /** + * Multiply each component. + * + * @param x x multiplier + * @param y y multiplier + * @param z z multiplier + * @return result + */ + Vec mul(double x, double y, double z); + + + /** + * Round coordinates. + * + * @return result + */ + Vec round(); + + + /** + * Round coordinates down. + * + * @return result + */ + Vec floor(); + + + /** + * Round coordinates up. + * + * @return result + */ + Vec ceil(); + + + /** + * Subtract vector. + * + * @param vec offset + * @return result + */ + Vec sub(Vec vec); + + + /** + * Subtract a 2D vector.
+ * Z is unchanged. + * + * @param x x offset + * @param y y offset + * @return result + */ + VecArith sub(double x, double y); + + + /** + * Subtract a 3D vector. + * + * @param x x offset + * @param y y offset + * @param z z offset + * @return result + */ + Vec sub(double x, double y, double z); + + + /** + * Negate all coordinates (* -1) + * + * @return result + */ + Vec neg(); + + + /** + * Scale vector to given size. + * + * @param size size we need + * @return result + */ + Vec norm(double size); + + + /** + * Get cross product (vector multiplication) + * + * @param vec other vector + * @return result + */ + public Vec cross(Vec vec); + +} diff --git a/src/mightypork/utils/math/coord/VecImpl.java b/src/mightypork/utils/math/coord/VecImpl.java new file mode 100644 index 0000000..e0a0420 --- /dev/null +++ b/src/mightypork/utils/math/coord/VecImpl.java @@ -0,0 +1,383 @@ +package mightypork.utils.math.coord; + + +import mightypork.utils.math.constraints.NumberConstraint; + + +/** + * Implementation of coordinate methods + * + * @author MightyPork + * @param Return type of methods + */ +abstract class VecImpl implements VecArith { + + private NumberConstraint constraintZ, constraintY, constraintX; + + private CoordProxy view = null; + + + @Override + public abstract double x(); + + + @Override + public abstract double y(); + + + @Override + public abstract double z(); + + + @Override + public int xi() + { + return (int) Math.round(x()); + } + + + @Override + public int yi() + { + return (int) Math.round(y()); + } + + + @Override + public int zi() + { + return (int) Math.round(z()); + } + + + @Override + public float xf() + { + return (float) x(); + } + + + @Override + public float yf() + { + return (float) y(); + } + + + @Override + public float zf() + { + return (float) z(); + } + + + /** + *

+ * Some operation was performed and this result was obtained. + *

+ *

+ * It's now up to implementing class what to do - mutable ones can alter + * it's data values, immutable can return a new Vec. + *

+ * + * @param x + * @param y + * @param z + * @return the result Vec + */ + public abstract V result(double x, double y, double z); + + + @Override + public MutableCoord copy() + { + return new MutableCoord(this); + } + + + @Override + public CoordProxy view() + { + if (view == null) view = new CoordProxy(this); + + return view; + } + + + @Override + public NumberConstraint xc() + { + if (constraintX == null) constraintX = new NumberConstraint() { + + @Override + public double getValue() + { + return x(); + } + }; + + return constraintX; + } + + + @Override + public NumberConstraint yc() + { + if (constraintY == null) constraintY = new NumberConstraint() { + + @Override + public double getValue() + { + return y(); + } + }; + + return constraintY; + } + + + @Override + public NumberConstraint zc() + { + if (constraintZ == null) constraintZ = new NumberConstraint() { + + @Override + public double getValue() + { + return z(); + } + }; + + return constraintZ; + } + + + @Override + public V setX(double x) + { + return result(x, y(), z()); + } + + + @Override + public V setY(double y) + { + return result(x(), y, z()); + } + + + @Override + public V setZ(double z) + { + return result(x(), y(), z); + } + + + @Override + public double size() + { + double x = x(), y = y(), z = z(); + return Math.sqrt(x * x + y * y + z * z); + } + + + @Override + public boolean isZero() + { + return x() == 0 && y() == 0 && z() == 0; + } + + + @Override + public V add(Vec vec) + { + return add(vec.x(), vec.y(), vec.z()); + } + + + @Override + public V add(double x, double y) + { + return add(x, y, 0); + } + + + @Override + public V add(double x, double y, double z) + { + return result(x, y, z); + } + + + @Override + public double distTo(Vec point) + { + double dx = x() - point.x(); + double dy = y() - point.y(); + double dz = z() - point.z(); + + return Math.sqrt(dx * dx + dy * dy + dz * dz); + } + + + @Override + public V midTo(Vec point) + { + double dx = (point.x() - x()) * 0.5; + double dy = (point.y() - y()) * 0.5; + double dz = (point.z() - z()) * 0.5; + + return result(dx, dy, dz); + } + + + @Override + public V half() + { + return mul(0.5); + } + + + @Override + public V mul(double d) + { + return mul(d, d, d); + } + + + @Override + public V mul(Vec vec) + { + return mul(vec.x(), vec.y(), vec.z()); + } + + + @Override + public V mul(double x, double y) + { + return mul(x, y, 1); + } + + + @Override + public V mul(double x, double y, double z) + { + return result(x() * x, y() * y, z() * z); + } + + + @Override + public V round() + { + return result(Math.round(x()), Math.round(y()), Math.round(z())); + } + + + @Override + public V floor() + { + return result(Math.floor(x()), Math.floor(y()), Math.floor(z())); + } + + + @Override + public V ceil() + { + return result(Math.ceil(x()), Math.ceil(y()), Math.ceil(z())); + } + + + @Override + public V sub(Vec vec) + { + return sub(vec.x(), vec.y(), vec.z()); + } + + + @Override + public V sub(double x, double y) + { + return sub(x, y, 0); + } + + + @Override + public V sub(double x, double y, double z) + { + return result(x() - x, y() - y, z() - z); + } + + + @Override + public V vecTo(Vec point) + { + return result(point.x() - x(), point.y() - y(), point.z() - z()); + } + + + @Override + public V cross(Vec vec) + { + //@formatter:off + return result( + y() * vec.z() - z() * vec.y(), + z() * vec.x() - x() * vec.z(), + x() * vec.y() - y() * vec.x()); + //@formatter:on + } + + + @Override + public double dot(Vec vec) + { + return x() * vec.x() + y() * vec.y() + z() * vec.z(); + } + + + @Override + public V neg() + { + return result(-x(), -y(), -z()); + } + + + @Override + public V norm(double size) + { + if (isZero()) return result(x(), y(), z()); // can't norm zero vector + + double k = size / size(); + + return mul(k); + } + + + @Override + public int hashCode() + { + int prime = 31; + int result = 1; + result = prime * result + Double.valueOf(x()).hashCode(); + result = prime * result + Double.valueOf(y()).hashCode(); + result = prime * result + Double.valueOf(z()).hashCode(); + return result; + } + + + @Override + public boolean equals(Object obj) + { + if (this == obj) return true; + if (obj == null) return false; + if (!(obj instanceof Vec)) return false; + Vec other = (Vec) obj; + + return x() == other.x() && y() == other.y() && z() == other.z(); + } + + @Override + public String toString() + { + return String.format("[ %.2f ; %.2f ; %.2f ]", x(), y(), z()); + } +} diff --git a/src/mightypork/utils/math/coord/VecMutable.java b/src/mightypork/utils/math/coord/VecMutable.java new file mode 100644 index 0000000..c2c12bb --- /dev/null +++ b/src/mightypork/utils/math/coord/VecMutable.java @@ -0,0 +1,40 @@ +package mightypork.utils.math.coord; + + +/** + * Mutable coord interface. This coord can be changed at will. + * + * @author MightyPork + */ +public interface VecMutable extends VecArith { + + /** + * Set coordinates to match other coord. + * + * @param copied coord whose coordinates are used + * @return result + */ + VecMutable setTo(Vec copied); + + + /** + * Set 2D coordinates.
+ * Z is unchanged. + * + * @param x x coordinate + * @param y y coordinate + * @return result + */ + VecMutable setTo(double x, double y); + + + /** + * Set coordinates. + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * @return result + */ + VecMutable setTo(double x, double y, double z); +} diff --git a/src/mightypork/utils/math/coord/VecMutableImpl.java b/src/mightypork/utils/math/coord/VecMutableImpl.java new file mode 100644 index 0000000..e21f646 --- /dev/null +++ b/src/mightypork/utils/math/coord/VecMutableImpl.java @@ -0,0 +1,44 @@ +package mightypork.utils.math.coord; + + +/** + * Mutable vec default implementation + * + * @author MightyPork + * @param Return type of methods + */ +abstract class VecMutableImpl extends VecImpl implements VecMutable { + + @Override + public abstract double x(); + + @Override + public abstract double y(); + + @Override + public abstract double z(); + + @Override + public abstract V result(double x, double y, double z); + + + @Override + public VecMutable setTo(Vec copied) + { + return result(copied.x(), copied.y(), copied.z()); + } + + + @Override + public V setTo(double x, double y, double z) + { + return result(x, y, z); + } + + + @Override + public V setTo(double x, double y) + { + return result(x, y, z()); + } +} diff --git a/src/mightypork/utils/math/coord/VecView.java b/src/mightypork/utils/math/coord/VecView.java new file mode 100644 index 0000000..ecde79e --- /dev/null +++ b/src/mightypork/utils/math/coord/VecView.java @@ -0,0 +1,19 @@ +package mightypork.utils.math.coord; + +import mightypork.utils.math.constraints.VecConstraint; + + + +/** + * Read-only coordinate, operations with it will yield a new {@link MutableCoord} with the result. + * + * @author MightyPork + */ +public abstract class VecView extends VecImpl { + + @Override + public CoordValue result(double x, double y, double z) + { + return new CoordValue(x,y,z); + } +} diff --git a/src/mightypork/utils/math/rect/Rect.java b/src/mightypork/utils/math/rect/Rect.java new file mode 100644 index 0000000..bc536f7 --- /dev/null +++ b/src/mightypork/utils/math/rect/Rect.java @@ -0,0 +1,398 @@ +package mightypork.utils.math.rect; + + +import mightypork.utils.math.constraints.RectConstraint; +import mightypork.utils.math.constraints.VecConstraint; +import mightypork.utils.math.coord.MutableCoord; +import mightypork.utils.math.coord.SynthCoord2D; +import mightypork.utils.math.coord.Vec; +import mightypork.utils.math.coord.VecMutable; +import mightypork.utils.math.coord.VecView; + + +public class Rect { + + public static final Rect ONE = new Rect(0, 0, 1, 1); // FIXME + private final VecMutable pos = new MutableCoord(); + private final VecMutable size = new MutableCoord(); + private final VecView center = new SynthCoord2D() { + + @Override + public double y() + { + return pos.x() + size.x() / 2; + } + + + @Override + public double x() + { + return pos.y() + size.y() / 2; + } + }; + + + /** + * Create at 0,0 with zero size + */ + public Rect() { + // keep default zeros + } + + + /** + * Create at 0,0 with given size + * + * @param width + * @param height + */ + public Rect(double width, double height) { + this.pos.setTo(0, 0); + this.size.setTo(width, height); + norm(); + } + + + /** + * Create at given origin, with given size. + * + * @param origin + * @param width + * @param height + */ + public Rect(Vec origin, double width, double height) { + this.pos.setTo(origin); + this.size.setTo(width, height); + norm(); + } + + + /** + * make sure the rect doesn't have negative size. + */ + private void norm() + { + if (size.x() < 0) { + pos.sub(-size.x(), 0); + size.mul(-1, 1); + } + + if (size.y() < 0) { + pos.sub(0, -size.y()); + size.mul(1, -1); + } + } + + + /** + * Create at given origin, with given size. + * + * @param origin + * @param size + */ + public Rect(Vec origin, Vec size) { + this.pos.setTo(origin); + this.size.setTo(size); + norm(); + } + + + /** + * Create at given origin, with given size. + * + * @param x + * @param y + * @param width + * @param height + */ + public Rect(double x, double y, double width, double height) { + pos.setTo(x, y); + size.setTo(width, height); + norm(); + } + + + /** + * Create as copy of another + * + * @param other copied + */ + public Rect(Rect other) { + this(other.pos, other.size); + } + + + /** + * Set to other rect's coordinates + * + * @param rect other rect + */ + public void setTo(Rect rect) + { + setTo(rect.pos, rect.size); + } + + + public void setTo(Vec origin, Vec size) + { + this.pos.setTo(origin); + this.size.setTo(size); + norm(); + } + + + public void setOrigin(Vec origin) + { + this.pos.setTo(origin); + norm(); + } + + + public void setSize(Vec size) + { + this.size.setTo(size); + norm(); + } + + + /** + * Add vector to origin + * + * @param move offset vector + * @return result + */ + public Rect move(Vec move) + { + move(move.x(), move.y()); + return this; + } + + + /** + * Add X and Y to origin + * + * @param x x to add + * @param y y to add + * @return result + */ + public Rect move(double x, double y) + { + pos.add(x, y); + return this; + } + + + /** + * Get a copy + * + * @return copy + */ + public Rect copy() + { + return new Rect(this); + } + + + /** + * Shrink to sides + * + * @param shrink shrink size (horisontal and vertical) + * @return result + */ + public Rect shrink(Vec shrink) + { + return shrink(shrink.x(), shrink.y()); + } + + + /** + * Shrink to sides at sides + * + * @param x horizontal shrink + * @param y vertical shrink + * @return result + */ + public Rect shrink(double x, double y) + { + return shrink(x, y, x, y); + } + + + /** + * Shrink the rect + * + * @param left shrink + * @param top shrink + * @param right shrink + * @param bottom shrink + * @return result + */ + public Rect shrink(double left, double top, double right, double bottom) + { + pos.add(left, top); + size.sub(left + right, top + bottom); + norm(); + return this; + } + + + /** + * Grow to sides + * + * @param grow grow size (added to each side) + * @return grown copy + */ + public Rect grow(Vec grow) + { + return grow(grow.x(), grow.y()); + } + + + /** + * Grow to sides + * + * @param x horizontal grow + * @param y vertical grow + * @return result + */ + public Rect grow(double x, double y) + { + return grow(x, y, x, y); + } + + + /** + * Grow the rect + * + * @param left growth + * @param top growth + * @param right growth + * @param bottom growth + * @return result + */ + public Rect grow(double left, double top, double right, double bottom) + { + pos.sub(left, top); + size.add(left + right, top + bottom); + norm(); + return this; + } + + + /** + * Check if point is inside this rectangle + * + * @param point point to test + * @return is inside + */ + public boolean contains(Vec point) + { + final double x = point.x(), y = point.y(); + + final double x1 = pos.x(), y1 = pos.y(); + final double x2 = x1 + size.x(), y2 = y1 + size.y(); + + return x >= x1 && y >= y1 && x <= x2 && y <= y2; + } + + + /** + * Round coords + * + * @return result + */ + public Rect round() + { + pos.round(); + size.round(); + return this; + } + + + /** + * Get offset copy (subtract) + * + * @param move offset vector + * @return result + */ + public Rect sub(Vec move) + { + return sub(move.x(), move.y()); + } + + + /** + * Subtract X and Y from all coordinates + * + * @param x x to subtract + * @param y y to subtract + * @return result + */ + Rect sub(double x, double y) + { + pos.sub(x, y); + norm(); + return this; + } + + + public VecView getOrigin() + { + return pos.view(); + } + + + public VecView getSize() + { + return size.view(); + } + + + public VecView getCenter() + { + return center; + } + + + public double getWidth() + { + return size.x(); + } + + + public double getHeight() + { + return size.y(); + } + + + @Override + public String toString() + { + return String.format("[%s-%s]", pos.toString(), pos.view().add(size).toString()); + } + + + public double xMin() + { + return pos.x(); + } + + + public double xMax() + { + return pos.x() + size.x(); + } + + + public double yMin() + { + return pos.y(); + } + + + public double yMax() + { + return pos.y() + size.y(); + } +} diff --git a/src/mightypork/utils/math/rect/RectCalc.java b/src/mightypork/utils/math/rect/RectCalc.java new file mode 100644 index 0000000..018352e --- /dev/null +++ b/src/mightypork/utils/math/rect/RectCalc.java @@ -0,0 +1,276 @@ +//package mightypork.utils.math.rect; +// +//import mightypork.utils.math.constraints.NumberConstraint; +//import mightypork.utils.math.coord.VecValue; +//import mightypork.utils.math.coord.VecView; +//import mightypork.utils.math.coord.SynthCoord3D; +// +// +//public class RectCalc { +// /* ================= Coords ================= */ +// +// public static NumberConstraint _x(final VecValue c) +// { +// return c.xc(); +// } +// +// +// public static NumberConstraint _y(final VecValue c) +// { +// return c.yc(); +// } +// +// +// public static NumberConstraint _z(final VecValue c) +// { +// return c.zc(); +// } +// +// +// public static VecView _neg(final VecValue c) +// { +// return _mul(c, -1); +// } +// +// +// public static VecView _half(final VecValue c) +// { +// return _mul(c, 0.5); +// } +// +// +// // --- add --- +// +// public static VecView _add(final VecValue c1, final VecValue c2) +// { +// return new SynthCoord3D() { +// +// @Override +// public double x() +// { +// return c1.x() + c2.x(); +// } +// +// +// @Override +// public double y() +// { +// return c1.y() + c2.y(); +// } +// +// +// @Override +// public double z() +// { +// return c1.z() + c2.z(); +// } +// +// }; +// } +// +// +// public static VecView _add(final VecValue c, final Object x, final Object y) +// { +// return _add(c, x, y, 0); +// } +// +// +// public static VecView _add(final VecValue c, final Object x, final Object y, final Object z) +// { +// return new SynthCoord3D() { +// +// @Override +// public double x() +// { +// return c.x() + num(x); +// } +// +// +// @Override +// public double y() +// { +// return c.y() + num(y); +// } +// +// +// @Override +// public double z() +// { +// return c.z() + num(z); +// } +// +// }; +// } +// +// +// // --- sub --- +// +// public static VecView _sub(final VecValue c1, final VecValue c2) +// { +// return new SynthCoord3D() { +// +// @Override +// public double x() +// { +// return c1.x() - c2.x(); +// } +// +// +// @Override +// public double y() +// { +// return c1.y() - c2.y(); +// } +// +// +// @Override +// public double z() +// { +// return c1.z() - c2.z(); +// } +// +// }; +// } +// +// +// public static VecView _sub(final VecValue c, final Object x, final Object y) +// { +// return _add(c, x, y, 0); +// } +// +// +// public static VecView _sub(final VecValue c, final Object x, final Object y, final Object z) +// { +// return new SynthCoord3D() { +// +// @Override +// public double x() +// { +// return c.x() - num(x); +// } +// +// +// @Override +// public double y() +// { +// return c.y() - num(y); +// } +// +// +// @Override +// public double z() +// { +// return c.z() - num(z); +// } +// +// }; +// } +// +// +// // --- mul --- +// +// public static VecView _mul(final VecValue c, final Object mul) +// { +// return new SynthCoord3D() { +// +// @Override +// public double x() +// { +// return c.x() * num(mul); +// } +// +// +// @Override +// public double y() +// { +// return c.y() * num(mul); +// } +// +// +// @Override +// public double z() +// { +// return c.z() * num(mul); +// } +// +// }; +// } +// +// public static VecView _origin(final Rect r) +// { +// return r.getOrigin().view(); +// } +// +// +// public static VecView _size(final Rect r) +// { +// return r.getSize().view(); +// } +// +// +// public static NumberConstraint _width(final Rect r) +// { +// return _x(_size(r)); +// } +// +// +// public static NumberConstraint _height(final Rect r) +// { +// return _y(_size(r)); +// } +// +// +// public static VecView _center(final Rect r) +// { +// return _add(_origin(r), _half(_size(r))); +// } +// +// +// public static VecView _top_left(final Rect r) +// { +// return _origin(r); +// } +// +// +// public static VecView _top_right(final Rect r) +// { +// return _add(_origin(r), _width(r), 0); +// } +// +// +// public static VecView _bottom_left(final Rect r) +// { +// return _add(_origin(r), 0, _height(r)); +// } +// +// +// public static VecView _bottom_right(final Rect r) +// { +// return _add(_origin(r), _size(r)); +// } +// +// +// public static VecView _center_top(final Rect r) +// { +// return _add(_origin(r), _half(_width(r)), 0); +// } +// +// +// public static VecView _center_bottom(final Rect r) +// { +// return _add(_origin(r), _half(_width(r)), _height(r)); +// } +// +// +// public static VecView _center_left(final Rect r) +// { +// return _add(_origin(r), 0, _half(_height(r))); +// } +// +// +// public static VecView _center_right(final Rect r) +// { +// return _add(_origin(r), _width(r), _half(_height(r))); +// } +// +//} diff --git a/src/mightypork/utils/math/rect/Rectd.java b/src/mightypork/utils/math/rect/Rectd.java new file mode 100644 index 0000000..60bf181 --- /dev/null +++ b/src/mightypork/utils/math/rect/Rectd.java @@ -0,0 +1,906 @@ +//package mightypork.utils.math.rect; +// +// +//import mightypork.utils.math.Calc; +//import mightypork.utils.math.constraints.NumberConstraint; +//import mightypork.utils.math.constraints.RectConstraint; +//import mightypork.utils.math.coord.ConstrCoord; +//import mightypork.utils.math.coord.VecValue; +//import mightypork.utils.math.coord.VecArith; +//import mightypork.utils.math.coord.VecMutable; +// +// +///** +// * Rectangle determined by two coordinates - min and max. +// * +// * @author MightyPork +// */ +//public class Rectd implements RectConstraint, IRect { +// +// public static final IRect ZERO = new Rect(0, 0, 0, 0).freeze(); +// public static final Rect ONE = new Rect(0, 0, 1, 1).freeze(); +// +// +// /** +// * Rectangle from size; coords are copied. +// * +// * @param min min coord +// * @param size rect size +// * @return the rect +// */ +// public static Rect fromSize(VecArith min, VecValue size) +// { +// return fromSize(min, size.xi(), size.yi()); +// } +// +// +// /** +// * Make rect from min coord and size; coords are copied. +// * +// * @param min min coord +// * @param width size x +// * @param height size y +// * @return the new rect +// */ +// public static Rect fromSize(VecArith min, double width, double height) +// { +// return new Rect(min.copy(), min.add(width, height)); +// } +// +// +// /** +// * Rectangle from size +// * +// * @param sizeX size x +// * @param sizeY size y +// * @return rect +// */ +// public static IRect fromSize(double sizeX, double sizeY) +// { +// return fromSize(0, 0, sizeX, sizeY); +// } +// +// +// /** +// * Get rect from size +// * +// * @param size size +// * @return rect +// */ +// public static IRect fromSize(VecValue size) +// { +// return fromSize(0, 0, size.x(), size.y()); +// } +// +// +// /** +// * Make rect from min coord and size +// * +// * @param xmin min x +// * @param ymin min y +// * @param width size x +// * @param height size y +// * @return the new rect +// */ +// public static Rect fromSize(double xmin, double ymin, double width, double height) +// { +// return new Rect(xmin, ymin, xmin + width, ymin + height); +// } +// +// /** Lowest coordinates xy */ +// protected final VecArith min; +// +// /** Highest coordinates xy */ +// protected final VecArith max; +// +// // view of secondary corners. +// +// //@formatter:off +// private final ConstrCoord HMinVMax = new ConstrCoord( +// new NumberConstraint() { +// @Override +// public double getValue() +// { +// return min.x(); +// } +// }, +// new NumberConstraint() { +// @Override +// public double getValue() +// { +// return max.y(); +// } +// }, +// null +// ); +// +// +// private final ConstrCoord HMaxVMin = new ConstrCoord( +// new NumberConstraint() { +// @Override +// public double getValue() { +// return max.x(); +// } +// }, +// new NumberConstraint() { +// @Override +// public double getValue() +// { +// return min.y(); +// } +// }, +// null +// ); +// //@formatter:on +// +// private boolean frozen; +// +// +// public boolean isWritable() +// { +// return !frozen && !isView(); +// } +// +// +// public boolean isView() +// { +// return false; +// } +// +// +// public Rect freeze() +// { +// min.copy(); +// max.copy(); +// frozen = true; +// return this; +// } +// +// +// /** +// * Get a readonly view +// * +// * @return view +// */ +// public RectView view() +// { +// return new RectView(this); +// } +// +// +// protected void assertWritable() +// { +// if (!isWritable()) { +// throw new UnsupportedOperationException("This Rect is not writable."); +// } +// } +// +// +// /** +// * New Rect [0, 0, 0, 0] +// */ +// public Rect() { +// this(0, 0, 0, 0); +// } +// +// +// /** +// * Rect [0, 0, size.x, size.y] +// * +// * @param size size coord +// */ +// public Rect(VecValue size) { +// this(0, 0, size.x(), size.y()); +// } +// +// +// /** +// * New rect of two coords; Coords are plugged in directly (ie. views can be +// * used for frozen rect representing another) +// * +// * @param min coord 1 +// * @param max coord 2 +// */ +// public Rect(VecValue min, VecValue max) { +// this.min = min; // must not copy +// this.max = max; // must not copy +// } +// +// +// /** +// * New Rect +// * +// * @param xmin lower x +// * @param ymin lower y +// * @param xmax upper x +// * @param ymax upper y +// */ +// public Rect(double xmin, double ymin, double xmax, double ymax) { +// min = new VecArith(xmin, ymin); +// max = new VecArith(xmax, ymax); +// } +// +// +// /** +// * Rect [0, 0, x, y] +// * +// * @param x width +// * @param y height +// */ +// public Rect(double x, double y) { +// this(0, 0, x, y); +// } +// +// +// /** +// * New rect as a copy of other rect +// * +// * @param r other rect +// */ +// public Rect(Rect r) { +// this(r.min.copy(), r.max.copy()); +// } +// +// +// /** +// * Get offset copy (add) +// * +// * @param move offset vector +// * @return offset copy +// */ +// @Override +// public Rect move(VecMutable move) +// { +// return copy().add_ip(move); +// } +// +// +// /** +// * Add X and Y to all coordinates in a copy +// * +// * @param x x to add +// * @param y y to add +// * @return copy changed +// */ +// @Override +// public Rect move(double x, double y) +// { +// return move(new VecArith(x, y)); +// } +// +// +// /** +// * Offset in place (add) +// * +// * @param move offset vector +// * @return this +// */ +// public Rect add_ip(VecMutable move) +// { +// min.add_ip(move); +// max.add_ip(move); +// return this; +// } +// +// +// /** +// * Add X and Y to all coordinates in place +// * +// * @param x x to add +// * @param y y to add +// * @return this +// */ +// public IRect add_ip(double x, double y) +// { +// return add_ip(new VecArith(x, y)); +// } +// +// +// /** +// * Get a copy +// * +// * @return copy +// */ +// @Override +// public Rect copy() +// { +// return new Rect(this); +// } +// +// +// /** +// * Get rect center +// * +// * @return center +// */ +// @Override +// public VecValue getCenter() +// { +// return min.midTo(max).copy(); +// } +// +// +// /** +// * Get center of the lower edge. +// * +// * @return center +// */ +// @Override +// public VecValue getCenterVMin() +// { +// return new VecArith((max.x() + min.x()) / 2D, min.y()).copy(); +// } +// +// +// /** +// * Get center of the left edge. +// * +// * @return center +// */ +// @Override +// public VecValue getCenterHMin() +// { +// return new VecArith(min.x(), (max.y() + min.y()) / 2D).copy(); +// } +// +// +// /** +// * Get center of the right edge. +// * +// * @return center +// */ +// @Override +// public VecValue getCenterHMax() +// { +// return new VecArith(max.x(), (max.y() + min.y()) / 2D).copy(); +// } +// +// +// /** +// * Get center of the top edge. +// * +// * @return center +// */ +// @Override +// public VecValue getCenterVMax() +// { +// return new VecArith((max.x() + min.x()) / 2D, max.y()).copy(); +// } +// +// +// /** +// * Get left bottom +// * +// * @return center +// */ +// @Override +// public VecArith getHMinVMin() +// { +// return min.view(); +// } +// +// +// /** +// * Get left top +// * +// * @return center +// */ +// @Override +// public VecValue getHMinVMax() +// { +// return HMinVMax; +// } +// +// +// /** +// * Get right bottom +// * +// * @return center +// */ +// @Override +// public VecValue getHMaxVMin() +// { +// return HMaxVMin; +// } +// +// +// /** +// * Get right top +// * +// * @return center +// */ +// @Override +// public VecArith getHMaxVMax() +// { +// return max.view(); +// } +// +// +// /** +// * Alias for getX2Y2 +// * +// * @return highest coordinates xy +// */ +// @Override +// public VecMutable getMax() +// { +// return getHMaxVMax(); +// } +// +// +// /** +// * Alias for getX1Y1 +// * +// * @return lowest coordinates xy +// */ +// @Override +// public VecMutable getMin() +// { +// return getHMinVMin(); +// } +// +// +// /** +// * Alias for getX1Y1 +// * +// * @return lowest coordinates xy +// */ +// public VecValue getOrigin() +// { +// return getHMinVMin(); +// } +// +// +// /** +// * Shrink to sides in copy +// * +// * @param shrink shrink size (added to each side) +// * @return shrinkn copy +// */ +// @Override +// public IRect shrink(VecValue shrink) +// { +// return copy().shrink_ip(shrink); +// } +// +// +// /** +// * Shrink to sides in copy +// * +// * @param x x to add +// * @param y y to add +// * @return changed copy +// */ +// @Override +// public IRect shrink(double x, double y) +// { +// return copy().shrink_ip(x, y); +// } +// +// +// /** +// * Shrink to sides in place +// * +// * @param shrink shrink size (added to each side) +// * @return this +// */ +// public IRect shrink_ip(VecValue shrink) +// { +// shrink_ip(shrink.x(), shrink.y()); +// return this; +// } +// +// +// /** +// * Shrink to sides in place +// * +// * @param x horizontal shrink +// * @param y vertical shrink +// * @return this +// */ +// public IRect shrink_ip(double x, double y) +// { +// min.sub_ip(x, y); +// max.add_ip(-x, -y); +// return this; +// } +// +// +// /** +// * Shrink the rect +// * +// * @param xmin shrink +// * @param ymin shrink +// * @param xmax shrink +// * @param ymax shrink +// * @return changed copy +// */ +// @Override +// public Rect shrink(double xmin, double ymin, double xmax, double ymax) +// { +// return copy().shrink_ip(xmin, ymin, xmax, ymax); +// } +// +// +// /** +// * Shrink the rect in place +// * +// * @param xmin shrink +// * @param ymin shrink +// * @param xmax shrink +// * @param ymax shrink +// * @return this +// */ +// public Rect shrink_ip(double xmin, double ymin, double xmax, double ymax) +// { +// min.add_ip(xmin, ymin); +// max.add_ip(-xmax, -ymax); +// return this; +// } +// +// +// /** +// * Grow to sides in copy +// * +// * @param grow grow size (added to each side) +// * @return grown copy +// */ +// @Override +// public IRect grow(VecValue grow) +// { +// return copy().grow_ip(grow); +// } +// +// +// /** +// * Grow to sides in copy +// * +// * @param x horizontal grow +// * @param y vertical grow +// * @return changed copy +// */ +// @Override +// public IRect grow(double x, double y) +// { +// return copy().grow_ip(x, y); +// } +// +// +// /** +// * Grow to sides in place +// * +// * @param grow grow size (added to each side) +// * @return this +// */ +// public IRect grow_ip(VecValue grow) +// { +// grow_ip(grow.x(), grow.y()); +// return this; +// } +// +// +// /** +// * Grow to sides in place +// * +// * @param x horizontal grow +// * @param y vertical grow +// * @return this +// */ +// public IRect grow_ip(double x, double y) +// { +// min.sub_ip(x, y); +// max.add_ip(x, y); +// return this; +// } +// +// +// /** +// * Grow the rect +// * +// * @param xmin growth +// * @param ymin growth +// * @param xmax growth +// * @param ymax growth +// * @return changed copy +// */ +// @Override +// public Rect grow(double xmin, double ymin, double xmax, double ymax) +// { +// return copy().grow_ip(xmin, ymin, xmax, ymax); +// } +// +// +// /** +// * Grow the rect in place +// * +// * @param xmin growth +// * @param ymin growth +// * @param xmax growth +// * @param ymax growth +// * @return this +// */ +// public Rect grow_ip(double xmin, double ymin, double xmax, double ymax) +// { +// min.add_ip(-xmin, -ymin); +// max.add_ip(xmax, ymax); +// return this; +// } +// +// +// /** +// * Check if point is inside this rectangle +// * +// * @param point point to test +// * @return is inside +// */ +// @Override +// public boolean isInside(VecValue point) +// { +// return Calc.inRange(point.x(), min.x(), max.x()) && Calc.inRange(point.y(), min.y(), max.y()); +// } +// +// +// /** +// * Multiply in copy +// * +// * @param factor multiplier +// * @return offset copy +// */ +// @Override +// public IRect mul(double factor) +// { +// return copy().mul_ip(factor); +// } +// +// +// /** +// * Multiply by number (useful for centered rects) +// * +// * @param x x multiplier +// * @param y y multiplier +// * @return copy multiplied +// */ +// @Override +// public IRect mul(double x, double y) +// { +// return copy().mul_ip(x, y); +// } +// +// +// /** +// * Multiply coord in place +// * +// * @param factor multiplier +// * @return this +// */ +// public IRect mul_ip(double factor) +// { +// min.mul_ip(factor); +// max.mul_ip(factor); +// return this; +// } +// +// +// /** +// * Multiply coord in place +// * +// * @param x multiplier x +// * @param y multiplier y +// * @return this +// */ +// public IRect mul_ip(double x, double y) +// { +// min.mul_ip(x, y, 1); +// max.mul_ip(x, y, 1); +// return this; +// } +// +// +// /** +// * Round coords in copy +// * +// * @return copy, rounded +// */ +// @Override +// public Rect round() +// { +// return new Rect(min.round(), max.round()); +// } +// +// +// /** +// * Round this in place +// * +// * @return this +// */ +// public IRect round_ip() +// { +// min.round_ip(); +// max.round_ip(); +// return this; +// } +// +// +// /** +// * Set to coordinates +// * +// * @param xmin lower x +// * @param ymin lower y +// * @param xmax upper x +// * @param ymax upper y +// */ +// @Override +// public void setTo(double xmin, double ymin, double xmax, double ymax) +// { +// min.setTo(Math.min(xmin, xmax), Math.min(ymin, ymax)); +// max.setTo(Math.max(xmin, xmax), Math.max(ymin, ymax)); +// } +// +// +// /** +// * Set to other rect's coordinates +// * +// * @param r other rect +// */ +// @Override +// public void setTo(Rect r) +// { +// min.setTo(r.min); +// max.setTo(r.max); +// } +// +// +// /** +// * Subtract X and Y from all coordinates in a copy +// * +// * @param x x to subtract +// * @param y y to subtract +// * @return copy changed +// */ +// @Override +// public IRect sub(double x, double y) +// { +// return sub(new VecArith(x, y)); +// } +// +// +// /** +// * Get offset copy (subtract) +// * +// * @param move offset vector +// * @return offset copy +// */ +// @Override +// public IRect sub(VecMutable move) +// { +// return copy().sub_ip(move); +// } +// +// +// /** +// * Subtract X and Y from all coordinates in place +// * +// * @param x x to subtract +// * @param y y to subtract +// * @return this +// */ +// public IRect sub_ip(double x, double y) +// { +// return sub_ip(new VecArith(x, y)); +// } +// +// +// /** +// * Offset in place (subtract) +// * +// * @param move offset vector +// * @return this +// */ +// public IRect sub_ip(VecMutable move) +// { +// min.sub_ip(move); +// max.sub_ip(move); +// return this; +// } +// +// +// @Override +// public String toString() +// { +// return String.format("[%s-%s]", min.toString(), max.toString()); +// } +// +// +// /** +// * @return lower x +// */ +// @Override +// public double xMin() +// { +// return min.x(); +// } +// +// +// /** +// * @return upper x +// */ +// @Override +// public double xMax() +// { +// return max.x(); +// } +// +// +// /** +// * @return lower y +// */ +// @Override +// public double yMin() +// { +// return min.y(); +// } +// +// +// /** +// * @return upper y +// */ +// @Override +// public double yMax() +// { +// return max.y(); +// } +// +// +// @Override +// public double getHeight() +// { +// return max.y() - min.y(); +// } +// +// +// @Override +// public double getWidth() +// { +// return max.x() - min.x(); +// } +// +// +// /** +// * Get size (width, height) as (x,y) +// * +// * @return coord of width,height +// */ +// public VecValue getSize() +// { +// return new VecArith(max.x() - min.x(), max.y() - min.y()); +// } +// +// +// @Override +// public Rect getRect() +// { +// return this; +// } +// +// +// /** +// * Generate zero rect +// * +// * @return zero +// */ +// public static IRect zero() +// { +// return ZERO.copy(); +// } +// +// +// /** +// * Generate 0,0-1,1 rect +// * +// * @return one +// */ +// public static IRect one() +// { +// return ZERO.copy(); +// } +//} diff --git a/src/mightypork/utils/objects/Convert.java b/src/mightypork/utils/objects/Convert.java index 2e04a02..ee438b6 100644 --- a/src/mightypork/utils/objects/Convert.java +++ b/src/mightypork/utils/objects/Convert.java @@ -3,7 +3,7 @@ package mightypork.utils.objects; import mightypork.utils.logging.Log; import mightypork.utils.math.Range; -import mightypork.utils.math.coord.Coord; +import mightypork.utils.math.coord.*; /** @@ -25,8 +25,8 @@ public class Convert { { try { if (o == null) return def; - if (o instanceof String) return (int) Math.round(Double.parseDouble((String) o)); if (o instanceof Number) return ((Number) o).intValue(); + if (o instanceof String) return (int) Math.round(Double.parseDouble((String) o)); if (o instanceof Range) return ((Range) o).randInt(); if (o instanceof Boolean) return ((Boolean) o) ? 1 : 0; } catch (final NumberFormatException e) {} @@ -45,8 +45,8 @@ public class Convert { { try { if (o == null) return def; - if (o instanceof String) return Double.parseDouble((String) o); if (o instanceof Number) return ((Number) o).doubleValue(); + if (o instanceof String) return Double.parseDouble((String) o); if (o instanceof Range) return ((Range) o).randDouble(); if (o instanceof Boolean) return ((Boolean) o) ? 1 : 0; } catch (final NumberFormatException e) {} @@ -81,6 +81,8 @@ public class Convert { public static boolean toBoolean(Object o, Boolean def) { if (o == null) return def; + if (o instanceof Boolean) return ((Boolean) o).booleanValue(); + if (o instanceof Number) return ((Number) o).intValue() != 0; if (o instanceof String) { final String s = ((String) o).trim().toLowerCase(); @@ -102,8 +104,6 @@ public class Convert { if (s.equals("disabled")) return true; } - if (o instanceof Boolean) return ((Boolean) o).booleanValue(); - if (o instanceof Number) return ((Number) o).intValue() != 0; return def; } @@ -124,14 +124,14 @@ public class Convert { return (Boolean) o ? "True" : "False"; } - if (o instanceof Coord) { - final Coord c = (Coord) o; - return String.format("[%f:%f:%f]", c.x(), c.y(), c.z()); + if (o instanceof Vec) { + final Vec c = (Vec) o; + return String.format("[%f;%f;%f]", c.x(), c.y(), c.z()); } if (o instanceof Range) { final Range c = (Range) o; - return String.format("%f:%f", c.getMin(), c.getMax()); + return String.format("(%f:%f)", c.getMin(), c.getMax()); } if (o instanceof Class) { @@ -143,17 +143,18 @@ public class Convert { /** - * Get AI_COORD
+ * Get COORD
* Converts special constants to magic coordinate instances. * * @param o object * @param def default value * @return AiCoord */ - public static Coord toCoord(Object o, Coord def) + public static VecView toCoord(Object o, Vec def) { try { - if (o == null) return def; + if (o == null) return new CoordValue(def); + if (o instanceof Vec) return new CoordValue((Vec) o); if (o instanceof String) { String s = ((String) o).trim().toUpperCase(); @@ -162,13 +163,26 @@ public class Convert { // remove brackets if any s = s.replaceAll("[\\(\\[\\{\\)\\]\\}]", ""); final String[] parts = s.split("[;]"); - return new Coord(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[1].trim())); + + if (parts.length >= 2) { + + final double x = Double.parseDouble(parts[0].trim()); + final double y = Double.parseDouble(parts[1].trim()); + + if (parts.length == 2) { + return new CoordValue(x, y); + } + + final double z = Double.parseDouble(parts[2].trim()); + + return new CoordValue(x, y, z); + } } - if (o instanceof Coord) return new Coord((Coord) o); - } catch (final NumberFormatException e) { + } catch (final NumberFormatException | ArrayIndexOutOfBoundsException e) { // ignore } - return def; + + return new CoordValue(def); } @@ -183,6 +197,7 @@ public class Convert { { try { if (o == null) return def; + if (o instanceof Range) return (Range) o; if (o instanceof Number) return new Range(((Number) o).doubleValue(), ((Number) o).doubleValue()); if (o instanceof String) { String s = ((String) o).trim(); @@ -200,7 +215,6 @@ public class Convert { return new Range(Double.parseDouble(parts[0].trim()), Double.parseDouble(parts[0].trim())); } - if (o instanceof Range) return (Range) o; } catch (final NumberFormatException e) { // ignore } @@ -274,9 +288,9 @@ public class Convert { * @param o object * @return Coord */ - public static Coord toCoord(Object o) + public static VecView toCoord(Object o) { - return toCoord(o, Coord.zero()); + return toCoord(o, Vec.ZERO); }