src/apps/testapps/testBBox.c (192 lines of code) (raw):
/*
* Copyright 2016-2018 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <math.h>
#include <stdlib.h>
#include "bbox.h"
#include "constants.h"
#include "geoCoord.h"
#include "polygon.h"
#include "test.h"
void assertBBox(const Geofence* geofence, const BBox* expected,
const GeoCoord* inside, const GeoCoord* outside) {
BBox result;
bboxFromGeofence(geofence, &result);
t_assert(bboxEquals(&result, expected), "Got expected bbox");
t_assert(bboxContains(&result, inside), "Contains expected inside point");
t_assert(!bboxContains(&result, outside),
"Does not contain expected outside point");
}
SUITE(BBox) {
TEST(posLatPosLon) {
GeoCoord verts[] = {{0.8, 0.3}, {0.7, 0.6}, {1.1, 0.7}, {1.0, 0.2}};
const Geofence geofence = {.numVerts = 4, .verts = verts};
const BBox expected = {1.1, 0.7, 0.7, 0.2};
const GeoCoord inside = {0.9, 0.4};
const GeoCoord outside = {0.0, 0.0};
assertBBox(&geofence, &expected, &inside, &outside);
}
TEST(negLatPosLon) {
GeoCoord verts[] = {{-0.3, 0.6}, {-0.4, 0.9}, {-0.2, 0.8}, {-0.1, 0.6}};
const Geofence geofence = {.numVerts = 4, .verts = verts};
const BBox expected = {-0.1, -0.4, 0.9, 0.6};
const GeoCoord inside = {-0.3, 0.8};
const GeoCoord outside = {0.0, 0.0};
assertBBox(&geofence, &expected, &inside, &outside);
}
TEST(posLatNegLon) {
GeoCoord verts[] = {{0.7, -1.4}, {0.8, -0.9}, {1.0, -0.8}, {1.1, -1.3}};
const Geofence geofence = {.numVerts = 4, .verts = verts};
const BBox expected = {1.1, 0.7, -0.8, -1.4};
const GeoCoord inside = {0.9, -1.0};
const GeoCoord outside = {0.0, 0.0};
assertBBox(&geofence, &expected, &inside, &outside);
}
TEST(negLatNegLon) {
GeoCoord verts[] = {
{-0.4, -1.4}, {-0.3, -1.1}, {-0.1, -1.2}, {-0.2, -1.4}};
const Geofence geofence = {.numVerts = 4, .verts = verts};
const BBox expected = {-0.1, -0.4, -1.1, -1.4};
const GeoCoord inside = {-0.3, -1.2};
const GeoCoord outside = {0.0, 0.0};
assertBBox(&geofence, &expected, &inside, &outside);
}
TEST(aroundZeroZero) {
GeoCoord verts[] = {{0.4, -0.4}, {0.4, 0.4}, {-0.4, 0.4}, {-0.4, -0.4}};
const Geofence geofence = {.numVerts = 4, .verts = verts};
const BBox expected = {0.4, -0.4, 0.4, -0.4};
const GeoCoord inside = {-0.1, -0.1};
const GeoCoord outside = {1.0, -1.0};
assertBBox(&geofence, &expected, &inside, &outside);
}
TEST(transmeridian) {
GeoCoord verts[] = {{0.4, M_PI - 0.1},
{0.4, -M_PI + 0.1},
{-0.4, -M_PI + 0.1},
{-0.4, M_PI - 0.1}};
const Geofence geofence = {.numVerts = 4, .verts = verts};
const BBox expected = {0.4, -0.4, -M_PI + 0.1, M_PI - 0.1};
const GeoCoord insideOnMeridian = {-0.1, M_PI};
const GeoCoord outside = {1.0, M_PI - 0.5};
assertBBox(&geofence, &expected, &insideOnMeridian, &outside);
const GeoCoord westInside = {0.1, M_PI - 0.05};
t_assert(bboxContains(&expected, &westInside),
"Contains expected west inside point");
const GeoCoord eastInside = {0.1, -M_PI + 0.05};
t_assert(bboxContains(&expected, &eastInside),
"Contains expected east outside point");
const GeoCoord westOutside = {0.1, M_PI - 0.5};
t_assert(!bboxContains(&expected, &westOutside),
"Does not contain expected west outside point");
const GeoCoord eastOutside = {0.1, -M_PI + 0.5};
t_assert(!bboxContains(&expected, &eastOutside),
"Does not contain expected east outside point");
}
TEST(edgeOnNorthPole) {
GeoCoord verts[] = {{M_PI_2 - 0.1, 0.1},
{M_PI_2 - 0.1, 0.8},
{M_PI_2, 0.8},
{M_PI_2, 0.1}};
const Geofence geofence = {.numVerts = 4, .verts = verts};
const BBox expected = {M_PI_2, M_PI_2 - 0.1, 0.8, 0.1};
const GeoCoord inside = {M_PI_2 - 0.01, 0.4};
const GeoCoord outside = {M_PI_2, 0.9};
assertBBox(&geofence, &expected, &inside, &outside);
}
TEST(edgeOnSouthPole) {
GeoCoord verts[] = {{-M_PI_2 + 0.1, 0.1},
{-M_PI_2 + 0.1, 0.8},
{-M_PI_2, 0.8},
{-M_PI_2, 0.1}};
const Geofence geofence = {.numVerts = 4, .verts = verts};
const BBox expected = {-M_PI_2 + 0.1, -M_PI_2, 0.8, 0.1};
const GeoCoord inside = {-M_PI_2 + 0.01, 0.4};
const GeoCoord outside = {-M_PI_2, 0.9};
assertBBox(&geofence, &expected, &inside, &outside);
}
TEST(containsEdges) {
const BBox bbox = {0.1, -0.1, 0.2, -0.2};
GeoCoord points[] = {
{0.1, 0.2}, {0.1, 0.0}, {0.1, -0.2}, {0.0, 0.2},
{-0.1, 0.2}, {-0.1, 0.0}, {-0.1, -0.2}, {0.0, -0.2},
};
const int numPoints = 8;
for (int i = 0; i < numPoints; i++) {
t_assert(bboxContains(&bbox, &points[i]), "Contains edge point");
}
}
TEST(containsEdgesTransmeridian) {
const BBox bbox = {0.1, -0.1, -M_PI + 0.2, M_PI - 0.2};
GeoCoord points[] = {
{0.1, -M_PI + 0.2}, {0.1, M_PI}, {0.1, M_PI - 0.2},
{0.0, -M_PI + 0.2}, {-0.1, -M_PI + 0.2}, {-0.1, M_PI},
{-0.1, M_PI - 0.2}, {0.0, M_PI - 0.2},
};
const int numPoints = 8;
for (int i = 0; i < numPoints; i++) {
t_assert(bboxContains(&bbox, &points[i]),
"Contains transmeridian edge point");
}
}
TEST(bboxCenterBasicQuandrants) {
GeoCoord center;
BBox bbox1 = {1.0, 0.8, 1.0, 0.8};
GeoCoord expected1 = {0.9, 0.9};
bboxCenter(&bbox1, ¢er);
t_assert(geoAlmostEqual(¢er, &expected1), "pos/pos as expected");
BBox bbox2 = {-0.8, -1.0, 1.0, 0.8};
GeoCoord expected2 = {-0.9, 0.9};
bboxCenter(&bbox2, ¢er);
t_assert(geoAlmostEqual(¢er, &expected2), "neg/pos as expected");
BBox bbox3 = {1.0, 0.8, -0.8, -1.0};
GeoCoord expected3 = {0.9, -0.9};
bboxCenter(&bbox3, ¢er);
t_assert(geoAlmostEqual(¢er, &expected3), "pos/neg as expected");
BBox bbox4 = {-0.8, -1.0, -0.8, -1.0};
GeoCoord expected4 = {-0.9, -0.9};
bboxCenter(&bbox4, ¢er);
t_assert(geoAlmostEqual(¢er, &expected4), "neg/neg as expected");
BBox bbox5 = {0.8, -0.8, 1.0, -1.0};
GeoCoord expected5 = {0.0, 0.0};
bboxCenter(&bbox5, ¢er);
t_assert(geoAlmostEqual(¢er, &expected5),
"around origin as expected");
}
TEST(bboxCenterTransmeridian) {
GeoCoord center;
BBox bbox1 = {1.0, 0.8, -M_PI + 0.3, M_PI - 0.1};
GeoCoord expected1 = {0.9, -M_PI + 0.1};
bboxCenter(&bbox1, ¢er);
t_assert(geoAlmostEqual(¢er, &expected1), "skew east as expected");
BBox bbox2 = {1.0, 0.8, -M_PI + 0.1, M_PI - 0.3};
GeoCoord expected2 = {0.9, M_PI - 0.1};
bboxCenter(&bbox2, ¢er);
t_assert(geoAlmostEqual(¢er, &expected2), "skew west as expected");
BBox bbox3 = {1.0, 0.8, -M_PI + 0.1, M_PI - 0.1};
GeoCoord expected3 = {0.9, M_PI};
bboxCenter(&bbox3, ¢er);
t_assert(geoAlmostEqual(¢er, &expected3),
"on antimeridian as expected");
}
TEST(bboxIsTransmeridian) {
BBox bboxNormal = {1.0, 0.8, 1.0, 0.8};
t_assert(!bboxIsTransmeridian(&bboxNormal),
"Normal bbox not transmeridian");
BBox bboxTransmeridian = {1.0, 0.8, -M_PI + 0.3, M_PI - 0.1};
t_assert(bboxIsTransmeridian(&bboxTransmeridian),
"Transmeridian bbox is transmeridian");
}
TEST(bboxEquals) {
BBox bbox = {1.0, 0.0, 1.0, 0.0};
BBox north = bbox;
north.north += 0.1;
BBox south = bbox;
south.south += 0.1;
BBox east = bbox;
east.east += 0.1;
BBox west = bbox;
west.west += 0.1;
t_assert(bboxEquals(&bbox, &bbox), "Equals self");
t_assert(!bboxEquals(&bbox, &north), "Not equals different north");
t_assert(!bboxEquals(&bbox, &south), "Not equals different south");
t_assert(!bboxEquals(&bbox, &east), "Not equals different east");
t_assert(!bboxEquals(&bbox, &west), "Not equals different west");
}
}