我在本教程中使用了六边形代码,并创建了一个createHex类(我应该发布代码吗?)。链接的网页已使用以下代码通过createHex中的数学运算实际绘制六边形:
@Override
public void paint(Graphics g){
for(int j = 0; int j < BOARD_HEIGHT; j++){
for(int i = 0; i < BOARD_HEIGHT; I++){
mCellMetrics.setCellIndex(i, j);
if(mCells[j][i] != 0){
mCellMetrics.computeCorners(mCornersX, mCornersY);
g.setColor((mCells[j][i] == L_ON) ? COLOR.ORANGE):COLOR.GRAY;
g.fillPolygon(mCornersX, mCornersY, NUM_HEX_CORNERS);
g.setColor(COLOR.BLACK)
g.drawPolygon(mCornersX, mCornersY, NUM_HEX_CORNERS);
}
}
}
}
我遇到的问题是Android没有包含所有必需方法的Graphics类。我在android文档上做了大约一个半小时的钓鱼,而我发现最接近的东西是Path类,但是它没有我需要的方法。我想在顶部的链接文章中使用六边形代码,但找不到等效的图形类。如果没有等效项,有人可以告诉我如何使用链接的代码获得所需的结果吗?
我的问题:如何将链接文章中的代码移植到android?
编辑:
我决定,如果我包括计算六边形的边和什么的六边形代码,可能对其他人(和潜在的回答者)有帮助,所以这里是createHex.java:
package com.rush;
/**
* Uniform hexagonal grid cell's metrics utility class.
*/
public class HexGridCell {
private static final int[] NEIGHBORS_DI = { 0, 1, 1, 0, -1, -1 };
private static final int[][] NEIGHBORS_DJ = {
{ -1, -1, 0, 1, 0, -1 }, { -1, 0, 1, 1, 1, 0 } };
private final int[] CORNERS_DX; // array of horizontal offsets of the cell's corners
private final int[] CORNERS_DY; // array of
vertical offsets of the cell's corners
private final int SIDE;
private int mX = 0; // cell's left coordinate
private int mY = 0; // cell's top coordinate
private int mI = 0; // cell's horizontal grid coordinate
private int mJ = 0; // cell's vertical grid coordinate
/**
* Cell radius (distance from center to one of the corners)
*/
public final int RADIUS;
/**
* Cell height
*/
public final int HEIGHT;
/**
* Cell width
*/
public final int WIDTH;
public static final int NUM_NEIGHBORS = 6;
/**
* @param radius Cell radius (distance from the center to one of the corners)
*/
public HexGridCell(int radius) {
RADIUS = radius;
WIDTH = radius * 2;
HEIGHT = (int) (((float) radius) * Math.sqrt(3));
SIDE = radius * 3 / 2;
int cdx[] = { RADIUS / 2, SIDE, WIDTH, SIDE, RADIUS / 2, 0 };
CORNERS_DX = cdx;
int cdy[] = { 0, 0, HEIGHT / 2, HEIGHT, HEIGHT, HEIGHT / 2 };
CORNERS_DY = cdy;
}
/**
* @return X coordinate of the cell's top left corner.
*/
public int getLeft() {
return mX;
}
/**
* @return Y coordinate of the cell's top left corner.
*/
public int getTop() {
return mY;
}
/**
* @return X coordinate of the cell's center
*/
public int getCenterX() {
return mX + RADIUS;
}
/**
* @return Y coordinate of the cell's center
*/
public int getCenterY() {
return mY + HEIGHT / 2;
}
/**
* @return Horizontal grid coordinate for the cell.
*/
public int getIndexI() {
return mI;
}
/**
* @return Vertical grid coordinate for the cell.
*/
public int getIndexJ() {
return mJ;
}
/**
* @return Horizontal grid coordinate for the given neighbor.
*/
public int getNeighborI(int neighborIdx) {
return mI + NEIGHBORS_DI[neighborIdx];
}
/**
* @return Vertical grid coordinate for the given neighbor.
*/
public int getNeighborJ(int neighborIdx) {
return mJ + NEIGHBORS_DJ[mI % 2][neighborIdx];
}
/**
* Computes X and Y coordinates for all of the cell's 6 corners, clockwise,
* starting from the top left.
*
* @param cornersX Array to fill in with X coordinates of the cell's corners
* @param cornersX Array to fill in with Y coordinates of the cell's corners
*/
public void computeCorners(int[] cornersX, int[] cornersY) {
for (int k = 0; k < NUM_NEIGHBORS; k++) {
cornersX[k] = mX + CORNERS_DX[k];
cornersY[k] = mY + CORNERS_DY[k];
}
}
/**
* Sets the cell's horizontal and vertical grid coordinates.
*/
public void setCellIndex(int i, int j) {
mI = i;
mJ = j;
mX = i * SIDE;
mY = HEIGHT * (2 * j + (i % 2)) / 2;
}
/**
* Sets the cell as corresponding to some point inside it (can be used for
* e.g. mouse picking).
*/
public void setCellByPoint(int x, int y) {
int ci = (int)Math.floor((float)x/(float)SIDE);
int cx = x - SIDE*ci;
int ty = y - (ci % 2) * HEIGHT / 2;
int cj = (int)Math.floor((float)ty/(float)HEIGHT);
int cy = ty - HEIGHT*cj;
if (cx > Math.abs(RADIUS / 2 - RADIUS * cy / HEIGHT)) {
setCellIndex(ci, cj);
} else {
setCellIndex(ci - 1, cj + (ci % 2) - ((cy < HEIGHT / 2) ? 1 :
0));
}
}
}
有关代码如何工作的说明,请参阅链接的文章。
试试这个:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Region;
import android.util.AttributeSet;
import android.view.View;
public class HexagonMaskView extends View {
private Path hexagonPath;
private Path hexagonBorderPath;
private float radius;
private float width, height;
private int maskColor;
public HexagonMaskView(Context context) {
super(context);
init();
}
public HexagonMaskView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public HexagonMaskView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
hexagonPath = new Path();
hexagonBorderPath = new Path();
maskColor = 0xFF01FF77;
}
public void setRadius(float r) {
this.radius = r;
calculatePath();
}
public void setMaskColor(int color) {
this.maskColor = color;
invalidate();
}
private void calculatePath() {
float triangleHeight = (float) (Math.sqrt(3) * radius / 2);
float centerX = width/2;
float centerY = height/2;
hexagonPath.moveTo(centerX, centerY + radius);
hexagonPath.lineTo(centerX - triangleHeight, centerY + radius/2);
hexagonPath.lineTo(centerX - triangleHeight, centerY - radius/2);
hexagonPath.lineTo(centerX, centerY - radius);
hexagonPath.lineTo(centerX + triangleHeight, centerY - radius/2);
hexagonPath.lineTo(centerX + triangleHeight, centerY + radius/2);
hexagonPath.moveTo(centerX, centerY + radius);
float radiusBorder = radius - 5;
float triangleBorderHeight = (float) (Math.sqrt(3) * radiusBorder / 2);
hexagonBorderPath.moveTo(centerX, centerY + radiusBorder);
hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY + radiusBorder/2);
hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY - radiusBorder/2);
hexagonBorderPath.lineTo(centerX, centerY - radiusBorder);
hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY - radiusBorder/2);
hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY + radiusBorder/2);
hexagonBorderPath.moveTo(centerX, centerY + radiusBorder);
invalidate();
}
@Override
public void onDraw(Canvas c){
super.onDraw(c);
c.clipPath(hexagonBorderPath, Region.Op.DIFFERENCE);
c.drawColor(Color.WHITE);
c.save();
c.clipPath(hexagonPath, Region.Op.DIFFERENCE);
c.drawColor(maskColor);
c.save();
}
// getting the view size and default radius
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
radius = height / 2 - 10;
calculatePath();
}
}
我似乎在绘制正确的十六进制网格时遇到了一点麻烦: 正如您所看到的,六边形只是稍微不对齐,尽管我相信我的数学是正确的(其中一些可以通过http://www.redblobgames.com/grids/hexagons/进行验证)。 我的绘制方法是从左上六边形(第一行的第一个瓷砖)开始,绘制那一行瓷砖。然后对于下一行,有一个负X偏移量和正Y偏移量等,直到它到达中间行,在中间行X偏移量增加,直到0:
我以前做了几个实验,以找到绘制大规模六边形网格的最佳方法。 我尝试使用、绘制hexes。它在小网格中工作得很好,但如果我在一个网格中有超过1000+的单元格,fps就开始很难下降。 所以我想出了这个想法,将纹理(包含六边形网格模式)应用到一个简单的平面上。我只需要设置纹理的函数来指定垂直和水平执行多少次重复。
我想在Google Map V2的地图上画一个徒手多边形。 这项任务可以在地图V1中完成,但Google地图已经从V2中删除了该类。(根据此Google Map V2具有删除覆盖类)。 Google Map V1绘制自由风格多边形的好例子。 在Map V2中,我们可以借助Google官方文档以编程方式绘制多边形,但用户应该怎么做?我发现Map V2的答案不清楚 我从简单的谷歌地图开始 我在这个主题
问题内容: 我刚接触Android,并且一直在研究Canvas。我正在尝试绘制箭头,但是在绘制轴时运气不好,没有一个箭头在起作用。 我进行了一些搜索,找到一个Java示例,但是Android没有or 。 现在,我的代码如下所示(箭头看上去完全不像箭头): 我查看了以下线程以获取指导: * http://www.java-forums.org/awt-swing/6241-how-u-rotate-
我需要在Mapbox Android SDK地图上绘制一个带孔的GeoJSON多边形。 正如GeoJSON规范所说, 对于类型“多边形”,“坐标”成员必须是线性环坐标数组的数组。对于有多个环的多边形,第一个必须是外环,其他必须是内环或孔。 在手册Mapbox JS和Mapbox GL JS中,加载GeoJSONs由库本身处理。从这把小提琴中可以看出,lib考虑了内环,因此正确地绘制了孔。 当我查看