Add removal mechanism for signal wires.
This commit is contained in:
parent
a2bcf79309
commit
8b3bbfee78
@ -13,11 +13,14 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.codigoparallevar.minicards.motion.MotionMode;
|
import com.codigoparallevar.minicards.motion.MotionMode;
|
||||||
|
import com.codigoparallevar.minicards.parts.connectors.SignalRoundOutputConnector;
|
||||||
import com.codigoparallevar.minicards.types.Part;
|
import com.codigoparallevar.minicards.types.Part;
|
||||||
import com.codigoparallevar.minicards.types.PartConnection;
|
import com.codigoparallevar.minicards.types.PartConnection;
|
||||||
import com.codigoparallevar.minicards.types.PartGrid;
|
import com.codigoparallevar.minicards.types.PartGrid;
|
||||||
import com.codigoparallevar.minicards.types.Position;
|
import com.codigoparallevar.minicards.types.Position;
|
||||||
import com.codigoparallevar.minicards.types.Selectable;
|
import com.codigoparallevar.minicards.types.Selectable;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.Wiring.SignalWire;
|
||||||
|
import com.codigoparallevar.minicards.types.connectors.Wiring.Wire;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.AnyInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.AnyInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.BooleanInputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.BooleanInputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
||||||
@ -35,6 +38,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class CanvasView extends View implements PartGrid {
|
public class CanvasView extends View implements PartGrid {
|
||||||
|
private static final String LogTag = "Canvas view";
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
List<Part> parts = new ArrayList<>();
|
List<Part> parts = new ArrayList<>();
|
||||||
@ -92,7 +96,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
Map<String, Part> partsById = buildPartsById();
|
Map<String, Part> partsById = buildPartsById();
|
||||||
for (PartConnection connection : connections){
|
for (PartConnection connection : connections){
|
||||||
if (!partsById.containsKey(connection.inputPartId)){
|
if (!partsById.containsKey(connection.inputPartId)){
|
||||||
Log.e("Canvas view", "Key '" + connection.inputPartId
|
Log.e(LogTag, "Key '" + connection.inputPartId
|
||||||
+ "' not found on deserialization");
|
+ "' not found on deserialization");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -101,14 +105,14 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
InputConnector inputConnector = inputPart.getConnectorWithId(connection.inputConnectorId);
|
InputConnector inputConnector = inputPart.getConnectorWithId(connection.inputConnectorId);
|
||||||
|
|
||||||
if (inputConnector == null){
|
if (inputConnector == null){
|
||||||
Log.e("Canvas view", "Connector ID '" + connection.inputConnectorId
|
Log.e(LogTag, "Connector ID '" + connection.inputConnectorId
|
||||||
+ "' not found on deserialization");
|
+ "' not found on deserialization");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputConnector outputConnector = connection.outputConnector;
|
OutputConnector outputConnector = connection.outputConnector;
|
||||||
if (inputConnector == null){
|
if (inputConnector == null){
|
||||||
Log.e("Canvas view", "Connector not found on connection");
|
Log.e(LogTag, "Connector not found on connection");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +124,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
outputConnector.connectTo(inputConnector);
|
outputConnector.connectTo(inputConnector);
|
||||||
}
|
}
|
||||||
catch (ClassCastException e) {
|
catch (ClassCastException e) {
|
||||||
Log.e("Minicards - Canvas view", "Malformed connection", e);
|
Log.e(LogTag, "Malformed connection", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +133,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
Map<String, Part> partsById = new HashMap<>(parts.size());
|
Map<String, Part> partsById = new HashMap<>(parts.size());
|
||||||
for (Part part : parts) {
|
for (Part part : parts) {
|
||||||
partsById.put(part.get_id(), part);
|
partsById.put(part.get_id(), part);
|
||||||
Log.w("CanvasView", "Added part ID: " + part.get_id() + " - " + part);
|
Log.w(LogTag, "Added part ID: " + part.get_id() + " - " + part);
|
||||||
}
|
}
|
||||||
|
|
||||||
return partsById;
|
return partsById;
|
||||||
@ -146,7 +150,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
part.draw(scrolledCanvas, _devMode);
|
part.draw(scrolledCanvas, _devMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log.d("Render time", System.currentTimeMillis() - renderStartTime + "ms");
|
Log.v(LogTag, "Render time: " + (System.currentTimeMillis() - renderStartTime) + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawBackground(ScrolledCanvas canvas) {
|
private void drawBackground(ScrolledCanvas canvas) {
|
||||||
@ -190,11 +194,21 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
lastTouchedPosition.to(xInScreen, yInScreen);
|
lastTouchedPosition.to(xInScreen, yInScreen);
|
||||||
lastTouchedTime = System.currentTimeMillis();
|
lastTouchedTime = System.currentTimeMillis();
|
||||||
if (selectedPart == null) {
|
if (selectedPart == null) {
|
||||||
Log.d("Touched part", "not found");
|
Log.d(LogTag, "Touched part not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (selectedPart instanceof Wire) {
|
||||||
|
// No drag or long-touch, just show the "cut" option
|
||||||
|
// TODO:
|
||||||
|
Log.d(LogTag, "Touched Wire");
|
||||||
|
Wire selectedWire = (Wire) selectedPart;
|
||||||
|
selectedPart = null;
|
||||||
|
|
||||||
Log.d("Touched part", "Part: " + selectedPart);
|
selectedWire.unlink();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log.d(LogTag, "Touched part FOUND. Part: " + selectedPart);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -215,7 +229,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
selectedPart.getMoveable().drop(xInCanvas, yInCanvas);
|
selectedPart.getMoveable().drop(xInCanvas, yInCanvas);
|
||||||
|
|
||||||
if (inDropZone(xInScreen, yInScreen)) {
|
if (inDropZone(xInScreen, yInScreen)) {
|
||||||
Log.d("Canvas", "Deleting element" + selectedPart);
|
Log.d(LogTag, "Deleting element" + selectedPart);
|
||||||
parts.remove(selectedPart);
|
parts.remove(selectedPart);
|
||||||
selectedPart.unlink();
|
selectedPart.unlink();
|
||||||
}
|
}
|
||||||
@ -230,7 +244,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
try {
|
try {
|
||||||
saveState();
|
saveState();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w("PartCanvasView", e.getMessage());
|
Log.w(LogTag, e.getMessage());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -240,7 +254,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d("CanvasView", "Moving part="+selectedPart);
|
// Log.v(LogTag, "Moving part="+selectedPart);
|
||||||
if (selectedPart == null){
|
if (selectedPart == null){
|
||||||
int xMovement = _mouseDownPoint.item1 - xInScreen;
|
int xMovement = _mouseDownPoint.item1 - xInScreen;
|
||||||
int yMovement = _mouseDownPoint.item2 - yInScreen;
|
int yMovement = _mouseDownPoint.item2 - yInScreen;
|
||||||
@ -251,7 +265,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
_mouseDownPoint = new Tuple2(xInScreen, yInScreen);
|
_mouseDownPoint = new Tuple2(xInScreen, yInScreen);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log.d("Canvas", "X: " + xInScreen + " Y: " + yInScreen
|
Log.d(LogTag, "X: " + xInScreen + " Y: " + yInScreen
|
||||||
+ " in drop zone " + _dropToRemoveZone + " : "
|
+ " in drop zone " + _dropToRemoveZone + " : "
|
||||||
+ inDropZone(xInScreen, yInScreen));
|
+ inDropZone(xInScreen, yInScreen));
|
||||||
|
|
||||||
@ -273,7 +287,7 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Log.d("PartCanvasView", "Unhandled action: " + event.getAction());
|
Log.d(LogTag, "Unhandled action: " + event.getAction());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,12 +351,35 @@ public class CanvasView extends View implements PartGrid {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then with input ones
|
// // Then with input ones
|
||||||
List<InputConnector> inputConnectors = part.getInputConnectors();
|
// List<InputConnector> inputConnectors = part.getInputConnectors();
|
||||||
if (inputConnectors != null) {
|
// if (inputConnectors != null) {
|
||||||
for (InputConnector inputConnector : inputConnectors) {
|
// for (InputConnector inputConnector : inputConnectors) {
|
||||||
if (inputConnector.containsPoint(x, y)) {
|
// if (inputConnector.containsPoint(x, y)) {
|
||||||
return inputConnector;
|
// return inputConnector;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, try with the wires
|
||||||
|
for (int i = parts.size() - 1; i >= 0; i--) {
|
||||||
|
final Part part = parts.get(i);
|
||||||
|
List<OutputConnector> outputConnectors = part.getOutputConnectors();
|
||||||
|
if (outputConnectors != null) {
|
||||||
|
for (OutputConnector outputConnector : outputConnectors) {
|
||||||
|
if (outputConnector instanceof SignalRoundOutputConnector) {
|
||||||
|
SignalRoundOutputConnector conn = (SignalRoundOutputConnector) outputConnector;
|
||||||
|
List<SignalWire> wires = conn.getWires();
|
||||||
|
if (wires == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Wire wire : wires) {
|
||||||
|
if (wire.containsPoint(x, y)) {
|
||||||
|
Log.d(LogTag, "Point in wire " + wire);
|
||||||
|
return wire;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,12 +230,10 @@ public class CardActivity extends AppCompatActivity {
|
|||||||
devFabMenu.setVisibility(View.GONE);
|
devFabMenu.setVisibility(View.GONE);
|
||||||
userFabMenu.setVisibility(View.GONE);
|
userFabMenu.setVisibility(View.GONE);
|
||||||
((View)removePartFab).setVisibility(View.VISIBLE);
|
((View)removePartFab).setVisibility(View.VISIBLE);
|
||||||
Log.d("Main", "Changing visibility!");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.setDevMode(devMode);
|
this.setDevMode(devMode);
|
||||||
((View)removePartFab).setVisibility(View.GONE);
|
((View)removePartFab).setVisibility(View.GONE);
|
||||||
Log.d("Main", "Now changing visibility!");
|
|
||||||
}
|
}
|
||||||
canvasView.setDropZone(
|
canvasView.setDropZone(
|
||||||
removePartFab.getX(), removePartFab.getX() + removePartFab.getWidth(),
|
removePartFab.getX(), removePartFab.getX() + removePartFab.getWidth(),
|
||||||
|
@ -20,6 +20,8 @@ import java.util.List;
|
|||||||
|
|
||||||
public class SignalRoundOutputConnector implements Drawable, SignalOutputConnector,
|
public class SignalRoundOutputConnector implements Drawable, SignalOutputConnector,
|
||||||
RoundOutputConnector<Signal, SignalInputConnector, SignalWire> {
|
RoundOutputConnector<Signal, SignalInputConnector, SignalWire> {
|
||||||
|
private static final String LogTag = "RoundOutputConnector";
|
||||||
|
|
||||||
private PartGrid _partGrid;
|
private PartGrid _partGrid;
|
||||||
private int _centerX;
|
private int _centerX;
|
||||||
private int _centerY;
|
private int _centerY;
|
||||||
@ -71,7 +73,7 @@ public class SignalRoundOutputConnector implements Drawable, SignalOutputConnect
|
|||||||
SignalInputConnector resultPoint = _partGrid.getSignalInputConnectorOn(
|
SignalInputConnector resultPoint = _partGrid.getSignalInputConnectorOn(
|
||||||
wire.getXEnd(), wire.getYEnd());
|
wire.getXEnd(), wire.getYEnd());
|
||||||
|
|
||||||
Log.d("RoundOutputConnector", "Dropped wire on " + resultPoint);
|
Log.d(LogTag, "Dropped wire on " + resultPoint);
|
||||||
|
|
||||||
// Not connected
|
// Not connected
|
||||||
if (resultPoint == null){
|
if (resultPoint == null){
|
||||||
@ -88,7 +90,7 @@ public class SignalRoundOutputConnector implements Drawable, SignalOutputConnect
|
|||||||
_wires.add(wire);
|
_wires.add(wire);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log.w("RoundOutputConnector",
|
Log.w(LogTag,
|
||||||
"Asked to drop non matching wire "
|
"Asked to drop non matching wire "
|
||||||
+ "(expected " + _currentWire + ", got " + wire + ")");
|
+ "(expected " + _currentWire + ", got " + wire + ")");
|
||||||
}
|
}
|
||||||
@ -97,6 +99,7 @@ public class SignalRoundOutputConnector implements Drawable, SignalOutputConnect
|
|||||||
@Override
|
@Override
|
||||||
public void unlinkWire(SignalWire wire) {
|
public void unlinkWire(SignalWire wire) {
|
||||||
_wires.remove(wire);
|
_wires.remove(wire);
|
||||||
|
_connections.remove(wire.getAttachedTo());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -173,4 +176,8 @@ public class SignalRoundOutputConnector implements Drawable, SignalOutputConnect
|
|||||||
public float getRadius() {
|
public float getRadius() {
|
||||||
return _radius;
|
return _radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<SignalWire> getWires() {
|
||||||
|
return this._wires;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,23 +3,28 @@ package com.codigoparallevar.minicards.types.connectors.Wiring;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
import com.codigoparallevar.minicards.ScrolledCanvas;
|
import com.codigoparallevar.minicards.ScrolledCanvas;
|
||||||
import com.codigoparallevar.minicards.types.Drawable;
|
import com.codigoparallevar.minicards.types.Drawable;
|
||||||
import com.codigoparallevar.minicards.types.Dropper;
|
import com.codigoparallevar.minicards.types.Dropper;
|
||||||
import com.codigoparallevar.minicards.types.Moveable;
|
import com.codigoparallevar.minicards.types.Moveable;
|
||||||
|
import com.codigoparallevar.minicards.types.Selectable;
|
||||||
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
||||||
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
|
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
|
||||||
import com.codigoparallevar.minicards.types.wireData.WireDataType;
|
import com.codigoparallevar.minicards.types.wireData.WireDataType;
|
||||||
|
|
||||||
public class Wire<T extends WireDataType, InputConnectorType extends InputConnector<T, InputConnectorType>>
|
public class Wire<T extends WireDataType, InputConnectorType extends InputConnector<T, InputConnectorType>>
|
||||||
implements Moveable, Drawable {
|
implements Moveable, Drawable, Selectable {
|
||||||
|
|
||||||
|
private final double MAX_DISTANCE_TO_CONTAINS = 15;
|
||||||
|
|
||||||
private final Dropper _dropper;
|
private final Dropper _dropper;
|
||||||
private int _xinit;
|
private int _xinit;
|
||||||
private int _yinit;
|
private int _yinit;
|
||||||
private int _xend;
|
private int _xend;
|
||||||
private int _yend;
|
private int _yend;
|
||||||
|
private Path path = null;
|
||||||
private final static int _pathRunWay = 100;
|
private final static int _pathRunWay = 100;
|
||||||
protected InputConnectorType _attachedTo = null;
|
protected InputConnectorType _attachedTo = null;
|
||||||
protected OutputConnector _attachedFrom = null;
|
protected OutputConnector _attachedFrom = null;
|
||||||
@ -36,12 +41,14 @@ public class Wire<T extends WireDataType, InputConnectorType extends InputConnec
|
|||||||
public void moveStart(int x, int y){
|
public void moveStart(int x, int y){
|
||||||
_xinit = x;
|
_xinit = x;
|
||||||
_yinit = y;
|
_yinit = y;
|
||||||
|
invalidatePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveEnd(int x, int y) {
|
public void moveEnd(int x, int y) {
|
||||||
_xend = x;
|
_xend = x;
|
||||||
_yend = y;
|
_yend = y;
|
||||||
|
invalidatePath(); // Invalidate current path
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -51,23 +58,17 @@ public class Wire<T extends WireDataType, InputConnectorType extends InputConnec
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(ScrolledCanvas canvas, boolean devMode) {
|
public void draw(ScrolledCanvas canvas, boolean devMode) {
|
||||||
final Path samplePath = new Path();
|
|
||||||
|
|
||||||
samplePath.moveTo(_xinit, _yinit);
|
|
||||||
samplePath.cubicTo(
|
|
||||||
_xinit, _yinit + _pathRunWay,
|
|
||||||
_xend, _yend - _pathRunWay,
|
|
||||||
_xend, _yend);
|
|
||||||
|
|
||||||
Paint pathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
Paint pathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
pathPaint.setColor(Color.parseColor("#44FF44"));
|
pathPaint.setColor(Color.parseColor("#44FF44"));
|
||||||
pathPaint.setStrokeWidth(10.0f);
|
pathPaint.setStrokeWidth(10.0f);
|
||||||
pathPaint.setStrokeCap(Paint.Cap.ROUND);
|
pathPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
pathPaint.setStyle(Paint.Style.STROKE);
|
pathPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
|
||||||
canvas.drawPath(samplePath, pathPaint);
|
canvas.drawPath(getPath(), pathPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public int getXEnd() {
|
public int getXEnd() {
|
||||||
return _xend;
|
return _xend;
|
||||||
}
|
}
|
||||||
@ -83,18 +84,94 @@ public class Wire<T extends WireDataType, InputConnectorType extends InputConnec
|
|||||||
_xend = resultPoint.getX();
|
_xend = resultPoint.getX();
|
||||||
_yend = resultPoint.getY();
|
_yend = resultPoint.getY();
|
||||||
resultPoint.getAttachment(this);
|
resultPoint.getAttachment(this);
|
||||||
|
|
||||||
|
invalidatePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputConnector getAttachedTo() {
|
public InputConnector getAttachedTo() {
|
||||||
return _attachedTo;
|
return _attachedTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Moveable getMoveable() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void unlink() {
|
public void unlink() {
|
||||||
_attachedTo = null;
|
_attachedFrom.unlinkWire(this);
|
||||||
_dropper.unlinkWire(this);
|
_attachedTo.unlinkWire(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object query(Object lastValue) {
|
public Object query(Object lastValue) {
|
||||||
return this._attachedFrom.query(lastValue);
|
return this._attachedFrom.query(lastValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void invalidatePath() {
|
||||||
|
path = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getPath() {
|
||||||
|
if (path == null) {
|
||||||
|
path = new Path();
|
||||||
|
|
||||||
|
// Bezier
|
||||||
|
path.moveTo(_xinit, _yinit);
|
||||||
|
path.cubicTo(
|
||||||
|
_xinit, _yinit + _pathRunWay,
|
||||||
|
_xend, _yend - _pathRunWay,
|
||||||
|
_xend, _yend);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsPoint(int x, int y) {
|
||||||
|
return distanceToPoint(x, y) < MAX_DISTANCE_TO_CONTAINS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double distanceToPoint(int x, int y) {
|
||||||
|
final int POINT_HALFSIDE = 25 / 2;
|
||||||
|
RectF rectangle = new RectF(x - POINT_HALFSIDE, y - POINT_HALFSIDE,
|
||||||
|
x + POINT_HALFSIDE, y + POINT_HALFSIDE);
|
||||||
|
|
||||||
|
double sqDist1 = squareDistanceToSegment(_xinit, _yinit,
|
||||||
|
_xinit, _yinit + _pathRunWay / 3,
|
||||||
|
x, y
|
||||||
|
);
|
||||||
|
double sqDist2 = squareDistanceToSegment(
|
||||||
|
_xinit, _yinit + _pathRunWay / 3,
|
||||||
|
_xend, _yend - _pathRunWay / 3,
|
||||||
|
x, y
|
||||||
|
);
|
||||||
|
double sqDist3 = squareDistanceToSegment(
|
||||||
|
_xend, _yend - _pathRunWay / 3,
|
||||||
|
_xend, _yend,
|
||||||
|
x, y
|
||||||
|
);
|
||||||
|
|
||||||
|
return Math.sqrt(Math.min(sqDist1, Math.min(sqDist2, sqDist3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private double squareDistanceToSegment(int vx, int vy, int wx, int wy, int px, int py) {
|
||||||
|
// Return minimum distance between line segment vw and point p
|
||||||
|
// i.e. |w-v|^2 - avoid a sqrt
|
||||||
|
final double l2 = distance(vx, vy, wx, wy);
|
||||||
|
if (l2 == 0.0) return distance(vx, vy, px, py); // v == w case
|
||||||
|
// Consider the line extending the segment, parameterized as v + t (w - v).
|
||||||
|
// We find projection of point p onto the line.
|
||||||
|
// It falls where t = [(p-v) . (w-v)] / |w-v|^2
|
||||||
|
// We clamp t from [0,1] to handle points outside the segment vw.
|
||||||
|
|
||||||
|
double pointInLine = ((px - vx) * (wx - vx) + (py - vy) * (wy - vy)) / l2;
|
||||||
|
pointInLine = Math.max(0, Math.min(1, pointInLine));
|
||||||
|
|
||||||
|
return distance(vx + pointInLine * (wx - vx),
|
||||||
|
vy + pointInLine * (wy - vy),
|
||||||
|
px, py
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double distance(double vx, double vy, double px, double py) {
|
||||||
|
return Math.pow(vx - px, 2) + Math.pow(vy - py, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user