//======================================================================================================== public void Test(FPoint p0, Vector2 n0) { int y_idx = (int)(p0.y / 64); int x_idx = (int)(p0.x / 64); if (y_idx >= 0 && y_idx < topo.num_Y_grids && x_idx >= 0 && x_idx < topo.num_X_grids) { Grid g = topo.grids[y_idx, x_idx]; for (int i = 0; i < g.num_polys; i++) { Polygon p = g.polygons[i]; foreach (Border b in p.borders) { if (p0.Equals(b.from)) { //shit,原来是个顶点 return; } Vector2 d = GetV2FromBorder(b); Vector2 test = GetV2(p0) - GetV2(b.from); //decimal t1 = (decimal)test.X / (decimal)d.X; //decimal t2 = (decimal)test.Y / (decimal)d.Y; //以下全错! long dx = (long)(test.X * 10000) / (long)(d.X * 10000); long dy = (long)(test.Y * 10000) / (long)(d.Y * 10000); double ddx = ((double)dx) / 10000; if (dx == dy && ddx > 0 && ddx < 1) //b.from、p0、b.to三点共线 { //判断Vector2.Ccw(b,n0)的符号,belong/neighbor得到polygon Vector2 vb = GetV2FromBorder(b); int poly_idx; if (Vector2.Ccw(vb, n0) > 0) { poly_idx = b.belong_poly; } else { poly_idx = b.neighbor_poly; } return; } } //if (g.polygons[i].IsWithin(test_p)) // g.poly_idxs[i]; } } }
//======================================================================================================== public void LOS_Engine(FPoint from, FPoint to) { int srcp = topo.SelectPolygon(from.x, from.y); int dstp = topo.SelectPolygon(to.x, to.y); if (srcp == -1 || dstp == -1) { return; } if (!topo.polys[srcp].enterable || !topo.polys[dstp].enterable) { return; } lfp.Add(from); if (srcp == dstp) { lfp.Add(to); return; } Vector2 n0 = GetV2(from, to); n0.Normalize(); TestBorderCall(from, n0, topo.polys[srcp]); do { switch (ret.result) { case RESULT.TEST_BORDER: TestVertexPolygon(ret.p0, ret.n0, ret.poly); break; case RESULT.TEST_VERTEX: TestPureVertex(ret.p0, ret.n0); break; } //以下是检测LOS是否可终止 Polygon dst = topo.polys[dstp]; switch (ret.result) { case RESULT.TEST_BORDER: if (ret.poly == dst) { lfp.Add(to); return; } break; case RESULT.TEST_VERTEX: FPoint fp = lfp[lfp.Count - 1]; foreach (Border b in dst.borders) { if (fp.Equals(b.from)) { lfp.Add(to); return; } } break; } } while (ret.result != RESULT.TEST_END); }