1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-08 08:23:11 +00:00

Base AI, new Cache system, DAO changes and better geometry handling

Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
2011-05-27 02:49:15 -03:00
parent aabe375b49
commit 73f51e53c0
95 changed files with 3079 additions and 1884 deletions

View File

@@ -0,0 +1,211 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util;
import com.l2jserver.util.geometry.Point;
import com.l2jserver.util.geometry.Point3D;
/**
* Class with basic math.<br>
* Thanks to:
* <ul>
* <li>http://geom-java.sourceforge.net/</li>
* <li>
* http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/DistancePoint.java</li>
* </ul>
* <br>
* <br>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class MathUtil {
/**
* Returns distance between two 2D points
*
* @param point1
* first point
* @param point2
* second point
* @return distance between points
*/
public static double getDistance(Point point1, Point point2) {
return getDistance(point1.x, point1.y, point2.x, point2.y);
}
/**
* Returns distance between two sets of coords
*
* @param x1
* first x coord
* @param y1
* first y coord
* @param x2
* second x coord
* @param y2
* second y coord
* @return distance between sets of coords
*/
public static double getDistance(int x1, int y1, int x2, int y2) {
// using long to avoid possible overflows when multiplying
long dx = x2 - x1;
long dy = y2 - y1;
// return Math.hypot(x2 - x1, y2 - y1); // Extremely slow
// return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); // 20 times faster
// than hypot
return Math.sqrt(dx * dx + dy * dy); // 10 times faster then previous
// line
}
/**
* Returns distance between two 3D points
*
* @param point1
* first point
* @param point2
* second point
* @return distance between points
*/
public static double getDistance(Point3D point1, Point3D point2) {
return getDistance(point1.getX(), point1.getY(), point1.getZ(),
point2.getX(), point2.getY(), point2.getZ());
}
/**
* Returns distance between 3D set of coords
*
* @param x1
* first x coord
* @param y1
* first y coord
* @param z1
* first z coord
* @param x2
* second x coord
* @param y2
* second y coord
* @param z2
* second z coord
* @return distance between coords
*/
public static double getDistance(float x1, float y1, float z1, float x2,
float y2, float z2) {
float dx = x1 - x2;
float dy = y1 - y2;
float dz = z1 - z2;
// We should avoid Math.pow or Math.hypot due to performance reasons
return Math.sqrt(dx * dx + dy * dy + dz * dz);
}
/**
* Returns closest point on segment to point
*
* @param ss
* segment start point
* @param se
* segment end point
* @param p
* point to found closest point on segment
* @return closest point on segment to p
*/
public static Point getClosestPointOnSegment(Point ss, Point se, Point p) {
return getClosestPointOnSegment(ss.x, ss.y, se.x, se.y, p.x, p.y);
}
/**
* Returns closest point on segment to point
*
* @param sx1
* segment x coord 1
* @param sy1
* segment y coord 1
* @param sx2
* segment x coord 2
* @param sy2
* segment y coord 2
* @param px
* point x coord
* @param py
* point y coord
* @return closets point on segment to point
*/
public static Point getClosestPointOnSegment(int sx1, int sy1, int sx2,
int sy2, int px, int py) {
double xDelta = sx2 - sx1;
double yDelta = sy2 - sy1;
if ((xDelta == 0) && (yDelta == 0)) {
throw new IllegalArgumentException(
"Segment start equals segment end");
}
double u = ((px - sx1) * xDelta + (py - sy1) * yDelta)
/ (xDelta * xDelta + yDelta * yDelta);
final Point closestPoint;
if (u < 0) {
closestPoint = new Point(sx1, sy1);
} else if (u > 1) {
closestPoint = new Point(sx2, sy2);
} else {
closestPoint = new Point((int) Math.round(sx1 + u * xDelta),
(int) Math.round(sy1 + u * yDelta));
}
return closestPoint;
}
/**
* Returns distance to segment
*
* @param ss
* segment start point
* @param se
* segment end point
* @param p
* point to found closest point on segment
* @return distance to segment
*/
public static double getDistanceToSegment(Point ss, Point se, Point p) {
return getDistanceToSegment(ss.x, ss.y, se.x, se.y, p.x, p.y);
}
/**
* Returns distance to segment
*
* @param sx1
* segment x coord 1
* @param sy1
* segment y coord 1
* @param sx2
* segment x coord 2
* @param sy2
* segment y coord 2
* @param px
* point x coord
* @param py
* point y coord
* @return distance to segment
*/
public static double getDistanceToSegment(int sx1, int sy1, int sx2,
int sy2, int px, int py) {
Point closestPoint = getClosestPointOnSegment(sx1, sy1, sx2, sy2, px,
py);
return getDistance(closestPoint.x, closestPoint.y, px, py);
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.l2jserver.util.factory;
import java.lang.ref.ReferenceQueue;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -81,6 +82,15 @@ public class CollectionFactory {
return new PriorityQueue<T>();
}
/**
* Creates a new reference queue of type <tt>T</tt>
*
* @return the created queue
*/
public static final <T> ReferenceQueue<T> newReferenceQueue() {
return new ReferenceQueue<T>();
}
/**
* Creates a new map.
*

View File

@@ -0,0 +1,125 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util.geometry;
/**
* Class with basic method implementation for areas.<br>
* If possible it should be subclassed. <br>
* In other case {@link Area} should be implemented directly
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class AbstractArea implements Area {
/**
* Minimal z of area
*/
private final int minZ;
/**
* Maximal Z of area
*/
private final int maxZ;
/**
* Creates new AbstractArea with min and max z
*
* @param minZ
* min z
* @param maxZ
* max z
*/
protected AbstractArea(int minZ, int maxZ) {
if (minZ > maxZ) {
throw new IllegalArgumentException("minZ(" + minZ + ") > maxZ("
+ maxZ + ")");
}
this.minZ = minZ;
this.maxZ = maxZ;
}
@Override
public boolean isInside2D(Point point) {
return isInside2D(point.x, point.y);
}
@Override
public boolean isInside3D(Point3D point) {
return isInside3D(point.getX(), point.getY(), point.getZ());
}
@Override
public boolean isInside3D(int x, int y, int z) {
return isInsideZ(z) && isInside2D(x, y);
}
@Override
public boolean isInsideZ(Point3D point) {
return isInsideZ(point.getZ());
}
@Override
public boolean isInsideZ(int z) {
return z >= getMinZ() && z <= getMaxZ();
}
@Override
public double getDistance2D(Point point) {
return getDistance2D(point.x, point.y);
}
@Override
public double getDistance3D(Point3D point) {
return getDistance3D(point.getX(), point.getY(), point.getZ());
}
@Override
public Point getClosestPoint(Point point) {
return getClosestPoint(point.x, point.y);
}
@Override
public Point3D getClosestPoint(Point3D point) {
return getClosestPoint(point.getX(), point.getY(), point.getZ());
}
@Override
public Point3D getClosestPoint(int x, int y, int z) {
Point closest2d = getClosestPoint(x, y);
int zCoord;
if (isInsideZ(z)) {
zCoord = z;
} else if (z < getMinZ()) {
zCoord = getMinZ();
} else {
zCoord = getMaxZ();
}
return new Point3D(closest2d.x, closest2d.y, zCoord);
}
@Override
public int getMinZ() {
return minZ;
}
@Override
public int getMaxZ() {
return maxZ;
}
}

