This repository has been archived by the owner on Jan 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
529 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
""" | ||
@brief test log(time=10s) | ||
""" | ||
import os | ||
import sys | ||
import unittest | ||
|
||
|
||
try: | ||
import src | ||
import pyquickhelper as skip_ | ||
except ImportError: | ||
path = os.path.normpath( | ||
os.path.abspath( | ||
os.path.join( | ||
os.path.split(__file__)[0], | ||
"..", | ||
".."))) | ||
if path not in sys.path: | ||
sys.path.append(path) | ||
path = os.path.normpath( | ||
os.path.abspath( | ||
os.path.join( | ||
os.path.split(__file__)[0], | ||
"..", | ||
"..", | ||
"..", | ||
"pyquickhelper", | ||
"src"))) | ||
if path not in sys.path: | ||
sys.path.append(path) | ||
import src | ||
import pyquickhelper as skip_ | ||
|
||
|
||
from pyquickhelper.loghelper import fLOG | ||
from src.ensae_teaching_cs.special.geometry_point import GeometryPoint | ||
from src.ensae_teaching_cs.special.geometry_segment import GeometrySegment | ||
from src.ensae_teaching_cs.special.geometry_polygone import GeometryPolygone | ||
|
||
|
||
class TestGeometry(unittest.TestCase): | ||
|
||
def test_geometry_point(self): | ||
fLOG( | ||
__file__, | ||
self._testMethodName, | ||
OutputPrint=__name__ == "__main__") | ||
|
||
p = GeometryPoint(4, 5) | ||
p += p | ||
self.assertEqual(p, (8, 10)) | ||
p -= p | ||
self.assertEqual(p, (0, 0)) | ||
p2 = GeometryPoint(4, 5) + GeometryPoint(1, 1) | ||
self.assertEqual(p2, (5, 6)) | ||
norm = p2.norm2() | ||
seg = GeometrySegment(p, p2) | ||
norms = seg.norm2() | ||
self.assertEqual(norms, norm) | ||
|
||
def test_geometry_polygone(self): | ||
fLOG( | ||
__file__, | ||
self._testMethodName, | ||
OutputPrint=__name__ == "__main__") | ||
middle = GeometryPoint(GeometryPoint(0.5, 0.1)) | ||
|
||
poly = GeometryPolygone([GeometryPoint(0, 0), GeometryPoint(1, 0), | ||
GeometryPoint(1, 1), GeometryPoint(0, 1)]) | ||
r = poly.in_convex(middle) | ||
assert r | ||
out = GeometryPoint(0.5, -0.1) | ||
r = poly.in_convex(out) | ||
assert not r | ||
|
||
def test_geometry_polygone2(self): | ||
fLOG( | ||
__file__, | ||
self._testMethodName, | ||
OutputPrint=__name__ == "__main__") | ||
|
||
poly = GeometryPolygone([GeometryPoint(0, 0), GeometryPoint(0, 1), | ||
GeometryPoint(1, 1), GeometryPoint(1, 0)]) | ||
convex = poly.convex() | ||
fLOG(convex) | ||
self.assertEqual(len(convex), len(poly)) | ||
r = [GeometryPoint(0, 1), GeometryPoint( | ||
0, 0), GeometryPoint(1, 0), GeometryPoint(1, 1)] | ||
for p, e in zip(convex, r): | ||
self.assertEqual(p, e) | ||
|
||
if __name__ == "__main__": | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
""" | ||
@file | ||
@brief Defines a point in N-dimension | ||
""" | ||
|
||
import math | ||
|
||
|
||
class GeometryException(Exception): | ||
""" | ||
raises when an issue arises with class GeometryPoint | ||
""" | ||
pass | ||
|
||
|
||
class GeometryPoint(object): | ||
""" | ||
one point | ||
""" | ||
__slots__ = ["_x"] | ||
|
||
def __init__(self, *x): | ||
""" | ||
constructor | ||
@param x is a vector | ||
""" | ||
if isinstance(x, (tuple, list)): | ||
if len(x) == 0: | ||
raise ValueError("empty dimension") | ||
if isinstance(x[0], GeometryPoint) and len(x) == 1: | ||
self._x = x[0]._x | ||
else: | ||
self._x = tuple(x) | ||
else: | ||
raise TypeError(type(x)) | ||
|
||
def __eq__(self, x): | ||
""" | ||
is equal | ||
""" | ||
return self._x == x | ||
|
||
def __neq__(self, x): | ||
""" | ||
is different | ||
""" | ||
return not self.__eq__(x) | ||
|
||
def __len__(self): | ||
""" | ||
returns the dimension | ||
""" | ||
return len(self._x) | ||
|
||
def __str__(self): | ||
""" | ||
converts into string | ||
""" | ||
if len(self) == 2: | ||
s = "({0},{1})".format(*self._x) | ||
return s.replace(".000000", "") | ||
else: | ||
format = ", ".join(["{}" for _ in self._x]) | ||
t = format.format(*self._x) | ||
s = "(%s)" % t | ||
return s.replace(".000000", "") | ||
|
||
def __repr__(self): | ||
""" | ||
``eval(__repr__)`` should return the same object | ||
""" | ||
return "GeometryPoint(%s)" % ", ".join(str(_) for _ in self._x) | ||
|
||
def __iadd__(self, x): | ||
""" | ||
addition | ||
""" | ||
if len(self) != len(x): | ||
raise GeometryException("dimension problem %d != %d" % | ||
(len(self), len(x))) | ||
if len(self) == 2: | ||
self._x = (self._x[0] + x._x[0], self._x[1] + x._x[1]) | ||
else: | ||
self._x = tuple(a + b for a, b in zip(self._x, x._x)) | ||
return self | ||
|
||
def __add__(self, x): | ||
""" | ||
addition | ||
""" | ||
if len(self) != len(x): | ||
raise GeometryException("dimension problem %d != %d" % | ||
(len(self), len(x))) | ||
if len(self) == 2: | ||
return GeometryPoint(self._x[0] + x._x[0], self._x[1] + x._x[1]) | ||
else: | ||
return GeometryPoint(a + b for a, b in zip(self._x, x._x)) | ||
|
||
def __sub__(self, x): | ||
""" | ||
substraction | ||
""" | ||
if len(self) != len(x): | ||
raise GeometryException("dimension problem %d != %d" % | ||
(len(self), len(x))) | ||
if len(self) == 2: | ||
return GeometryPoint(self._x[0] - x._x[0], self._x[1] - x._x[1]) | ||
else: | ||
return GeometryPoint(a - b for a, b in zip(self._x, x._x)) | ||
|
||
def __imul__(self, k): | ||
""" | ||
multiplication by a scalar | ||
""" | ||
if len(self) == 2: | ||
self._x = (self._x[0] * k, self._x[1] * k) | ||
else: | ||
self._x = tuple(_ * k for _ in self._x) | ||
return self | ||
|
||
def __mul__(self, k): | ||
""" | ||
multiplication by a scalar | ||
""" | ||
if len(self) == 2: | ||
return GeometryPoint(self._x[0] * k, self._x[1] * k) | ||
else: | ||
return GeometryPoint(_ * k for _ in self._x) | ||
|
||
def scalar(self, x): | ||
""" | ||
scalar product | ||
""" | ||
if len(self) != len(x): | ||
raise GeometryException("dimension problem %d != %d\n%s ? %s" % (len(self), len(x), | ||
str(self), str(x))) | ||
r = 0. | ||
for a, b in zip(self._x, x._x): | ||
r += a * b | ||
return r | ||
|
||
def __cmp__(self, x): | ||
""" | ||
comparison | ||
""" | ||
if len(self) != len(x): | ||
raise GeometryException("dimension problem %d != %d" % | ||
(len(self), len(x))) | ||
for a, b in zip(self._x, x._x): | ||
t = -1 if a < b else (0 if a == b else 1) | ||
if t != 0: | ||
return t | ||
return 0 | ||
|
||
def __lt__(self, x): | ||
""" | ||
inferior | ||
""" | ||
return self.__cmp__(x) == -1 | ||
|
||
def product(self, x): | ||
""" | ||
vectoriel product, dimension 2 only | ||
""" | ||
if len(self) != 2: | ||
raise GeometryException( | ||
"this function only exists if len(self) == 2") | ||
|
||
return self._x[1] * x._x[0] - self._x[0] * x._x[1] | ||
|
||
def cossin(self): | ||
""" | ||
return the cos, sin of a vector (dimension 2 only) | ||
""" | ||
n = self.norm2() | ||
if n == 0.: | ||
return 1., 0. | ||
n = n ** 0.5 | ||
p = GeometryPoint(1., 0.) | ||
cos = self.scalar(p) / n | ||
sin = self.product(p) / n | ||
return cos, sin | ||
|
||
def norm2(self): | ||
""" | ||
return the norm | ||
""" | ||
return self.scalar(self) | ||
|
||
def angle(self): | ||
""" | ||
return the angle | ||
""" | ||
cos, sin = self.cossin() | ||
if cos == 0: | ||
if sin == 0: | ||
return 0 | ||
elif sin > 0: | ||
return math.pi / 2 | ||
else: | ||
return -math.pi / 2 | ||
else: | ||
t = sin / cos | ||
a = math.atan(t) | ||
if cos < 0: | ||
return a - math.pi | ||
else: | ||
return a |
Oops, something went wrong.