package stu.tnt.math;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Disposable;
public class Line implements Disposable {
public Vector2 lineStart;
public Vector2 lineEnd;
private Vector2 mTMP = new Vector2();
public static final class LineMode {
public static final byte SQUARE_LINE = 0;
public static final byte PARALLEL_LINE = 1;
}
public Line() {
lineStart = new Vector2();
lineEnd = new Vector2();
}
public Line(Line line) {
set(line);
}
public Line(Vector2 startPoint, float angleFactor) {
}
public Line(Vector2 startPoint, Line line, byte linemode) {
if (linemode == LineMode.SQUARE_LINE) {
Vector2 d = line.getNormalVector();
Vector2 endPoint = new Vector2(startPoint.x + d.x, startPoint.y
+ d.y);
set(startPoint, endPoint);
} else if (linemode == LineMode.PARALLEL_LINE) {
Vector2 d = line.getDirectionalVector();
Vector2 endPoint = new Vector2(startPoint.x + d.x, startPoint.y
+ d.y);
set(startPoint, endPoint);
}
}
public Line(float startX, float startY, Vector2 normalVector) {
lineStart = new Vector2(startX, startY);
lineEnd = new Vector2(startX + normalVector.y, startY - normalVector.x);
}
public Line(Vector2 lineStart, Vector2 lineEnd) {
this.lineStart = lineStart;
this.lineEnd = lineEnd;
}
public Line(float startX, float startY, float endX, float endY) {
this.lineStart = new Vector2(startX, startY);
this.lineEnd = new Vector2(endX, endY);
}
/*************************************************************
*
*************************************************************/
public Line set(float x, float y, float x1, float y1) {
lineStart.set(x, y);
lineEnd.set(x1, y1);
return this;
}
public Line setEnd(float x, float y) {
lineEnd.set(x, y);
return this;
}
public Line setStart(float x, float y) {
lineStart.set(x, y);
return this;
}
private void set(Vector2 startPoint, Vector2 endPoint) {
lineStart = startPoint;
lineEnd = endPoint;
}
public Line set(Line line) {
this.lineStart = new Vector2(line.lineStart.x, line.lineStart.y);
this.lineEnd = new Vector2(line.lineEnd.x, line.lineEnd.y);
return this;
}
public Line cpy() {
return new Line(this);
}
/*************************************************************
*
*************************************************************/
public Vector2 getNormalVector() {
mTMP.set(lineEnd.x - lineStart.x, lineEnd.y - lineStart.y);
if (mTMP.y < 0)
mTMP.set(-mTMP.y, mTMP.x);
else
mTMP.set(mTMP.y, -mTMP.x);
return mTMP;
}
public Vector2 getDirectionalVector() {
return mTMP.set(lineEnd.x - lineStart.x, lineEnd.y - lineStart.y);
}
/**
* Get the angle between this line and 0x line
*
* @return result is in range [0,360]
*/
public float getAngleFactor() {
if (lineEnd.x == lineStart.x) {
if (lineEnd.y > lineStart.y)
return 90;
if (lineEnd.y < lineStart.y)
return 270;
}
if (lineEnd.y == lineStart.y) {
if (lineStart.x < lineEnd.x)
return 360;
if (lineStart.x > lineEnd.x)
return 180;
}
if (lineEnd.x > lineStart.x)
return (float) (180.0f / MathUtils.PI * Math
.atan((lineEnd.y - lineStart.y) / (lineEnd.x - lineStart.x)));
if (lineEnd.x < lineStart.x)
return (float) (180.0f / MathUtils.PI * Math
.atan((lineEnd.y - lineStart.y) / (lineEnd.x - lineStart.x))) - 180;
return 0;
}
public float getConstantOfLine() {
Vector2 n = getNormalVector();
float c = -(n.x * lineStart.x + n.y * lineStart.y);
return c;
}
public Vector2 getMidPoint() {
return mTMP.set((lineStart.x + lineEnd.x) / 2,
(lineStart.y + lineEnd.y) / 2);
}
/*************************************************************
*
*************************************************************/
public float module() {
float tmp = (float) Math.sqrt((lineStart.x - lineEnd.x)
* (lineStart.x - lineEnd.x) + (lineStart.y - lineEnd.y)
* (lineStart.y - lineEnd.y));
return tmp;
}
public float module2() {
float tmp = (float) ((lineStart.x - lineEnd.x)
* (lineStart.x - lineEnd.x) + (lineStart.y - lineEnd.y)
* (lineStart.y - lineEnd.y));
return tmp;
}
/*************************************************************
*
*************************************************************/
public int getXinLine(int y) {
float delta = ((float) (lineStart.x - lineEnd.x) / (float) (lineStart.y - lineEnd.y));
return (int) (delta * (y - lineStart.y) + lineStart.x);
}
public float getYinLine(float x) {
float delta = ((float) (lineStart.y - lineEnd.y) / (float) (lineStart.x - lineEnd.x));
return (int) (delta * (x - lineStart.x) + lineStart.y);
}
/**
* You input point(x0,y0) and i will return: a*x0 + b*y0 + c
*
* @param point
* @return
*/
public float getLine(Vector2 point) {
// Normal vector in 2D (vector pha'p tuyen)
Vector2 n = getNormalVector();
float c = -(n.x * lineStart.x + n.y * lineStart.y);
return (n.x * point.x + n.y * point.y + c);
}
/*************************************************************
*
*************************************************************/
public float getSideOnLine(Vector2 point) {
float side = getLine(point);
return side;
}
public boolean isOnLeftSide(Vector2 point) {
if (getSideOnLine(point) < 0)
return true;
return false;
}
public boolean isOnRightSide(Vector2 point) {
if (getSideOnLine(point) > 0)
return true;
return false;
}
public float calDistancePointToLine(Vector2 point) {
float delta = Math.abs(getLine(point));
float module = getNormalVector().len();
return (delta / module);
}
public Vector2 calCrossPoint(Line line) {
mTMP = getNormalVector();
float a1 = mTMP.x;
float b1 = mTMP.y;
float c1 = getConstantOfLine();
mTMP = line.getNormalVector();
float a2 = mTMP.x;
float b2 = mTMP.y;
float c2 = line.getConstantOfLine();
if (a1 * b2 == b1 * a2)
return null;
else
return new Vector2((b1 * c2 - c1 * b2) / (b2 * a1 - b1 * a2), (a2
* c1 - c2 * a1)
/ (b2 * a1 - b1 * a2));
}
@Override
public void dispose() {
lineEnd = null;
lineStart = null;
mTMP = null;
}
}