View File

@@ -0,0 +1,196 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util.geometry;
/**
* Basic interface for all areas.<br>
* It should be implemented in different ways for performance reasons.<br>
* For instance, we don't need complex math for squares or circles, but we need
* it for more complex polygons.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Area {
/**
* Returns true if point is inside area ignoring z value
*
* @param point
* point to check
* @return point is inside or not
*/
boolean isInside2D(Point point);
/**
* Returns true if coords are inside area ignoring z value
*
* @param x
* x coord
* @param y
* y coord
* @return coords are inside or not
*/
boolean isInside2D(int x, int y);
/**
* Returns true if point is inside area
*
* @param point
* point to check
* @return true if point is inside
*/
boolean isInside3D(Point3D point);
/**
* Returns true if coors are inside area
*
* @param x
* x coord
* @param y
* y coord
* @param z
* z coord
* @return true if coords are inside
*/
boolean isInside3D(int x, int y, int z);
/**
* Checks if z coord is insize
*
* @param point
* point to check
* @return is z inside or not
*/
boolean isInsideZ(Point3D point);
/**
* Checks is z coord is inside
*
* @param z
* z coord
* @return is z inside or not
*/
boolean isInsideZ(int z);
/**
* Returns distance from point to closest point of this area ignoring z.<br>
* Returns 0 if point is inside area.
*
* @param point
* point to calculate distance from
* @return distance or 0 if is inside area
*/
double getDistance2D(Point point);
/**
* Returns distance from point to closest point of this area ignoring z.<br>
* Returns 0 point is inside area.
*
* @param x
* x coord
* @param y
* y coord
* @return distance or 0 if is inside area
*/
double getDistance2D(int x, int y);
/**
* Returns distance from point to this area.<br>
* Returns 0 if is inside.
*
* @param point
* point to check
* @return distance or 0 if is inside
*/
double getDistance3D(Point3D point);
/**
* Returns distance from coords to this area
*
* @param x
* x coord
* @param y
* y coord
* @param z
* z coord
* @return distance or 0 if is inside
*/
double getDistance3D(int x, int y, int z);
/**
* Returns closest point of area to given point.<br>
* Returns point with coords = point arg if is inside
*
* @param point
* point to check
* @return closest point
*/
Point getClosestPoint(Point point);
/**
* Returns closest point of area to given coords.<br>
* Returns point with coords x and y if coords are inside
*
* @param x
* x coord
* @param y
* y coord
* @return closest point
*/
Point getClosestPoint(int x, int y);
/**
* Returns closest point of area to given point.<br>
* Works exactly like {@link #getClosestPoint(int, int)} if
* {@link #isInsideZ(int)} returns true.<br>
* In other case closest z edge is set as z coord.
*
* @param point
* point to check
* @return closest point of area to point
*/
Point3D getClosestPoint(Point3D point);
/**
* Returns closest point of area to given coords.<br>
* Works exactly like {@link #getClosestPoint(int, int)} if
* {@link #isInsideZ(int)} returns true.<br>
* In other case closest z edge is set as z coord.
*
* @param x
* x coord
* @param y
* y coord
* @param z
* z coord
* @return closest point of area to point
*/
Point3D getClosestPoint(int x, int y, int z);
/**
* Return minimal z of this area
*
* @return minimal z of this area
*/
int getMinZ();
/**
* Returns maximal z of this area
*
* @return maximal z of this area
*/
int getMaxZ();
}

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util.dimensional;
package com.l2jserver.util.geometry;
import org.apache.commons.math.geometry.Vector3D;
@@ -91,7 +91,7 @@ public class Coordinate {
return "Coordinate [" + vector + "]";
}
public Point toPoint() {
return new Point(this, 0);
public Point3D toPoint() {
return new Point3D(this, 0);
}
}

