正六边形:判断点是否在正六边形内

 前文 正六边形:平铺中函数

//根据坐标计算网格信息
Vec2 HelloWorld::getGridByPos(const Vec2& pos)
{
	int girdX = pos.x/ (1.5 * sideLen)+0.5;
	int girdY = 0;
	if (girdX % 2 == 0)
	{
		girdY = pos.y / (sideLen * sqrt3) + 0.5;
	}
	else
	{
		girdY = pos.y / (sideLen * sqrt3) + 1;
	}
	return Vec2(girdX, girdY);
}

逻辑存在BUG,处于边界时计算有误,需要判断点是否在正六边形内进行纠偏处理。

如何判断点是否在正六边形内?

把正六边形分解,将问题转换为,点是否在矩形IGDJ或三角形GCD内;

 

设dx,dy分别为点到正六边形中心点的差值【>=0】,

若点在矩形内,则dx必然在IG区间【dx<1】且dy在IJ区间【dy<1.73】

若点在三角形内,则dx必然在GC区间【1<dx<2】且dy在DC线的下方【以G点为原点,DC线的坐标关系描述为y= -1.73x+1.73】

代码实现如下:

const int cubeSideLen = 2;
const int halfSideLen = cubeSideLen * 0.5;
const double mathSqrt3 = 1.732051;
const double cubeSideLen_X_mathSqrt3 = cubeSideLen * mathSqrt3;

class Grid
{
public:
	Grid() {}
	Grid(int x, int y, int z = 0) {
		this->x = x;
		this->y = y;
		this->z = z;
	}

	int x = 0;
	int y = 0;
	int z = 0;
	
	//六边形中心坐标
	double posX = 0;
	double posY = 0;

	//指定坐标是否在六边形内
	bool posInGrid(const double &posX, const double &posY) 
	{
		double dx = std::abs(this->posX - posX);
		double dy = std::abs(this->posY - posY);
		if (dx <= halfSideLen)
		{
			return dy <= halfSideLen * mathSqrt3;
		}
		else
		{
			int maxY = -mathSqrt3 * (dx - halfSideLen) + halfSideLen * mathSqrt3;
			return dy < maxY;
		}
	}
};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要生成六边形的经纬度信息,可以按照以下步骤: 1. 定义六边形的中心点的经纬度坐标。 2. 计算六边形每个顶点的经纬度坐标。可以根据六边形的半径和中心点的经纬度坐标,使用弦余弦函数来计算。 3. 将六边形的顶点按照顺序连接起来,形成一个多边形。 以下是示例代码,用于在指定经纬度范围内生成六边形的经纬度信息: ```java public class HexagonGenerator { private static final double R = 6371; // 地球半径,单位 km public static List<LatLng> generate(double centerLat, double centerLng, double radius) { List<LatLng> hexagonVertices = new ArrayList<>(); // 计算六边形每个顶点的经纬度坐标 for (int i = 0; i < 6; i++) { double angle = Math.PI / 3 * i; double vertexLat = Math.asin(Math.sin(centerLat) * Math.cos(radius / R) + Math.cos(centerLat) * Math.sin(radius / R) * Math.cos(angle)); double vertexLng = centerLng + Math.atan2(Math.sin(angle) * Math.sin(radius / R) * Math.cos(centerLat), Math.cos(radius / R) - Math.sin(centerLat) * Math.sin(vertexLat)); hexagonVertices.add(new LatLng(vertexLat, vertexLng)); } // 将六边形的顶点按照顺序连接起来,形成一个多边形 hexagonVertices.add(hexagonVertices.get(0)); // 将第一个顶点添加到最后,形成闭合的多边形 return hexagonVertices; } } ``` 其中,`LatLng` 是一个自定义的类,用于表示经纬度坐标。在本示例中,假设我们已经有了一个 `LatLngBounds` 类型的对象,表示了指定的经纬度范围。可以使用以下代码来生成覆盖该范围的所有六边形的经纬度信息: ```java public class HexagonCover { private static final double HEXAGON_RADIUS = 5; // 六边形半径,单位 km public static List<List<LatLng>> generate(LatLngBounds bounds) { List<List<LatLng>> hexagonCover = new ArrayList<>(); double latStep = HEXAGON_RADIUS / (R * Math.PI / 180); // 纬度方向上每隔多少度生成一个六边形 double lngStep = HEXAGON_RADIUS / (R * Math.PI / 180 * Math.cos(bounds.getCenter().getLat())); // 经度方向上每隔多少度生成一个六边形 double startLat = Math.floor(bounds.getSouthWest().getLat() / latStep) * latStep; double startLng = Math.floor(bounds.getSouthWest().getLng() / lngStep) * lngStep; for (double lat = startLat; lat <= bounds.getNorthEast().getLat(); lat += latStep) { for (double lng = startLng; lng <= bounds.getNorthEast().getLng(); lng += lngStep) { List<LatLng> hexagonVertices = HexagonGenerator.generate(lat, lng, HEXAGON_RADIUS); if (isPolygonIntersectingBounds(hexagonVertices, bounds)) { hexagonCover.add(hexagonVertices); } } } return hexagonCover; } // 判断多边形是否与指定的经纬度范围相交 private static boolean isPolygonIntersectingBounds(List<LatLng> polygonVertices, LatLngBounds bounds) { for (LatLng vertex : polygonVertices) { if (!bounds.contains(vertex)) { return false; } } return true; } } ``` 以上代码中,`HexagonCover.generate()` 方法用于生成覆盖指定经纬度范围内所有六边形的经纬度信息,返回一个 `List<List<LatLng>>` 对象,其中每个元素表示一个六边形的顶点经纬度坐标列表。`isPolygonIntersectingBounds()` 方法用于判断一个多边形是否与指定的经纬度范围相交。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值