/*
* This file is part of aion-emu <aion-emu.com>.
*
* aion-emu 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.
*
* aion-emu 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 aion-emu. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aionemu.gameserver.model.geometry;
import java.awt.Point;
import java.awt.Rectangle;
import com.aionemu.gameserver.utils.MathUtil;
/**
* Rectangle area, most wide spread in the game
*
* @author SoulKeeper
*/
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);
Rectangle r = new Rectangle();
r.add(p1);
r.add(p2);
r.add(p3);
r.add(p4);
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;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isInside2D(int x, int y)
{
return x >= minX && x <= maxX && y >= minY && y <= maxY;
}
/**
* {@inheritDoc}
*/
@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);
}
}
/**
* {@inheritDoc}
*/
@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());
}
}
/**
* {@inheritDoc}
*/
@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;
}
}
}