View File

@@ -0,0 +1,122 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util.geometry;
import com.l2jserver.util.MathUtil;
/**
* This class implements cylinder area
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CylinderArea extends AbstractArea {
/**
* Center of cylinder
*/
private final int centerX;
/**
* Center of cylinder
*/
private final int centerY;
/**
* Cylinder radius
*/
private final int radius;
/**
* Creates new cylinder with given radius
*
* @param center
* center of the circle
* @param radius
* radius of the circle
* @param minZ
* min z
* @param maxZ
* max z
*/
public CylinderArea(Point center, int radius, int minZ, int maxZ) {
this(center.x, center.y, radius, minZ, maxZ);
}
/**
* Creates new cylider with given radius
*
* @param x
* center coord
* @param y
* center coord
* @param radius
* radius of the circle
* @param minZ
* min z
* @param maxZ
* max z
*/
public CylinderArea(int x, int y, int radius, int minZ, int maxZ) {
super(minZ, maxZ);
this.centerX = x;
this.centerY = y;
this.radius = radius;
}
@Override
public boolean isInside2D(int x, int y) {
return MathUtil.getDistance(centerX, centerY, x, y) < radius;
}
@Override
public double getDistance2D(int x, int y) {
if (isInside2D(x, y)) {
return 0;
} else {
return Math.abs(MathUtil.getDistance(centerX, centerY, x, y)
- radius);
}
}
@Override
public double getDistance3D(int x, int y, int z) {
if (isInside3D(x, y, z)) {
return 0;
} else if (isInsideZ(z)) {
return getDistance2D(x, y);
} else {
if (z < getMinZ()) {
return MathUtil.getDistance(centerX, centerY, getMinZ(), x, y,
z);
} else {
return MathUtil.getDistance(centerX, centerY, getMaxZ(), x, y,
z);
}
}
}
@Override
public Point getClosestPoint(int x, int y) {
if (isInside2D(x, y)) {
return new Point(x, y);
} else {
int vX = x - this.centerX;
int vY = y - this.centerY;
double magV = MathUtil.getDistance(centerX, centerY, x, y);
double pointX = centerX + vX / magV * radius;
double pointY = centerY + vY / magV * radius;
return new Point((int) Math.round(pointX), (int) Math.round(pointY));
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util.geometry;
/**
* An two dimensional point
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Point {
/**
* The X axis
*/
public final int x;
/**
* The Y axis
*/
public final int y;
/**
* Creates a new two dimensional point
*
* @param x
* the x axis
* @param y
* the y axis
*/
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public static final Point fromXY(int x, int y) {
return new Point(x, y);
}
}

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util.dimensional;
package com.l2jserver.util.geometry;
/**
* An point is composed of an Coordinate and an angle. The angle represents the
@@ -22,7 +22,7 @@ package com.l2jserver.util.dimensional;
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Point {
public class Point3D {
/**
* The point coordinate
*/
@@ -40,14 +40,28 @@ public class Point {
* @param angle
* the angle
*/
public Point(Coordinate coordinate, double angle) {
public Point3D(Coordinate coordinate, double angle) {
this.coordinate = coordinate;
this.angle = angle;
}
/**
* Creates a new point with 3 axis
*
* @param x
* the x axis
* @param y
* the y axis
* @param z
* the z axis
*/
public Point3D(int x, int y, int z) {
this(new Coordinate(x, y, z), 0);
}
/**
* @return the x
* @see com.l2jserver.util.dimensional.Coordinate#getX()
* @see com.l2jserver.util.geometry.Coordinate#getX()
*/
public int getX() {
return coordinate.getX();
@@ -55,7 +69,7 @@ public class Point {
/**
* @return the y
* @see com.l2jserver.util.dimensional.Coordinate#getY()
* @see com.l2jserver.util.geometry.Coordinate#getY()
*/
public int getY() {
return coordinate.getY();
@@ -63,7 +77,7 @@ public class Point {
/**
* @return the z
* @see com.l2jserver.util.dimensional.Coordinate#getZ()
* @see com.l2jserver.util.geometry.Coordinate#getZ()
*/
public int getZ() {
return coordinate.getZ();
@@ -73,7 +87,7 @@ public class Point {
* @param other
* the other coordinate
* @return the distance
* @see com.l2jserver.util.dimensional.Coordinate#getDistance(com.l2jserver.util.dimensional.Coordinate)
* @see com.l2jserver.util.geometry.Coordinate#getDistance(com.l2jserver.util.geometry.Coordinate)
*/
public double getDistance(Coordinate other) {
return coordinate.getDistance(other);
@@ -83,9 +97,9 @@ public class Point {
* @param other
* the other point
* @return the distance
* @see com.l2jserver.util.dimensional.Coordinate#getDistance(com.l2jserver.util.dimensional.Coordinate)
* @see com.l2jserver.util.geometry.Coordinate#getDistance(com.l2jserver.util.geometry.Coordinate)
*/
public double getDistance(Point other) {
public double getDistance(Point3D other) {
return coordinate.getDistance(other.coordinate);
}
@@ -114,10 +128,10 @@ public class Point {
* the z point
* @param angle
* the angle
* @return the new {@link Point} object created
* @return the new {@link Point3D} object created
*/
public static Point fromXYZA(int x, int y, int z, double angle) {
return new Point(Coordinate.fromXYZ(x, y, z), angle);
public static Point3D fromXYZA(int x, int y, int z, double angle) {
return new Point3D(Coordinate.fromXYZ(x, y, z), angle);
}
/**
@@ -129,9 +143,9 @@ public class Point {
* the y point
* @param z
* the z point
* @return the new {@link Point} object created
* @return the new {@link Point3D} object created
*/
public static Point fromXYZ(int x, int y, int z) {
public static Point3D fromXYZ(int x, int y, int z) {
return fromXYZA(x, y, z, 0);
}
}

View File

@@ -0,0 +1,155 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util.geometry;
import java.awt.Polygon;
import java.util.Collection;
import com.l2jserver.util.MathUtil;
/**
* Area of free form
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class PolygonArea extends AbstractArea {
/**
* Collection of x points
*/
private final int[] xPoints;
/**
* Collection of y points
*/
private final int[] yPoints;
/**
* Polygon used to calculate isInside()
*/
private final Polygon poly;
/**
* Creates new area from given points
*
* @param points
* list of points
* @param zMin
* minimal z
* @param zMax
* maximal z
*/
public PolygonArea(Collection<Point> points, int zMin, int zMax) {
this(points.toArray(new Point[points.size()]), zMin, zMax);
}
/**
* Creates new area from given points
*
* @param points
* list of points
* @param zMin
* minimal z
* @param zMax
* maximal z
*/
public PolygonArea(Point[] points, int zMin, int zMax) {
super(zMin, zMax);
if (points.length < 3) {
throw new IllegalArgumentException(
"Not enough points, needed at least 3 but got "
+ points.length);
}
this.xPoints = new int[points.length];
this.yPoints = new int[points.length];
Polygon polygon = new Polygon();
for (int i = 0, n = points.length; i < n; i++) {
Point p = points[i];
polygon.addPoint(p.x, p.y);
xPoints[i] = p.x;
yPoints[i] = p.y;
}
this.poly = polygon;
}
@Override
public boolean isInside2D(int x, int y) {
return poly.contains(x, y);
}
@Override
public double getDistance2D(int x, int y) {
if (isInside2D(x, y)) {
return 0;
} else {
Point cp = getClosestPoint(x, y);
return MathUtil.getDistance(cp.x, cp.y, x, y);
}
}
@Override
public double getDistance3D(int x, int y, int z) {
if (isInside3D(x, y, z)) {
return 0;
} else if (isInsideZ(z)) {
return getDistance2D(x, y);
} else {
Point3D cp = getClosestPoint(x, y, z);
return MathUtil.getDistance(cp.getX(), cp.getY(), cp.getZ(), x, y,
z);
}
}
@Override
public Point getClosestPoint(int x, int y) {
Point closestPoint = null;
double closestDistance = 0;
for (int i = 0; i < xPoints.length; i++) {
int nextIndex = i + 1;
if (nextIndex == xPoints.length) {
nextIndex = 0;
}
int p1x = xPoints[i];
int p1y = yPoints[i];
int p2x = xPoints[nextIndex];
int p2y = yPoints[nextIndex];
Point point = MathUtil.getClosestPointOnSegment(p1x, p1y, p2x, p2y,
x, y);
if (closestPoint == null) {
closestPoint = point;
closestDistance = MathUtil.getDistance(closestPoint.x,
closestPoint.y, x, y);
} else {
double newDistance = MathUtil.getDistance(point.x, point.y, x,
y);
if (newDistance < closestDistance) {
closestPoint = point;
closestDistance = newDistance;
}
}
}
return closestPoint;
}
}

View File

@@ -0,0 +1,177 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util.geometry;
import java.awt.Rectangle;
import com.l2jserver.util.MathUtil;
/**
* Rectangle area, most wide spread in the game
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class RectangleArea extends AbstractArea {
/**
* Min x point
*/
private final int minX;
/**
* Max x point
*/
private final int maxX;
/**
* Min y point
*/
private final int minY;
/**
* Max y point
*/
private final int maxY;
/**
* Creates new area from given points. Point order doesn't matter
*
* @param p1
* point
* @param p2
* point
* @param p3
* point
* @param p4
* point
* @param minZ
* minimal z
* @param maxZ
* maximal z
*/
public RectangleArea(Point p1, Point p2, Point p3, Point p4, int minZ,
int maxZ) {
super(minZ, maxZ);
// we should use a better way to do this
Rectangle r = new Rectangle();
r.add(new java.awt.Point(p1.x, p1.y));
r.add(new java.awt.Point(p2.x, p2.y));
r.add(new java.awt.Point(p3.x, p3.y));
r.add(new java.awt.Point(p4.x, p4.y));
minX = (int) r.getMinX();
maxX = (int) r.getMaxX();
minY = (int) r.getMinY();
maxY = (int) r.getMaxY();
}
/**
* Creates new are from given coords
*
* @param minX
* mimal x point
* @param minY
* minimal y point
* @param maxX
* maximal x point
* @param maxY
* maximal y point
* @param minZ
* minimal z point
* @param maxZ
* maximal z point
*/
public RectangleArea(int minX, int minY, int maxX, int maxY, int minZ,
int maxZ) {
super(minZ, maxZ);
this.minX = minX;
this.maxX = maxX;
this.minY = minY;
this.maxY = maxY;
}
@Override
public boolean isInside2D(int x, int y) {
return x >= minX && x <= maxX && y >= minY && y <= maxY;
}
@Override
public double getDistance2D(int x, int y) {
if (isInside2D(x, y)) {
return 0;
} else {
Point cp = getClosestPoint(x, y);
return MathUtil.getDistance(x, y, cp.x, cp.y);
}
}
@Override
public double getDistance3D(int x, int y, int z) {
if (isInside3D(x, y, z)) {
return 0;
} else if (isInsideZ(z)) {
return getDistance2D(x, y);
} else {
Point3D cp = getClosestPoint(x, y, z);
return MathUtil.getDistance(x, y, z, cp.getX(), cp.getY(),
cp.getZ());
}
}
@Override
public Point getClosestPoint(int x, int y) {
if (isInside2D(x, y)) {
return new Point(x, y);
} else {
// bottom edge
Point closestPoint = MathUtil.getClosestPointOnSegment(minX, minY,
maxX, minY, x, y);
double distance = MathUtil.getDistance(x, y, closestPoint.x,
closestPoint.y);
// top edge
Point cp = MathUtil.getClosestPointOnSegment(minX, maxY, maxX,
maxY, x, y);
double d = MathUtil.getDistance(x, y, cp.x, cp.y);
if (d < distance) {
closestPoint = cp;
distance = d;
}
// left edge
cp = MathUtil
.getClosestPointOnSegment(minX, minY, minX, maxY, x, y);
d = MathUtil.getDistance(x, y, cp.x, cp.y);
if (d < distance) {
closestPoint = cp;
distance = d;
}
// Right edge
cp = MathUtil
.getClosestPointOnSegment(maxX, minY, maxX, maxY, x, y);
d = MathUtil.getDistance(x, y, cp.x, cp.y);
if (d < distance) {
closestPoint = cp;
// distance = d;
}
return closestPoint;
}
}
}

View File

@@ -19,7 +19,7 @@ package com.l2jserver.util.jaxb;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.l2jserver.util.dimensional.Coordinate;
import com.l2jserver.util.geometry.Coordinate;
import com.l2jserver.util.jaxb.CoordinateAdapter.CoordinateElement;
/**