package org.mortbay.ijetty.component;
import org.mortbay.ijetty.AppConstants;
import org.mortbay.ijetty.util.LogUtil;
import android.graphics.Rect;
public class Polygon {
public static final double SIN_30 = Math.sin(Math.PI / 6);
public static final double SIN_60 = Math.sin(Math.PI / 3);
private Point[] points = new Point[6];
private double a = 0.0D;
private int w, h;
public Point[] getPoints() {
return points;
}
public Polygon() {
this.a = AppConstants.a;
this.w = AppConstants.w;
this.h = AppConstants.h;
for (int i = 0; i < points.length; i++)
points[i] = new Point(0, 0);
points[0].x = (int) (a * SIN_30);
points[1].x = 0;
points[2].x = (int) (a * SIN_30);
points[3].x = (int) (a + a * SIN_30);
points[4].x = (int) (a + 2 * a * SIN_30);
points[5].x = (int) (a + a * SIN_30);
points[0].y = 0;
points[1].y = (int) (a * SIN_60);
points[2].y = (int) (2 * a * SIN_60);
points[3].y = (int) (2 * a * SIN_60);
points[4].y = (int) (a * SIN_60);
points[5].y = 0;
}
/**
* 获得Logo图片矩形区域
*
* @return 矩形区域
*/
public Rect getLogoRect() {
return new Rect((int) (a * SIN_30 / 2), (int) (a * SIN_60 / 2),
(int) ((a * SIN_30 / 2) + (((double) w) / 2)), (int) ((a
* SIN_60 / 2) + (((double) h) / 2)));
}
/**
* 通过宽高获得边长
*
* @param w
* 宽度
* @param h
* 高度
* @return 边长
*/
public static double getPreferredSideLen(int w, int h) {
double width = (double) w;
double height = (double) h;
return Math.min(width / (1 + 2 * SIN_30), height / (2 * SIN_60));
}
/**
* 通过宽度获得边长
*
* @param w
* 宽度
* @return 边长
*/
public static double getPreferredSideLen(int w) {
double width = (double) w;
return (width / (1 + 2 * SIN_30));
}
/**
* 通过高度获得宽度
*
* @param h
* 高度
* @return 宽度
*/
public static int getPreferredWidth(int h) {
double height = (double) h;
double width = (height * (1 + 2 * SIN_30)) / (2 * SIN_60);
return (int) width;
}
/**
* 通过宽度获得高度
*
* @param w
* 宽度
* @return 高度
*/
public static int getPreferredHeight(int w) {
double width = (double) w;
double height = (2 * width * SIN_60) / ((1 + 2 * SIN_30));
return (int) height;
}
/**
* 判断某个点是否在三角形区域内
*
* @param a
* 三角形一点
* @param b
* 三角形一点
* @param c
* 三角形一点
* @param p
* 待判断的点
* @return 点是否在三角形内
*/
public static boolean checkPointInTriangle(Point a, Point b, Point c,
Point p) {
double abc = triangleArea(a, b, c);
double abp = triangleArea(a, b, p);
double acp = triangleArea(a, c, p);
double bcp = triangleArea(b, c, p);
Boolean retFlag = false;
if (abc == abp + acp + bcp) {
retFlag = true;
} else {
retFlag = false;
}
return retFlag;
}
/**
* 求三角形的面积
*
* @param a
* 三角形一点
* @param b
* 三角形一点
* @param c
* 三角形一点
* @return 三角形面积
*/
private static double triangleArea(Point a, Point b, Point c) {
double result = Math.abs((a.x * b.y + b.x * c.y + c.x * a.y - b.x * a.y
- c.x * b.y - a.x * c.y) / 2.0D);
return result;
}
/**
* 判断点是否在矩形区域内
*
* @param a
* 矩形左上角坐标
* @param b
* 矩形右下角坐标
* @param p
* 待判断的点
* @return 点是否在矩形内
*/
private static boolean checkPointInRectangle(Point a, Point b, Point p) {
int x = p.x;
int y = p.y;
Boolean retFlag = false;
if (x >= a.x && x <= b.x) {
if (y >= a.y && y <= b.y)
retFlag = true;
}
return retFlag;
}
/**
* 判断点是否在当前对象所在六边形内
*
* @param p
* 待判断的点
* @return 点是否在六边形内
*/
public boolean checkPointInHexagon(Point p) {
int x = p.x, y = p.y;
if (x < 0 || x > w)
return false;
if (y < 0 || y > h)
return false;
if (x <= points[0].x)
return checkPointInTriangle(points[0], points[1], points[2], p);
else if (x <= points[3].x)
return checkPointInRectangle(points[0], points[3], p);
else if (x <= points[4].x)
return checkPointInTriangle(points[3], points[4], points[5], p);
return false;
}
public int getW() {
return w;
}
public int getH() {
return h;
}
/**
* 获得六边形左上角的点坐标
*
* @param w
* 宽度
* @param h
* 高度
* @param a
* 边长
* @param row
* 行
* @param col
* 列
* @return 六边形左上角点的坐标
*/
public static Point getLocationPoint(int w, int h, double a, int row,
int col) {
Point p = new Point();
int x = 0, y = 0;
boolean vFlag = false;
vFlag = (col>0);
if (vFlag) {
if ((col % 2) == 0) {
x = (int) ((w + a) * (col / 2));
y = row * h - h / 2;
} else {
x = (int) (((w + a) * (col / 2) + (a * SIN_30 + a)));
y = (2 * row + 1) * h / 2 - h / 2;
}
}else{
col = Math.abs(col);
if ((col % 2) == 0) {
x = (int) ((w + a) * (col / 2));
y = row * h - h / 2;
} else {
x = (int) (((w + a) * (col / 2) + (a * SIN_30 + a)));
y = (2 * row + 1) * h / 2 - h / 2;
}
x=-x;
}
x-=(w+a);
p.x = x;
p.y = y;
return p;
}
/**
* 通过所在行列获得ID
*
* @param row
* 行
* @param col
* 列
* @return 唯一ID
*/
public static int getIDByRowCol(int row, int col) {
return (1000000000 + 100000 * col + row);
}
/**
* 通过高度初始化六边形的长,宽,边长
* @param height 指定的高度
*/
public static void initSize(int height) {
AppConstants.w = Polygon.getPreferredWidth(height);
AppConstants.a = Polygon.getPreferredSideLen(AppConstants.w);
AppConstants.h = height;
LogUtil.log("application initSize " + AppConstants.a + " "
+ AppConstants.w + " " + AppConstants.h);
}
}