def _pointsOnEllipse(c, smaa, smia, ang, n): """Generates points lying on the ellipse with center c, semi-major/semi-minor axis lengths smaa/smia, and major axis angle (E of N) ang. """ points = [] c = g.cartesianUnitVector(c) north, east = g.northEast(c) sa = math.sin(math.radians(ang)) ca = math.cos(math.radians(ang)) smaa = math.radians(smaa * g.DEG_PER_ARCSEC) smia = math.radians(smia * g.DEG_PER_ARCSEC) aoff = random.uniform(0.0, 2.0 * math.pi) for i in xrange(n): a = aoff + 2.0 * i * math.pi / n x = smaa * math.cos(a) y = smia * math.sin(a) # rotate x, y by a nc = ca * x - sa * y ec = sa * x + ca * y cc = math.sqrt(abs(1.0 - nc * nc - ec * ec)) points.append( g.normalize((cc * c[0] + nc * north[0] + ec * east[0], cc * c[1] + nc * north[1] + ec * east[1], cc * c[2] + nc * north[2] + ec * east[2]))) return points
def _pointsOnEllipse(c, smaa, smia, ang, n): """Generates points lying on the ellipse with center c, semi-major/semi-minor axis lengths smaa/smia, and major axis angle (E of N) ang. """ points = [] c = g.cartesianUnitVector(c) north, east = g.northEast(c) sa = math.sin(math.radians(ang)) ca = math.cos(math.radians(ang)) smaa = math.radians(smaa * g.DEG_PER_ARCSEC) smia = math.radians(smia * g.DEG_PER_ARCSEC) aoff = random.uniform(0.0, 2.0 * math.pi) for i in xrange(n): a = aoff + 2.0 * i * math.pi / n x = smaa * math.cos(a) y = smia * math.sin(a) # rotate x, y by a nc = ca * x - sa * y ec = sa * x + ca * y cc = math.sqrt(abs(1.0 - nc * nc - ec * ec)) points.append(g.normalize((cc * c[0] + nc * north[0] + ec * east[0], cc * c[1] + nc * north[1] + ec * east[1], cc * c[2] + nc * north[2] + ec * east[2]))) return points
def testSpatialPredicates(self): # ellipse-point for cen in ((0.0, 0.0), (45.0, 45.0), (135.0, -45.0), (0.0, 90.0)): smaa = random.uniform(30, 20000) smia = random.uniform(1, smaa) a = random.uniform(0.0, 360.0) e = g.SphericalEllipse(cen, smaa, smia, a) self.assertTrue(e.contains(cen)) self.assertTrue(e.contains(g.cartesianUnitVector(cen))) self.assertTrue(e.intersects(cen)) self.assertTrue(e.intersects(g.cartesianUnitVector(cen))) points = _pointsOnCircle( cen, e.getInnerCircle().getRadius() - g.ANGLE_EPSILON, 100) for p in points: self.assertTrue(e.contains(p)) points = _pointsOnCircle( cen, e.getBoundingCircle().getRadius() + g.ANGLE_EPSILON, 100) for p in points: self.assertFalse(e.intersects(p)) points = _pointsOnEllipse( cen, smaa - g.ANGLE_EPSILON * g.ARCSEC_PER_DEG, smia - g.ANGLE_EPSILON * g.ARCSEC_PER_DEG, a, 100) for p in points: self.assertTrue(e.contains(p)) points = _pointsOnEllipse( cen, smaa + g.ANGLE_EPSILON * g.ARCSEC_PER_DEG, smia + g.ANGLE_EPSILON * g.ARCSEC_PER_DEG, a, 100) for p in points: self.assertFalse(e.contains(p)) # ellipse-circle cen = (0.0, 0.0) e = g.SphericalEllipse(cen, 7200.0, 3600.0, 90.0) c = g.SphericalCircle(cen, e.getInnerCircle().getRadius() - g.ANGLE_EPSILON) self.assertTrue(e.intersects(c)) self.assertTrue(c.intersects(e)) self.assertTrue(e.contains(c)) self.assertFalse(c.contains(e)) # ellipse-box b = g.SphericalBox((-0.5, -0.5), (0.5, 0.5)) self.assertTrue(e.intersects(b)) self.assertTrue(e.contains(b)) b = g.SphericalBox((0.5, -0.5), (359.5, 0.5)) self.assertTrue(e.intersects(b)) self.assertFalse(e.contains(b))
def testCartesianUnitVector(self): v = g.cartesianUnitVector((1.0, 0.0, 0.0)) self.assertEqual(v[0], 1.0) self.assertEqual(v[1], 0.0) self.assertEqual(v[2], 0.0) v = g.cartesianUnitVector((1.0, 1.0, 1.0)) self.assertAlmostEqual(v[0], 0.577350269189626) self.assertAlmostEqual(v[1], 0.577350269189626) self.assertAlmostEqual(v[2], 0.577350269189626) v = g.cartesianUnitVector((45.0, 35.2643896827547)) self.assertAlmostEqual(v[0], 0.577350269189626) self.assertAlmostEqual(v[1], 0.577350269189626) self.assertAlmostEqual(v[2], 0.577350269189626) v = g.cartesianUnitVector((180.0, 0.0)) self.assertAlmostEqual(v[0], -1.0) self.assertAlmostEqual(v[1], 0.0) self.assertAlmostEqual(v[2], 0.0)
def testSpatialPredicates(self): # ellipse-point for cen in ((0.0, 0.0), (45.0, 45.0), (135.0, -45.0), (0.0, 90.0)): smaa = random.uniform(30, 20000) smia = random.uniform(1, smaa) a = random.uniform(0.0, 360.0) e = g.SphericalEllipse(cen, smaa, smia, a) self.assertTrue(e.contains(cen)) self.assertTrue(e.contains(g.cartesianUnitVector(cen))) self.assertTrue(e.intersects(cen)) self.assertTrue(e.intersects(g.cartesianUnitVector(cen))) points = _pointsOnCircle( cen, e.getInnerCircle().getRadius() - g.ANGLE_EPSILON, 100) for p in points: self.assertTrue(e.contains(p)) points = _pointsOnCircle( cen, e.getBoundingCircle().getRadius() + g.ANGLE_EPSILON, 100) for p in points: self.assertFalse(e.intersects(p)) points = _pointsOnEllipse( cen, smaa - g.ANGLE_EPSILON * g.ARCSEC_PER_DEG, smia - g.ANGLE_EPSILON * g.ARCSEC_PER_DEG, a, 100) for p in points: self.assertTrue(e.contains(p)) points = _pointsOnEllipse( cen, smaa + g.ANGLE_EPSILON * g.ARCSEC_PER_DEG, smia + g.ANGLE_EPSILON * g.ARCSEC_PER_DEG, a, 100) for p in points: self.assertFalse(e.contains(p)) # ellipse-circle cen = (0.0, 0.0) e = g.SphericalEllipse(cen, 7200.0, 3600.0, 90.0) c = g.SphericalCircle( cen, e.getInnerCircle().getRadius() - g.ANGLE_EPSILON) self.assertTrue(e.intersects(c)) self.assertTrue(c.intersects(e)) self.assertTrue(e.contains(c)) self.assertFalse(c.contains(e)) # ellipse-box b = g.SphericalBox((-0.5, -0.5), (0.5, 0.5)) self.assertTrue(e.intersects(b)) self.assertTrue(e.contains(b)) b = g.SphericalBox((0.5, -0.5), (359.5, 0.5)) self.assertTrue(e.intersects(b)) self.assertFalse(e.contains(b))
def _pointsOnCircle(c, r, n, clockwise=False): """Generates an n-gon lying on the circle with center c and radius r. Vertices are equi-spaced. """ c = g.cartesianUnitVector(c) north, east = g.northEast(c) points = [] sr = math.sin(math.radians(r)) cr = math.cos(math.radians(r)) aoff = random.uniform(0.0, 2.0 * math.pi) for i in xrange(n): a = 2.0 * i * math.pi / n if not clockwise: a = -a sa = math.sin(a + aoff) ca = math.cos(a + aoff) p = (ca * north[0] + sa * east[0], ca * north[1] + sa * east[1], ca * north[2] + sa * east[2]) points.append( g.normalize((cr * c[0] + sr * p[0], cr * c[1] + sr * p[1], cr * c[2] + sr * p[2]))) return points
def _pointsOnPeriodicHypotrochoid(c, R, r, d, n): assert isinstance(r, int) and isinstance(R, int) assert R > r assert (2 * r) % (R - r) == 0 points = [] c = g.cartesianUnitVector(c) north, east = g.northEast(c) scale = 1.0 / (R - r + d + 1) period = (2 * r) / (R - r) if period % 2 != 0: period *= 2 for i in xrange(n): theta = i * period * math.pi / n x = (R - r) * math.cos(theta) + d * math.cos((R - r) * theta / r) y = (R - r) * math.sin(theta) - d * math.sin((R - r) * theta / r) x *= scale y *= scale z = math.sqrt(1.0 - x * x - y * y) points.append(g.normalize((z * c[0] + x * north[0] + y * east[0], z * c[1] + x * north[1] + y * east[1], z * c[2] + x * north[2] + y * east[2]))) return points
def _pointsOnPeriodicHypotrochoid(c, R, r, d, n): assert isinstance(r, int) and isinstance(R, int) assert R > r assert (2 * r) % (R - r) == 0 points = [] c = geom.cartesianUnitVector(c) north, east = geom.northEast(c) scale = 1.0 / (R - r + d + 1) period = (2 * r) / (R - r) if period % 2 != 0: period *= 2 for i in range(n): theta = i * period * math.pi / n x = (R - r) * math.cos(theta) + d * math.cos((R - r) * theta / r) y = (R - r) * math.sin(theta) - d * math.sin((R - r) * theta / r) x *= scale y *= scale z = math.sqrt(1.0 - x * x - y * y) points.append(geom.normalize((z * c[0] + x * north[0] + y * east[0], z * c[1] + x * north[1] + y * east[1], z * c[2] + x * north[2] + y * east[2]))) return points
def _pointsOnCircle(c, r, n, clockwise=False): """Generates an n-gon lying on the circle with center c and radius r. Vertices are equi-spaced. """ c = g.cartesianUnitVector(c) north, east = g.northEast(c) points = [] sr = math.sin(math.radians(r)) cr = math.cos(math.radians(r)) aoff = random.uniform(0.0, 2.0 * math.pi) for i in xrange(n): a = 2.0 * i * math.pi / n if not clockwise: a = -a sa = math.sin(a + aoff) ca = math.cos(a + aoff) p = (ca * north[0] + sa * east[0], ca * north[1] + sa * east[1], ca * north[2] + sa * east[2]) points.append(g.normalize((cr * c[0] + sr * p[0], cr * c[1] + sr * p[1], cr * c[2] + sr * p[2]))) return points
def testEdge(self): v1 = g.cartesianUnitVector(0.0, 45.0) v2 = g.cartesianUnitVector(180.0, 45.0) n = (0.0, -1.0, 0.0) b = g.SphericalBox.edge(v1, v2, n) self.assertEqual(b.getMin()[0], 0.0) self.assertEqual(b.getMax()[0], 360.0) self.assertAlmostEqual(b.getMin()[1], 45.0) self.assertEqual(b.getMax()[1], 90.0) v1 = g.cartesianUnitVector(0.0, 45.0) v2 = g.cartesianUnitVector(0.0, 75.0) b = g.SphericalBox.edge(v1, v2, n) self.assertAlmostEqual(b.getMin()[0], 0.0) self.assertAlmostEqual(b.getMax()[0], 0.0) self.assertAlmostEqual(b.getMin()[1], 45.0) self.assertAlmostEqual(b.getMax()[1], 75.0) v1 = g.cartesianUnitVector(-0.1 * g.ANGLE_EPSILON, 45.0) v2 = g.cartesianUnitVector(180 + 0.1 * g.ANGLE_EPSILON, 45.0) n = g.normalize(g.cross(v1, v2)) b = g.SphericalBox.edge(v1, v2, n) self.assertEqual(b.getMin()[0], 0.0) self.assertEqual(b.getMax()[0], 360.0) self.assertAlmostEqual(b.getMin()[1], 45.0) self.assertEqual(b.getMax()[1], 90.0) v1 = g.cartesianUnitVector(-0.1 * g.ANGLE_EPSILON, 45.0) v2 = g.cartesianUnitVector(0.1 * g.ANGLE_EPSILON, 75.0) n = g.normalize(g.cross(v1, v2)) b = g.SphericalBox.edge(v1, v2, n) self.assertAlmostEqual(b.getMin()[0], 360.0) self.assertAlmostEqual(b.getMax()[0], 0.0) self.assertAlmostEqual(b.getMin()[1], 45.0) self.assertAlmostEqual(b.getMax()[1], 75.0) v1 = g.cartesianUnitVector(1.0, 1.0) v2 = g.cartesianUnitVector(2.0, 2.0) n = g.normalize(g.cross(v1, v2)) b = g.SphericalBox.edge(v1, v2, n) self.assertAlmostEqual(b.getMin()[0], 1.0) self.assertAlmostEqual(b.getMax()[0], 2.0) self.assertAlmostEqual(b.getMin()[1], 1.0) self.assertAlmostEqual(b.getMax()[1], 2.0) v1 = g.cartesianUnitVector(-1.0, 3.0) v2 = g.cartesianUnitVector(2.0, -1.0) n = g.normalize(g.cross(v1, v2)) b = g.SphericalBox.edge(v1, v2, n) self.assertAlmostEqual(b.getMin()[0], 359.0) self.assertAlmostEqual(b.getMax()[0], 2.0) self.assertAlmostEqual(b.getMin()[1], -1.0) self.assertAlmostEqual(b.getMax()[1], 3.0)
def testEdge(self): v1 = g.cartesianUnitVector(0.0, 45.0) v2 = g.cartesianUnitVector(180.0, 45.0) n = (0.0, -1.0, 0.0) b = g.SphericalBox.edge(v1, v2, n) self.assertEqual(b.getMin()[0], 0.0) self.assertEqual(b.getMax()[0], 360.0) self.assertAlmostEqual(b.getMin()[1], 45.0) self.assertEqual(b.getMax()[1], 90.0) v1 = g.cartesianUnitVector(0.0, 45.0) v2 = g.cartesianUnitVector(0.0, 75.0) b = g.SphericalBox.edge(v1, v2, n) self.assertAlmostEqual(b.getMin()[0], 0.0) self.assertAlmostEqual(b.getMax()[0], 0.0) self.assertAlmostEqual(b.getMin()[1], 45.0) self.assertAlmostEqual(b.getMax()[1], 75.0) v1 = g.cartesianUnitVector(-0.1 * g.ANGLE_EPSILON, 45.0) v2 = g.cartesianUnitVector(180 + 0.1 *g.ANGLE_EPSILON, 45.0) n = g.normalize(g.cross(v1, v2)) b = g.SphericalBox.edge(v1, v2, n) self.assertEqual(b.getMin()[0], 0.0) self.assertEqual(b.getMax()[0], 360.0) self.assertAlmostEqual(b.getMin()[1], 45.0) self.assertEqual(b.getMax()[1], 90.0) v1 = g.cartesianUnitVector(-0.1 * g.ANGLE_EPSILON, 45.0) v2 = g.cartesianUnitVector(0.1 * g.ANGLE_EPSILON, 75.0) n = g.normalize(g.cross(v1, v2)) b = g.SphericalBox.edge(v1, v2, n) self.assertAlmostEqual(b.getMin()[0], 360.0) self.assertAlmostEqual(b.getMax()[0], 0.0) self.assertAlmostEqual(b.getMin()[1], 45.0) self.assertAlmostEqual(b.getMax()[1], 75.0) v1 = g.cartesianUnitVector(1.0, 1.0) v2 = g.cartesianUnitVector(2.0, 2.0) n = g.normalize(g.cross(v1, v2)) b = g.SphericalBox.edge(v1, v2, n) self.assertAlmostEqual(b.getMin()[0], 1.0) self.assertAlmostEqual(b.getMax()[0], 2.0) self.assertAlmostEqual(b.getMin()[1], 1.0) self.assertAlmostEqual(b.getMax()[1], 2.0) v1 = g.cartesianUnitVector(-1.0, 3.0) v2 = g.cartesianUnitVector(2.0, -1.0) n = g.normalize(g.cross(v1, v2)) b = g.SphericalBox.edge(v1, v2, n) self.assertAlmostEqual(b.getMin()[0], 359.0) self.assertAlmostEqual(b.getMax()[0], 2.0) self.assertAlmostEqual(b.getMin()[1], -1.0) self.assertAlmostEqual(b.getMax()[1], 3.0)