static void test_reach(const RasterMap& map, fixed mwind, fixed mc) { GlideSettings settings; settings.SetDefaults(); GlidePolar polar(mc); SpeedVector wind(Angle::Degrees(0), mwind); TerrainRoute route; route.UpdatePolar(settings, polar, polar, wind); route.SetTerrain(&map); GeoPoint origin(map.GetMapCenter()); fixed pd = map.PixelDistance(origin, 1); printf("# pixel size %g\n", (double)pd); bool retval= true; short horigin = map.GetHeight(origin)+1000; AGeoPoint aorigin(origin, RoughAltitude(horigin)); RoutePlannerConfig config; config.SetDefaults(); retval = route.SolveReach(aorigin, config, RoughAltitude::Max()); ok(retval, "reach solve", 0); PrintHelper::print_reach_tree(route); GeoPoint dest(origin.longitude-Angle::Degrees(0.02), origin.latitude-Angle::Degrees(0.02)); { Directory::Create(_T("output/results")); std::ofstream fout("output/results/terrain.txt"); unsigned nx = 100; unsigned ny = 100; for (unsigned i=0; i< nx; ++i) { for (unsigned j=0; j< ny; ++j) { fixed fx = (fixed)i / (nx - 1) * 2 - fixed(1); fixed fy = (fixed)j / (ny - 1) * 2 - fixed(1); GeoPoint x(origin.longitude + Angle::Degrees(fixed(0.6) * fx), origin.latitude + Angle::Degrees(fixed(0.6) * fy)); short h = map.GetInterpolatedHeight(x); AGeoPoint adest(x, RoughAltitude(h)); ReachResult reach; route.FindPositiveArrival(adest, reach); if ((i % 5 == 0) && (j % 5 == 0)) { AGeoPoint ao2(x, RoughAltitude(h + 1000)); route.SolveReach(ao2, config, RoughAltitude::Max()); } fout << x.longitude.Degrees() << " " << x.latitude.Degrees() << " " << h << " " << (int)reach.terrain << "\n"; } fout << "\n"; } fout << "\n"; } }
static void test_reach(const RasterMap& map, fixed mwind, fixed mc) { GlidePolar polar(mc); SpeedVector wind(Angle::degrees(fixed(0)), mwind); TerrainRoute route(polar, wind); route.set_terrain(&map); GeoPoint origin(map.GetMapCenter()); fixed pd = map.pixel_distance(origin, 1); printf("# pixel size %g\n", (double)pd); bool retval= true; route.verbose = 2; RoutePlannerConfig config; config.mode = RoutePlannerConfig::rpBoth; short horigin = map.GetHeight(origin)+1000; AGeoPoint aorigin(origin, horigin); retval = route.solve_reach(aorigin); ok(retval, "reach solve", 0); PrintHelper::print_reach_tree(route); GeoPoint dest(origin.Longitude-Angle::degrees(fixed(0.02)), origin.Latitude-Angle::degrees(fixed(0.02))); { std::ofstream fout ("results/terrain.txt"); unsigned nx = 100; unsigned ny = 100; for (unsigned i=0; i< nx; ++i) { for (unsigned j=0; j< ny; ++j) { fixed fx = (fixed)i/(nx-1)*fixed_two-fixed_one; fixed fy = (fixed)j/(ny-1)*fixed_two-fixed_one; GeoPoint x(origin.Longitude+Angle::degrees(fixed(0.6)*fx), origin.Latitude+Angle::degrees(fixed(0.6)*fy)); short h = map.GetInterpolatedHeight(x); AGeoPoint adest(x, h); short ha, hd; route.find_positive_arrival(adest, ha, hd); if ((i % 5 == 0) && (j % 5 == 0)) { AGeoPoint ao2(x, h+1000); route.solve_reach(ao2); } fout << x.Longitude.value_degrees() << " " << x.Latitude.value_degrees() << " " << h << " " << ha << "\n"; } fout << "\n"; } fout << "\n"; } }
void RasterRenderer::ScanMap(const RasterMap &map, const WindowProjection &projection) { // Coordinates of the MapWindow center unsigned x = projection.GetScreenWidth() / 2; unsigned y = projection.GetScreenHeight() / 2; // GeoPoint corresponding to the MapWindow center GeoPoint center = projection.ScreenToGeo(x, y); // GeoPoint "next to" Gmid (depends on terrain resolution) GeoPoint neighbor = projection.ScreenToGeo(x + quantisation_pixels, y + quantisation_pixels); // Geographical edge length of pixel in the MapWindow center in meters pixel_size = M_SQRT1_2 * center.DistanceS(neighbor); // set resolution if (pixel_size < 3000) { // Data point size of the (terrain) map in meters multiplied by 256 auto map_pixel_size = map.PixelDistance(center, 1); // How many screen pixels does one data point stretch? auto q = map_pixel_size / pixel_size; /* round down to reduce slope shading artefacts (caused by RasterBuffer interpolation) */ quantisation_effective = std::max(1, (int)q); /* disable slope shading when zoomed in very near (not enough terrain resolution to make a useful slope calculation) */ if (quantisation_effective > 25) quantisation_effective = 0; } else /* disable slope shading when zoomed out very far (too tiny) */ quantisation_effective = 0; #ifdef ENABLE_OPENGL bounds = projection.GetScreenBounds().Scale(1.5); bounds.IntersectWith(map.GetBounds()); height_matrix.Fill(map, bounds, projection.GetScreenWidth() / quantisation_pixels, projection.GetScreenHeight() / quantisation_pixels, true); last_quantisation_pixels = quantisation_pixels; #else height_matrix.Fill(map, projection, quantisation_pixels, true); #endif }
bool RasterWeather::LoadItem(const TCHAR* name, unsigned time_index) { TCHAR rasp_filename[MAX_PATH]; GetFilename(rasp_filename, name, time_index); RasterMap *map = new RasterMap(rasp_filename, NULL, NULL); if (!map->isMapLoaded()) { delete map; return false; } delete weather_map; weather_map = map; return true; }
void HeightMatrix::Fill(const RasterMap &map, const WindowProjection &projection, unsigned quantisation_pixels, bool interpolate) { const unsigned screen_width = projection.GetScreenWidth(); const unsigned screen_height = projection.GetScreenHeight(); SetSize((screen_width + quantisation_pixels - 1) / quantisation_pixels, (screen_height + quantisation_pixels - 1) / quantisation_pixels); minimum = 0x7fff; maximum = 0; for (unsigned y = 0; y < screen_height; y += quantisation_pixels) { const FastRowRotation rotation = projection.GetScreenAngleRotation(y - projection.GetScreenOrigin().y); short *p = data.begin() + y * width / quantisation_pixels; for (unsigned x = 0; x < screen_width; x += quantisation_pixels) { #ifndef SLOW_TERRAIN_STUFF const FastRowRotation::Pair r = rotation.Rotate(x - projection.GetScreenOrigin().x); GeoPoint gp; gp.Latitude = projection.GetGeoLocation().Latitude - projection.PixelsToAngle(r.second); gp.Longitude = projection.GetGeoLocation().Longitude + projection.PixelsToAngle(r.first) * gp.Latitude.invfastcosine(); #else GeoPoint gp = projection.ScreenToGeo(x, y); #endif short h = interpolate ? map.GetFieldInterpolated(gp) : map.GetField(gp); if (!RasterBuffer::is_special(h)) { if (h < minimum) minimum = h; if (h > maximum) maximum = h; } *p++ = h; } assert(p <= data.end()); } }
void MainWindow::createScene() //Renderer() { RasterMap *dda = new RasterMap( 40, 30, 0.1 ); dda->setPosition( -0.3, -1, -15 ); m_pRenderer->attachObject( dda ); Robot *robot = new Robot(); robot->setMovable( true ); robot->setPosition( 0, 2, -13 ); m_pRenderer->attachObject( robot, true ); WFObject *wf1 = new WFObject( "bowl.obj" ); wf1->setMaterial( "Marble" ); wf1->setTexture( "Marble" ); wf1->setPosition( -1, -2.4, -14.0 ); wf1->setMovable( true ); wf1->setRotatable( true ); wf1->setRotation( 0, 0, 0 ); m_pRenderer->attachObject( wf1 ); /* ParticleBox *ElasticPBox = new ParticleBox( 1.5, false, 0.9 ); ElasticPBox->setPosition( 3, -1, -13 ); m_pRenderer->attachObject( ElasticPBox ); ParticleBox *InelasticPBox = new ParticleBox( 1.5, true, 0.9 ); InelasticPBox->setPosition( 1, -1, -13 ); m_pRenderer->attachObject( InelasticPBox ); */ WFObject *wf2 = new WFObject( "brickwall.obj" ); wf2->setMaterial( "Wall" ); wf2->setTexture( "Wall" ); wf2->setPosition( 3.5, -2.0, -15.0 ); m_pRenderer->attachObject( wf2 ); WFObject *whiteboard = new WFObject( "whiteboard.obj" ); whiteboard->setMaterial( "Material" ); whiteboard->setTexture( "Whiteboard" ); whiteboard->setPosition( 0, -0.5, -15.1 ); m_pRenderer->attachObject( whiteboard ); WFObject *floor = new WFObject( "floor.obj" ); floor->setMaterial( "Floor" ); floor->setTexture( "Floor" ); floor->setPosition( 1.5, -2.5, -14.0 ); m_pRenderer->attachObject( floor ); }
void RasterRenderer::ScanMap(const RasterMap &map, const WindowProjection &projection) { // Coordinates of the MapWindow center unsigned x = projection.GetScreenWidth() / 2; unsigned y = projection.GetScreenHeight() / 2; // GeoPoint corresponding to the MapWindow center GeoPoint Gmid = projection.ScreenToGeo(x, y); // GeoPoint "next to" Gmid (depends on terrain resolution) GeoPoint Gneighbor = projection.ScreenToGeo(x + quantisation_pixels, y + quantisation_pixels); // Geographical edge length of pixel in the MapWindow center in meters pixel_size = fixed_sqrt_half * Gmid.Distance(Gneighbor); // set resolution fixed map_pixel_size = map.pixel_distance(Gmid, 1); fixed q = map_pixel_size / pixel_size; if (pixel_size < fixed(3000)) { /* round down to reduce slope shading artefacts (caused by RasterBuffer interpolation) */ quantisation_effective = std::max(1, (int)q); if (quantisation_effective > 25) /* disable slope shading when zoomed in very near (not enough terrain resolution to make a useful slope calculation) */ quantisation_effective = 0; } else /* disable slope shading when zoomed out very far (too tiny) */ quantisation_effective = 0; height_matrix.Fill(map, projection, quantisation_pixels, true); }
int main(int argc, char** argv) { static const char map_path[] = "tmp/map.xcm"; ZZIP_DIR *dir = zzip_dir_open(map_path, nullptr); if (dir == nullptr) { fprintf(stderr, "Failed to open %s\n", map_path); return EXIT_FAILURE; } RasterMap map; NullOperationEnvironment operation; if (!LoadTerrainOverview(dir, map.GetTileCache(), operation)) { fprintf(stderr, "failed to load map\n"); zzip_dir_close(dir); return EXIT_FAILURE; } map.UpdateProjection(); SharedMutex mutex; do { UpdateTerrainTiles(dir, map.GetTileCache(), mutex, map.GetProjection(), map.GetMapCenter(), 100000); } while (map.IsDirty()); zzip_dir_close(dir); plan_tests(4 + NUM_SOL); ok(test_route(28, map), "route 28", 0); return exit_status(); }
void RasterRenderer::ScanMap(const RasterMap &map, const WindowProjection &projection) { unsigned x = projection.GetScreenWidth() / 2; unsigned y = projection.GetScreenHeight() / 2; GeoPoint Gmid = projection.ScreenToGeo(x, y); pixel_size = fixed_sqrt_half * Distance(Gmid, projection.ScreenToGeo(x + quantisation_pixels, y + quantisation_pixels)); // set resolution fixed map_pixel_size = map.pixel_distance(Gmid, 1); quantisation_effective = (int)ceil(map_pixel_size / pixel_size); height_matrix.Fill(map, projection, quantisation_pixels, pixel_size * 3 < map_pixel_size * 2); }
int main(int argc, char** argv) { static const char hc_path[] = "tmp/map.xcm"; const char *map_path; if ((argc<2) || !strlen(argv[0])) { map_path = hc_path; } else { map_path = argv[0]; } ZZIP_DIR *dir = zzip_dir_open(map_path, nullptr); if (dir == nullptr) { fprintf(stderr, "Failed to open %s\n", map_path); return EXIT_FAILURE; } RasterMap map; NullOperationEnvironment operation; if (!LoadTerrainOverview(dir, map.GetTileCache(), operation)) { fprintf(stderr, "failed to load map\n"); zzip_dir_close(dir); return EXIT_FAILURE; } map.UpdateProjection(); SharedMutex mutex; do { UpdateTerrainTiles(dir, map.GetTileCache(), mutex, map.GetProjection(), map.GetMapCenter(), 100000); } while (map.IsDirty()); zzip_dir_close(dir); plan_tests(16*3); test_troute(map, 0, 0.1, 10000); test_troute(map, 0, 0, 10000); test_troute(map, 5.0, 1, 10000); return exit_status(); }
static bool test_route(const unsigned n_airspaces, const RasterMap& map) { Airspaces airspaces; setup_airspaces(airspaces, map.GetMapCenter(), n_airspaces); { std::ofstream fout("results/terrain.txt"); unsigned nx = 100; unsigned ny = 100; GeoPoint origin(map.GetMapCenter()); for (unsigned i = 0; i < nx; ++i) { for (unsigned j = 0; j < ny; ++j) { fixed fx = (fixed)i / (nx - 1) * fixed(2.0) - fixed_one; fixed fy = (fixed)j / (ny - 1) * fixed(2.0) - fixed_one; GeoPoint x(origin.longitude + Angle::Degrees(fixed(0.2) + fixed(0.7) * fx), origin.latitude + Angle::Degrees(fixed(0.9) * fy)); short h = map.GetInterpolatedHeight(x); fout << x.longitude.Degrees() << " " << x.latitude.Degrees() << " " << h << "\n"; } fout << "\n"; } fout << "\n"; } { // local scope, see what happens when we go out of scope GeoPoint p_start(Angle::Degrees(fixed(-0.3)), Angle::Degrees(fixed(0.0))); p_start += map.GetMapCenter(); GeoPoint p_dest(Angle::Degrees(fixed(0.8)), Angle::Degrees(fixed(-0.7))); p_dest += map.GetMapCenter(); AGeoPoint loc_start(p_start, RoughAltitude(map.GetHeight(p_start) + 100)); AGeoPoint loc_end(p_dest, RoughAltitude(map.GetHeight(p_dest) + 100)); AircraftState state; GlidePolar glide_polar(fixed(0.1)); AirspaceAircraftPerformanceGlide perf(glide_polar); GeoVector vec(loc_start, loc_end); fixed range = fixed(10000) + vec.distance / 2; state.location = loc_start; state.altitude = loc_start.altitude; { Airspaces as_route(airspaces, false); // dummy // real one, see if items changed as_route.synchronise_in_range(airspaces, vec.MidPoint(loc_start), range); int size_1 = as_route.size(); if (verbose) printf("# route airspace size %d\n", size_1); as_route.synchronise_in_range(airspaces, vec.MidPoint(loc_start), fixed_one); int size_2 = as_route.size(); if (verbose) printf("# route airspace size %d\n", size_2); ok(size_2 < size_1, "shrink as", 0); // go back as_route.synchronise_in_range(airspaces, vec.MidPoint(loc_end), range); int size_3 = as_route.size(); if (verbose) printf("# route airspace size %d\n", size_3); ok(size_3 >= size_2, "grow as", 0); // and again as_route.synchronise_in_range(airspaces, vec.MidPoint(loc_start), range); int size_4 = as_route.size(); if (verbose) printf("# route airspace size %d\n", size_4); ok(size_4 >= size_3, "grow as", 0); scan_airspaces(state, as_route, perf, true, loc_end); } // try the solver SpeedVector wind(Angle::Degrees(fixed(0)), fixed(0.0)); GlidePolar polar(fixed_one); GlideSettings settings; settings.SetDefaults(); AirspaceRoute route(airspaces); route.UpdatePolar(settings, polar, polar, wind); route.SetTerrain(&map); RoutePlannerConfig config; config.mode = RoutePlannerConfig::Mode::BOTH; bool sol = false; for (int i = 0; i < NUM_SOL; i++) { loc_end.latitude += Angle::Degrees(fixed(0.1)); loc_end.altitude = map.GetHeight(loc_end) + 100; route.Synchronise(airspaces, loc_start, loc_end); if (route.Solve(loc_start, loc_end, config)) { sol = true; if (verbose) { PrintHelper::print_route(route); } } else { if (verbose) { printf("# fail\n"); } sol = false; } char buffer[80]; sprintf(buffer, "route %d solution", i); ok(sol, buffer, 0); } } return true; }
static void test_troute(const RasterMap& map, fixed mwind, fixed mc, RoughAltitude ceiling) { GlideSettings settings; settings.SetDefaults(); GlidePolar polar(mc); SpeedVector wind(Angle::Degrees(0), mwind); TerrainRoute route; route.UpdatePolar(settings, polar, polar, wind); route.SetTerrain(&map); GeoPoint origin(map.GetMapCenter()); fixed pd = map.PixelDistance(origin, 1); printf("# pixel size %g\n", (double)pd); bool retval= true; { Directory::Create(_T("output/results")); std::ofstream fout ("output/results/terrain.txt"); unsigned nx = 100; unsigned ny = 100; for (unsigned i=0; i< nx; ++i) { for (unsigned j=0; j< ny; ++j) { fixed fx = (fixed)i / (nx - 1) * 2 - fixed(1); fixed fy = (fixed)j / (ny - 1) * 2 - fixed(1); GeoPoint x(origin.longitude + Angle::Degrees(fixed(0.6) * fx), origin.latitude + Angle::Degrees(fixed(0.4) * fy)); short h = map.GetInterpolatedHeight(x); fout << x.longitude.Degrees() << " " << x.latitude.Degrees() << " " << h << "\n"; } fout << "\n"; } fout << "\n"; } RoutePlannerConfig config; config.mode = RoutePlannerConfig::Mode::BOTH; unsigned i=0; for (fixed ang = fixed(0); ang < fixed_two_pi; ang += fixed(M_PI / 8)) { GeoPoint dest = GeoVector(fixed(40000.0), Angle::Radians(ang)).EndPoint(origin); short hdest = map.GetHeight(dest)+100; retval = route.Solve(AGeoPoint(origin, RoughAltitude(map.GetHeight(origin) + 100)), AGeoPoint(dest, RoughAltitude(positive(mc) ? hdest : std::max(hdest, (short)3200))), config, ceiling); char buffer[80]; sprintf(buffer,"terrain route solve, dir=%g, wind=%g, mc=%g ceiling=%d", (double)ang, (double)mwind, (double)mc, (int)ceiling); ok(retval, buffer, 0); PrintHelper::print_route(route); i++; } // polar.SetMC(fixed(0)); // route.UpdatePolar(polar, wind); }
bool PixelMap::isCollision(const RasterMap &rastermap, const IntPoint &pos1, const IntPoint &pos2, const IntRect &rect1, const IntRect &rect2, const Alignment &alignment1, const Alignment &alignment2) const { int fpx, fpy; /* First pixel to check */ int lpx, lpy; /* Last pixel to check */ int frx, fry; /* First pixel relative to rastermap */ IntPoint corner1(pos1), corner2(pos2); IntRect framerect1, framerect2; IntRect mrect1, mrect2; IntRect *cutrect; /* Break */ if(map == NULL) return false; /* Translate negative axises */ mrect1 = rect_translate_negative_axises(rect1, size); mrect2 = rect_translate_negative_axises(rect2, rastermap.getMapSize() * rastermap.getCellSize()); /* Align */ if(alignment1.getX() != 0) corner1.decX((int)(mrect1.getWidth() * alignment1.getX())); if(alignment1.getY() != 0) corner1.decY((int)(mrect1.getHeight() * alignment1.getY())); if(alignment2.getX() != 0) corner2.decX((int)(mrect2.getWidth() * alignment2.getX())); if(alignment2.getY() != 0) corner2.decY((int)(mrect2.getHeight() * alignment2.getY())); /* Framerects */ framerect1.load(corner1.getX(), corner1.getY(), mrect1.getWidth(), mrect1.getHeight()); framerect2.load(corner2.getX(), corner2.getY(), mrect2.getWidth(), mrect2.getHeight()); /* Break */ if(!size_to_rect(size).isCovering(mrect1)) throw Exception() << "pixelmap doesn't fully cover rect"; if(!size_to_rect(rastermap.getMapSize() * rastermap.getCellSize()).isCovering(mrect2)) throw Exception() << "rastermap doesn't fully cover rect"; /* Cutrect */ if((cutrect = framerect1.getCutrect(framerect2)) == NULL) return false; /* First / last pixel to check on pixelmap */ fpx = cutrect->getX() - (corner1.getX() - mrect1.getX()); fpy = cutrect->getY() - (corner1.getY() - mrect1.getY()); lpx = fpx + cutrect->getWidth() - 1; lpy = fpy + cutrect->getHeight() - 1; /* Get first pixel relative to rastermap */ frx = cutrect->getX() - (corner2.getX() - mrect2.getX()); fry = cutrect->getY() - (corner2.getY() - mrect2.getY()); /* Delete cutrect */ delete cutrect; /* Iterate pixels */ for(int py = fpy, ry = fry; py <= lpy; py++, ry++) { for(int px = fpx, rx = frx; px <= lpx; px++, rx++) { if(is_pixel(px, py)) { int cx, cy; /* Get cell */ cx = rx / rastermap.getCellSize().getWidth(); cy = ry / rastermap.getCellSize().getHeight(); /* Check */ if(rastermap.isCell(IntPoint(cx, cy))) { return true; } else { int add = rastermap.getCellSize().getWidth() - (rx % rastermap.getCellSize().getWidth()); rx += add; px += add; } } } } return false; }
static void test_troute(const RasterMap &map, double mwind, double mc, int ceiling) { GlideSettings settings; settings.SetDefaults(); RoutePlannerConfig config; config.mode = RoutePlannerConfig::Mode::BOTH; GlidePolar polar(mc); SpeedVector wind(Angle::Degrees(0), mwind); TerrainRoute route; route.UpdatePolar(settings, config, polar, polar, wind); route.SetTerrain(&map); GeoPoint origin(map.GetMapCenter()); auto pd = map.PixelDistance(origin, 1); printf("# pixel size %g\n", (double)pd); bool retval= true; { Directory::Create(Path(_T("output/results"))); std::ofstream fout ("output/results/terrain.txt"); unsigned nx = 100; unsigned ny = 100; for (unsigned i=0; i< nx; ++i) { for (unsigned j=0; j< ny; ++j) { auto fx = (double)i / (nx - 1) * 2 - 1; auto fy = (double)j / (ny - 1) * 2 - 1; GeoPoint x(origin.longitude + Angle::Degrees(0.6 * fx), origin.latitude + Angle::Degrees(0.4 * fy)); TerrainHeight h = map.GetInterpolatedHeight(x); fout << x.longitude.Degrees() << " " << x.latitude.Degrees() << " " << h.GetValue() << "\n"; } fout << "\n"; } fout << "\n"; } unsigned i=0; for (double ang = 0; ang < M_2PI; ang += M_PI / 8) { GeoPoint dest = GeoVector(40000.0, Angle::Radians(ang)).EndPoint(origin); int hdest = map.GetHeight(dest).GetValueOr0() + 100; retval = route.Solve(AGeoPoint(origin, map.GetHeight(origin).GetValueOr0() + 100), AGeoPoint(dest, mc > 0 ? hdest : std::max(hdest, 3200)), config, ceiling); char buffer[80]; sprintf(buffer,"terrain route solve, dir=%g, wind=%g, mc=%g ceiling=%d", (double)ang, (double)mwind, (double)mc, (int)ceiling); ok(retval, buffer, 0); PrintHelper::print_route(route); i++; } // polar.SetMC(0); // route.UpdatePolar(polar, wind); }