LightWave2D 0.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lightwave2d-0.0.3/LICENSE +21 -0
- lightwave2d-0.0.3/LightWave2D/VERSION +1 -0
- lightwave2d-0.0.3/LightWave2D/__init__.py +0 -0
- lightwave2d-0.0.3/LightWave2D/__pycache__/__init__.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/__pycache__/detector.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/__pycache__/experiment.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/__pycache__/grid.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/__pycache__/physics.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/__pycache__/pml.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/__pycache__/source.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/__pycache__/utils.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/components/__init__.py +4 -0
- lightwave2d-0.0.3/LightWave2D/components/__pycache__/__init__.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/components/__pycache__/base_class.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/components/__pycache__/scatterers.cpython-311.pyc +0 -0
- lightwave2d-0.0.3/LightWave2D/components/base_class.py +100 -0
- lightwave2d-0.0.3/LightWave2D/components/scatterers.py +185 -0
- lightwave2d-0.0.3/LightWave2D/detector.py +88 -0
- lightwave2d-0.0.3/LightWave2D/directories.py +33 -0
- lightwave2d-0.0.3/LightWave2D/experiment.py +383 -0
- lightwave2d-0.0.3/LightWave2D/grid.py +156 -0
- lightwave2d-0.0.3/LightWave2D/physics.py +17 -0
- lightwave2d-0.0.3/LightWave2D/pml.py +74 -0
- lightwave2d-0.0.3/LightWave2D/source.py +119 -0
- lightwave2d-0.0.3/LightWave2D/utils.py +95 -0
- lightwave2d-0.0.3/LightWave2D.egg-info/PKG-INFO +54 -0
- lightwave2d-0.0.3/LightWave2D.egg-info/SOURCES.txt +35 -0
- lightwave2d-0.0.3/LightWave2D.egg-info/dependency_links.txt +1 -0
- lightwave2d-0.0.3/LightWave2D.egg-info/requires.txt +22 -0
- lightwave2d-0.0.3/LightWave2D.egg-info/top_level.txt +5 -0
- lightwave2d-0.0.3/MANIFEST.in +7 -0
- lightwave2d-0.0.3/PKG-INFO +54 -0
- lightwave2d-0.0.3/README.rst +10 -0
- lightwave2d-0.0.3/developments/testings_0.py +87 -0
- lightwave2d-0.0.3/setup.cfg +92 -0
- lightwave2d-0.0.3/setup.py +6 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Martin de Sivry
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.3
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
from typing import NoReturn
|
|
5
|
+
|
|
6
|
+
import numpy
|
|
7
|
+
from LightWave2D.physics import Physics
|
|
8
|
+
import matplotlib.pyplot as plt
|
|
9
|
+
from matplotlib.patches import PathPatch
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseComponent():
|
|
13
|
+
def __post_init__(self):
|
|
14
|
+
self.build_object()
|
|
15
|
+
|
|
16
|
+
def build_object(self) -> NoReturn:
|
|
17
|
+
"""
|
|
18
|
+
Build the permittivity mesh for the square scatterer.
|
|
19
|
+
"""
|
|
20
|
+
self.epsilon_r_mesh = numpy.ones(self.grid.shape) # Background permittivity
|
|
21
|
+
|
|
22
|
+
self.compute_path()
|
|
23
|
+
|
|
24
|
+
x_mesh, y_mesh = numpy.meshgrid(self.grid.x_stamp, self.grid.y_stamp)
|
|
25
|
+
|
|
26
|
+
coordinates = numpy.c_[x_mesh.T.flatten(), y_mesh.T.flatten()]
|
|
27
|
+
|
|
28
|
+
self.idx = self.path.contains_points(coordinates).astype(bool).reshape(self.epsilon_r_mesh.shape)
|
|
29
|
+
|
|
30
|
+
self.epsilon_r_mesh[self.idx] = self.epsilon_r
|
|
31
|
+
|
|
32
|
+
def add_to_ax(self, ax: plt.axis) -> NoReturn:
|
|
33
|
+
"""
|
|
34
|
+
Add the scatterer to the provided axis as a circle.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
ax (Axis): The axis to which the scatterer will be added.
|
|
38
|
+
"""
|
|
39
|
+
patch = PathPatch(
|
|
40
|
+
self.path,
|
|
41
|
+
alpha=0.7,
|
|
42
|
+
color=self.facecolor,
|
|
43
|
+
label=str(self.__class__.__name__),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
return ax.add_patch(patch)
|
|
47
|
+
|
|
48
|
+
def plot(self) -> NoReturn:
|
|
49
|
+
figure, ax = plt.subplots(1, 1, figsize=(6, 6))
|
|
50
|
+
ax.set_title('FDTD Simulation')
|
|
51
|
+
ax.set_xlabel(r'x position [$\mu$m]')
|
|
52
|
+
ax.set_xlabel(r'y position [$\mu$m]')
|
|
53
|
+
ax.set_aspect('equal')
|
|
54
|
+
|
|
55
|
+
self.add_to_ax(ax)
|
|
56
|
+
ax.autoscale_view()
|
|
57
|
+
|
|
58
|
+
plt.show()
|
|
59
|
+
|
|
60
|
+
def interpret_position_to_index(self) -> tuple:
|
|
61
|
+
"""
|
|
62
|
+
Interprets and returns the value of positions x and y of the waveguide
|
|
63
|
+
|
|
64
|
+
:returns: The index of width and height
|
|
65
|
+
:rtype: int
|
|
66
|
+
"""
|
|
67
|
+
x, y = self.position
|
|
68
|
+
|
|
69
|
+
if isinstance(x, str):
|
|
70
|
+
x_index = self.grid.string_to_index(x, axis='x')
|
|
71
|
+
else:
|
|
72
|
+
x_index = self.grid.position_to_index(x, axis='x')
|
|
73
|
+
|
|
74
|
+
if isinstance(y, str):
|
|
75
|
+
y_index = self.grid.string_to_index(y, axis='y')
|
|
76
|
+
else:
|
|
77
|
+
y_index = self.grid.position_to_index(y, axis='y')
|
|
78
|
+
|
|
79
|
+
return x_index, y_index
|
|
80
|
+
|
|
81
|
+
def interpret_position_to_position(self) -> tuple:
|
|
82
|
+
"""
|
|
83
|
+
Interprets and returns the value of positions x and y of the waveguide
|
|
84
|
+
|
|
85
|
+
:returns: The index of width and height
|
|
86
|
+
:rtype: int
|
|
87
|
+
"""
|
|
88
|
+
x, y = self.position
|
|
89
|
+
|
|
90
|
+
coordinate = self.grid.get_coordinate(x=x, y=y)
|
|
91
|
+
|
|
92
|
+
return coordinate.x, coordinate.y
|
|
93
|
+
|
|
94
|
+
def add_to_mesh(self, epsilon_r_mesh: numpy.ndarray) -> None:
|
|
95
|
+
epsilon_r_mesh += self.epsilon_r_mesh
|
|
96
|
+
|
|
97
|
+
def add_non_linear_effect_to_field(self, field: numpy.ndarray) -> None:
|
|
98
|
+
chi_2 = 1e10
|
|
99
|
+
|
|
100
|
+
field += self.idx * self.grid.dt**2 / (self.epsilon_r_mesh * Physics.epsilon_0 * Physics.mu_0) * chi_2 * field ** 2
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
from typing import Tuple, Union, NoReturn
|
|
5
|
+
from pydantic.dataclasses import dataclass
|
|
6
|
+
import numpy
|
|
7
|
+
from LightWave2D.grid import Grid
|
|
8
|
+
from LightWave2D.components.base_class import BaseComponent
|
|
9
|
+
from matplotlib.path import Path
|
|
10
|
+
import shapely.geometry as geo
|
|
11
|
+
from matplotlib import patches
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
config_dict = dict(
|
|
15
|
+
kw_only=True,
|
|
16
|
+
extra='forbid',
|
|
17
|
+
slots=True,
|
|
18
|
+
arbitrary_types_allowed=True
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(config=config_dict)
|
|
23
|
+
class Waveguide(BaseComponent):
|
|
24
|
+
"""
|
|
25
|
+
Represents a waveguide in a simulation grid.
|
|
26
|
+
|
|
27
|
+
Attributes:
|
|
28
|
+
grid (Grid): The grid of the simulation mesh.
|
|
29
|
+
width (int | str): Width of the waveguide in grid cells or 'full' for full width.
|
|
30
|
+
height (int | str): Height of the waveguide in grid cells or 'full' for full height.
|
|
31
|
+
position (tuple): Starting position of the waveguide.
|
|
32
|
+
epsilon_r (float): Relative permittivity inside the waveguide.
|
|
33
|
+
"""
|
|
34
|
+
grid: Grid
|
|
35
|
+
width: Union[int | str]
|
|
36
|
+
height: Union[int | str]
|
|
37
|
+
position: Tuple[float | str, float | str]
|
|
38
|
+
epsilon_r: float
|
|
39
|
+
facecolor: str = 'lightblue'
|
|
40
|
+
edgecolor: str = 'blue'
|
|
41
|
+
|
|
42
|
+
def build_mesh(self) -> NoReturn:
|
|
43
|
+
"""
|
|
44
|
+
Build the permittivity mesh for the waveguide.
|
|
45
|
+
"""
|
|
46
|
+
width_index, height_index = self._interpret_width_height()
|
|
47
|
+
x_index, y_index = self._interpret_position_to_index()
|
|
48
|
+
|
|
49
|
+
x_start, x_end = x_index, x_index + width_index
|
|
50
|
+
y_start, y_end = y_index, y_index + height_index
|
|
51
|
+
|
|
52
|
+
self.epsilon_r_mesh[x_start:x_end, y_start:y_end] = self.epsilon_r
|
|
53
|
+
|
|
54
|
+
def _interpret_width_height(self) -> Tuple[float, float]:
|
|
55
|
+
"""
|
|
56
|
+
Interpret and return the width and height of the waveguide in grid indices.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
tuple: The indices of the width and height.
|
|
60
|
+
"""
|
|
61
|
+
if isinstance(self.width, str) and self.width.lower() == 'full':
|
|
62
|
+
width_index = self.grid.n_x
|
|
63
|
+
else:
|
|
64
|
+
width_index = self.grid.position_to_index(self.width, axis='x')
|
|
65
|
+
|
|
66
|
+
if isinstance(self.height, str) and self.height.lower() == 'full':
|
|
67
|
+
height_index = self.grid.n_y
|
|
68
|
+
else:
|
|
69
|
+
height_index = self.grid.position_to_index(self.height, axis='y')
|
|
70
|
+
|
|
71
|
+
return int(width_index), int(height_index)
|
|
72
|
+
|
|
73
|
+
def _interpret_position_to_index(self) -> Tuple[int, int]:
|
|
74
|
+
"""
|
|
75
|
+
Interpret and return the indices for the positions x and y of the waveguide.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
tuple: The indices of the x and y positions.
|
|
79
|
+
"""
|
|
80
|
+
x, y = self.position
|
|
81
|
+
x_index = self.grid.string_to_position_x(x) if isinstance(x, str) else self.grid.position_to_index(x, axis='x')
|
|
82
|
+
y_index = self.grid.string_to_position_y(y) if isinstance(y, str) else self.grid.position_to_index(y, axis='y')
|
|
83
|
+
return x_index, y_index
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclass(config=config_dict)
|
|
87
|
+
class Square(BaseComponent):
|
|
88
|
+
"""
|
|
89
|
+
Represents a square scatterer in a simulation grid.
|
|
90
|
+
|
|
91
|
+
Attributes:
|
|
92
|
+
grid (Grid): The grid of the simulation mesh.
|
|
93
|
+
position (Tuple[float | str, float | str]): Starting position of the scatterer (center of the square).
|
|
94
|
+
epsilon_r (float): Relative permittivity inside the scatterer.
|
|
95
|
+
side_length (float): Side length of the square scatterer.
|
|
96
|
+
"""
|
|
97
|
+
grid: Grid
|
|
98
|
+
position: Tuple[float | str, float | str]
|
|
99
|
+
epsilon_r: float
|
|
100
|
+
side_length: float
|
|
101
|
+
facecolor: str = 'lightblue'
|
|
102
|
+
edgecolor: str = 'blue'
|
|
103
|
+
|
|
104
|
+
def compute_path(self) -> NoReturn:
|
|
105
|
+
x0, y0 = self.position
|
|
106
|
+
self.coordinate = self.grid.get_coordinate(x=x0, y=y0)
|
|
107
|
+
|
|
108
|
+
half_side = self.side_length / 2
|
|
109
|
+
self.x_start = (self.coordinate.x - half_side)
|
|
110
|
+
self.x_end = (self.coordinate.x + half_side)
|
|
111
|
+
self.y_start = (self.coordinate.y - half_side)
|
|
112
|
+
self.y_end = (self.coordinate.y + half_side)
|
|
113
|
+
|
|
114
|
+
p0 = geo.Point(self.x_start, self.y_start)
|
|
115
|
+
p1 = geo.Point(self.x_start, self.y_end)
|
|
116
|
+
p2 = geo.Point(self.x_end, self.y_start)
|
|
117
|
+
p3 = geo.Point(self.x_end, self.y_end)
|
|
118
|
+
|
|
119
|
+
self.polygon = geo.Polygon([p0, p1, p3, p2])
|
|
120
|
+
|
|
121
|
+
self.path = Path(numpy.array(self.polygon.exterior.coords))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@dataclass(config=config_dict)
|
|
125
|
+
class Circle(BaseComponent):
|
|
126
|
+
"""
|
|
127
|
+
Represents a scatterer in a simulation grid.
|
|
128
|
+
|
|
129
|
+
Attributes:
|
|
130
|
+
grid (Grid): The grid of the simulation mesh.
|
|
131
|
+
position (Tuple[float | str, float | str]): Starting position of the scatterer.
|
|
132
|
+
epsilon_r (float): Relative permittivity inside the scatterer.
|
|
133
|
+
radius (float): Radius of the scatterer.
|
|
134
|
+
"""
|
|
135
|
+
grid: Grid
|
|
136
|
+
position: Tuple[float | str, float | str]
|
|
137
|
+
epsilon_r: float
|
|
138
|
+
radius: float
|
|
139
|
+
facecolor: str = 'lightblue'
|
|
140
|
+
|
|
141
|
+
def compute_path(self) -> NoReturn:
|
|
142
|
+
x0, y0 = self.position
|
|
143
|
+
self.coordinate = self.grid.get_coordinate(x=x0, y=y0)
|
|
144
|
+
self.polygon = geo.Point(self.coordinate.x, self.coordinate.y).buffer(self.radius)
|
|
145
|
+
self.path = Path(numpy.array(self.polygon.exterior.coords))
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@dataclass(config=config_dict)
|
|
149
|
+
class Ellipse(BaseComponent):
|
|
150
|
+
"""
|
|
151
|
+
Represents a scatterer in a simulation grid.
|
|
152
|
+
|
|
153
|
+
Attributes:
|
|
154
|
+
grid (Grid): The grid of the simulation mesh.
|
|
155
|
+
position (Tuple[float | str, float | str]): Starting position of the scatterer.
|
|
156
|
+
epsilon_r (float): Relative permittivity inside the scatterer.
|
|
157
|
+
width (float):
|
|
158
|
+
height (float):
|
|
159
|
+
angle (float):
|
|
160
|
+
"""
|
|
161
|
+
grid: Grid
|
|
162
|
+
position: Tuple[float | str, float | str]
|
|
163
|
+
width: float
|
|
164
|
+
height: float
|
|
165
|
+
epsilon_r: float
|
|
166
|
+
angle: float = 0
|
|
167
|
+
facecolor: str = 'lightblue'
|
|
168
|
+
edgecolor: str = 'blue'
|
|
169
|
+
|
|
170
|
+
def compute_path(self) -> NoReturn:
|
|
171
|
+
x0, y0 = self.position
|
|
172
|
+
self.coordinate = self.grid.get_coordinate(x=x0, y=y0)
|
|
173
|
+
|
|
174
|
+
polygon = patches.Ellipse(
|
|
175
|
+
(self.coordinate.x, self.coordinate.y),
|
|
176
|
+
width=self.width,
|
|
177
|
+
height=self.height,
|
|
178
|
+
angle=self.angle
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
vertices = polygon.get_verts()
|
|
182
|
+
self.polygon = geo.Polygon(vertices)
|
|
183
|
+
self.path = Path(numpy.array(self.polygon.exterior.coords))
|
|
184
|
+
|
|
185
|
+
# -
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
from typing import Tuple, Union, NoReturn
|
|
5
|
+
from dataclasses import field
|
|
6
|
+
import numpy
|
|
7
|
+
from LightWave2D.grid import Grid
|
|
8
|
+
from MPSPlots.render2D import SceneList
|
|
9
|
+
import shapely.geometry as geo
|
|
10
|
+
from matplotlib.path import Path
|
|
11
|
+
import cv2
|
|
12
|
+
from pydantic.dataclasses import dataclass
|
|
13
|
+
from LightWave2D.components.base_class import BaseComponent
|
|
14
|
+
import matplotlib.pyplot as plt
|
|
15
|
+
|
|
16
|
+
config_dict = dict(
|
|
17
|
+
kw_only=True,
|
|
18
|
+
slots=True,
|
|
19
|
+
extra='forbid',
|
|
20
|
+
arbitrary_types_allowed=True
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(config=config_dict)
|
|
25
|
+
class PointDetector(BaseComponent):
|
|
26
|
+
"""
|
|
27
|
+
Represents a point detector within a simulation grid.
|
|
28
|
+
|
|
29
|
+
Attributes:
|
|
30
|
+
grid (Grid): The simulation mesh grid.
|
|
31
|
+
position (Tuple[float | str, float | str]): The (x, y) coordinates of the point detector on the grid.
|
|
32
|
+
data (numpy.ndarray): The data collected by the detector over time.
|
|
33
|
+
"""
|
|
34
|
+
grid: Grid
|
|
35
|
+
position: Union[Tuple[float | str, float | str]]
|
|
36
|
+
data: numpy.ndarray = field(init=False)
|
|
37
|
+
facecolor: str = 'blue'
|
|
38
|
+
|
|
39
|
+
def __post_init__(self):
|
|
40
|
+
"""
|
|
41
|
+
Initialize the PointDetector by converting the given position into
|
|
42
|
+
grid coordinates and initializing the data array.
|
|
43
|
+
"""
|
|
44
|
+
x, y = self.position
|
|
45
|
+
|
|
46
|
+
self.p0 = self.grid.get_coordinate(x=x, y=y)
|
|
47
|
+
|
|
48
|
+
self.polygon = geo.Point(self.p0.x, self.p0.y)
|
|
49
|
+
|
|
50
|
+
self.path = Path(self.polygon.coords)
|
|
51
|
+
|
|
52
|
+
self.data = numpy.zeros(self.grid.n_steps)
|
|
53
|
+
|
|
54
|
+
def update_data(self, field: numpy.ndarray) -> NoReturn:
|
|
55
|
+
"""
|
|
56
|
+
Update the detector data based on the provided field values.
|
|
57
|
+
|
|
58
|
+
Parameters:
|
|
59
|
+
field (numpy.ndarray): The field values to update the detector data.
|
|
60
|
+
"""
|
|
61
|
+
self.data = field[:, self.p0.x_index, self.p0.y_index]
|
|
62
|
+
|
|
63
|
+
def plot_data(self) -> SceneList:
|
|
64
|
+
"""
|
|
65
|
+
Plot the detector data over time.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
SceneList: A scene list containing the plot.
|
|
69
|
+
"""
|
|
70
|
+
scene = SceneList()
|
|
71
|
+
ax = scene.append_ax()
|
|
72
|
+
ax.add_line(x=self.grid.time_stamp, y=self.data)
|
|
73
|
+
return scene
|
|
74
|
+
|
|
75
|
+
def add_to_ax(self, ax: plt.axis) -> NoReturn:
|
|
76
|
+
"""
|
|
77
|
+
Add the scatterer to the provided axis as a circle.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
ax (Axis): The axis to which the scatterer will be added.
|
|
81
|
+
"""
|
|
82
|
+
ax.scatter(
|
|
83
|
+
self.p0.x,
|
|
84
|
+
self.p0.y,
|
|
85
|
+
color=self.facecolor
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import LightWave2D
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
'root_path',
|
|
10
|
+
'project_path',
|
|
11
|
+
'doc_path',
|
|
12
|
+
'doc_css_path',
|
|
13
|
+
'version_path',
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
root_path = Path(LightWave2D.__path__[0])
|
|
17
|
+
|
|
18
|
+
project_path = root_path.parents[0]
|
|
19
|
+
|
|
20
|
+
doc_path = project_path.joinpath('docs')
|
|
21
|
+
|
|
22
|
+
doc_css_path = doc_path.joinpath('source/_static/default.css')
|
|
23
|
+
|
|
24
|
+
version_path = root_path.joinpath('VERSION')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if __name__ == '__main__':
|
|
28
|
+
for path_name in __all__:
|
|
29
|
+
path = locals()[path_name]
|
|
30
|
+
print(path)
|
|
31
|
+
assert path.exists(), f"Path {path_name} do not exists"
|
|
32
|
+
|
|
33
|
+
# -
|