Habe Darstellende Geometrie Beispiel mit sympy nachcodiert
und würde die Elemente gerne in einem Plot betrachten.
Wie geht das am komfortabelsten

Danke für Euren Tip
Erhy
äquivalente Ansätze gibt.import matplotlib.lines as lines
from matplotlib import artist
Code: Alles auswählen
# PlotSympyGeometryWithMatPlotLibExample.py by Erhy
import matplotlib.lines as mlines
import matplotlib.pyplot as plt
from matplotlib import patches
import sympy.geometry as geom
from sympy import Rational, pi
# import numpy as np #is numpy used here ?
plotArtists = [] #MatPlotLib artists to plot
plot_xlim = (0, .300)
plot_ylim = (0, .255)
plot_xlimR = ( Rational(str(plot_xlim[0])), Rational(str(plot_xlim[1])) )
plot_ylimR = ( Rational(str(plot_ylim[0])), Rational(str(plot_ylim[1])) )
# plot area for conversion from sympy.geometry elements to MatPlotLib artists
rect0 = geom.Polygon((plot_xlimR[0], plot_ylimR[0]),
(plot_xlimR[1], plot_ylimR[0]),
(plot_xlimR[1], plot_ylimR[1]),
(plot_xlimR[0], plot_ylimR[1]))
# # # conversion from sympy.geometry elements to Matplotlib artists # # #
def addGeomForPlot(sympyZs):
rect0j = rect0 # plot area
def twoIntersectionWithBorder( pois ) :
p1 = [pois[0].args[0], pois[0].args[1]]
p2 = [pois[1].args[0], pois[1].args[1]]
resul = mlines.Line2D([float(p1[0]), float(p2[0])],
[float(p1[1]), float(p2[1])])
return resul
for sympyZ in sympyZs:
# if type(sympyZ) is geom.line.Line2D :
typstr = str(type(sympyZ))
if typstr == "<class 'sympy.geometry.line.Segment2D'>":
pois = geom.intersection(rect0j, sympyZ)
if len(pois) == 2: # two points
result = twoIntersectionWithBorder( pois )
result.set_linewidth( 2 )
plotArtists.append(result)
elif len(pois) == 1: # one point
# find the other point of the segment, which is inside the borders
if rect0j.encloses_point(sympyZ.args[0]) :
poi2 = sympyZ.args[0]
else:
poi2 = sympyZ.args[1]
p1 = [pois[0].args[0], pois[0].args[1]]
p2 = [poi2.args[0], poi2.args[1]]
result = mlines.Line2D([float(p1[0]), float(p2[0])],
[float(p1[1]), float(p2[1])],
linewidth=2)
plotArtists.append(result)
else:
if rect0j.encloses_point(sympyZ.args[0]) and rect0j.encloses_point(sympyZ.args[1]):
# inside the borders
result = mlines.Line2D([float(sympyZ.args[0].args[0]), float(sympyZ.args[1].args[0])],
[float(sympyZ.args[0].args[1]), float(sympyZ.args[1].args[1])],
linewidth=2)
plotArtists.append(result)
elif typstr == "<class 'sympy.geometry.line.Line2D'>":
rect0j = rect0
# pois = rect0j.intersection(sympyZ)
pois = geom.intersection(rect0j, sympyZ)
if len(pois) == 2: # two points
result = twoIntersectionWithBorder( pois )
result.set_linewidth( 1 )
plotArtists.append(result)
elif typstr == "<class 'sympy.geometry.line.Ray2D'>":
rect0j = rect0
pois = geom.intersection(rect0j, sympyZ)
if len(pois) == 2: # two points
result = twoIntersectionWithBorder( pois )
result.set_linewidth( 1 )
plotArtists.append(result)
elif len(pois) == 1:
p1 = [float(pois[0].args[0]), float(pois[0].args[1])]
pSource = sympyZ.source
p2 = [float(pSource.args[0]), float(pSource.args[1])]
result = mlines.Line2D([p1[0], p2[0]],
[p1[1], p2[1]], linewidth=1)
plotArtists.append(result)
elif typstr == "<class 'sympy.geometry.ellipse.Circle'>":
result = patches.Circle((float(sympyZ.args[0].args[0]), float(sympyZ.args[0].args[1]),
), float(sympyZ.args[1]), linewidth=1, fill=False)
plotArtists.append(result)
# # example for visual check of angle computation # #
poiA = [Rational('0.04'), Rational('0.015')]
poiB = [Rational('0.135'), Rational('0.05')]
poiC = [Rational('0.210'), Rational('0.140')]
p1, p2, p3 = geom.Point(poiA), geom.Point(poiB), geom.Point(poiC)
r0 = Rational('0.0') #zero
l0 = geom.Line(geom.Point([r0, r0]), geom.Point([r0 + 1, r0])) # horizontal line
segm1, segm2 = geom.Segment(p1, p2), geom.Segment(p2, p3)
segmMinLen = min([segm1.length, segm2.length])
# circle
ci = geom.Circle(p2, segmMinLen)
# line for visual test:
lMittel = geom.Line(
segm1.intersection(ci)[0], segm2.intersection(ci)[0]). \
parallel_line(p2)
# angle computation
angSegm1 = l0.smallest_angle_between(segm1)
angSegm2 = l0.smallest_angle_between(segm2)
angStretch = angSegm1 + ((angSegm2 - angSegm1) / Rational('2.0'))
# degStretch = np.rad2deg(float(angStretch))
forGradAng = pi + angSegm1 + ((angStretch - angSegm1) / Rational('2.0'))
# degGradAng = np.rad2deg(float(forGradAng))
rayForGradient = geom.Ray(p2, angle=forGradAng)
addGeomForPlot([segm1, segm2, ci, lMittel, rayForGradient])
fig = plt.figure(figsize=(7, 7))
ax = fig.add_subplot(1, 1, 1, aspect=1)
ax.set_xlim(plot_xlim[0], plot_xlim[1])
ax.set_ylim(plot_ylim[0], plot_ylim[1])
for aj in plotArtists: # plot all artists
ax.add_artist(aj)
plt.show()
Code: Alles auswählen
p1 = [points[0].args[0], points[0].args[1]]
p2 = [points[1].args[0], points[1].args[1]]
# ->
p1 = points[0].args
p2 = points[1].args
Code: Alles auswählen
def make_2d_line_from_points(points):
return mlines.Line2D(
[point.args[0] for point in points],
[point.args[1] for point in points],
)
Code: Alles auswählen
#!/usr/bin/env python3
# PlotSympyGeometryWithMatPlotLibExample.py by Erhy
from matplotlib import patches
from matplotlib import lines as mlines
from matplotlib import pyplot as plt
from sympy import Rational, pi as PI
from sympy import geometry as geom
def make_2d_line_from_points(points, linewidth):
return mlines.Line2D(
[point.x for point in points],
[point.y for point in points],
linewidth=linewidth,
)
def convert_geometry_to_artists(plot_area, geometry_entities):
#
# TODO Use `functools.singledispatch` to break this up into smaller, self
# contained functions, so there's no chance of leaking values from one
# type/loop iteration to another.
#
for entity in geometry_entities:
if isinstance(entity, geom.line.Segment2D):
points = geom.intersection(plot_area, entity)
if len(points) == 2:
yield make_2d_line_from_points(points, 2)
elif len(points) == 1:
#
# Find the other point of the segment, which is inside the
# borders.
#
point_b = next(
point
for point in entity.args
if plot_area.encloses_point(point)
)
yield make_2d_line_from_points([points[0], point_b], 2)
else:
if all(map(plot_area.encloses_point, entity.args)):
# Completely inside the borders.
yield make_2d_line_from_points(entity.args, linewidth=2)
elif isinstance(entity, geom.line.Line2D):
points = geom.intersection(plot_area, entity)
if len(points) == 2:
yield make_2d_line_from_points(points, 1)
elif isinstance(entity, geom.line.Ray2D):
points = geom.intersection(plot_area, entity)
if len(points) == 2:
yield make_2d_line_from_points(points, 1)
elif len(points) == 1:
yield make_2d_line_from_points([points[0], entity.source], 1)
elif isinstance(entity, geom.ellipse.Circle):
yield patches.Circle(
entity.center, entity.radius, linewidth=1, fill=False
)
else:
raise ValueError(f"unknown geometry entity {entity!r}")
def main():
#
# Plot area for conversion from sympy.geometry elements to MatPlotLib
# artists.
#
plot_max_x = Rational("0.300")
plot_max_y = Rational("0.255")
plot_area = geom.Polygon(
(0, 0), (plot_max_x, 0), (plot_max_x, plot_max_y), (0, plot_max_y)
)
#
# Example for visual check of angle computation.
#
point_a = geom.Point([Rational("0.04"), Rational("0.015")])
point_b = geom.Point([Rational("0.135"), Rational("0.05")])
point_c = geom.Point([Rational("0.210"), Rational("0.140")])
horizontal_line = geom.Line(geom.Point([0, 0]), geom.Point([1, 0]))
segment_a = geom.Segment(point_a, point_b)
segment_b = geom.Segment(point_b, point_c)
min_segment_length = min(segment_a.length, segment_b.length)
circle = geom.Circle(point_b, min_segment_length)
# Line for visual test.
middle_line = geom.Line(
segment_a.intersection(circle)[0], segment_b.intersection(circle)[0]
).parallel_line(point_b)
# Angle computation.
segment_a_angle = horizontal_line.smallest_angle_between(segment_a)
segment_b_angle = horizontal_line.smallest_angle_between(segment_b)
angle_stretch = segment_a_angle + ((segment_b_angle - segment_a_angle) / 2)
gradient_angle = (
PI + segment_a_angle + ((angle_stretch - segment_a_angle) / 2)
)
gradient_ray = geom.Ray(point_b, angle=gradient_angle)
plot_artists = convert_geometry_to_artists(
plot_area, [segment_a, segment_b, circle, middle_line, gradient_ray]
)
figure = plt.figure(figsize=(7, 7))
axis = figure.add_subplot(1, 1, 1, aspect=1)
axis.set_xlim(0, float(plot_max_x))
axis.set_ylim(0, float(plot_max_y))
for artist in plot_artists:
axis.add_artist(artist)
plt.show()
if __name__ == "__main__":
main()
Code: Alles auswählen
#!/usr/bin/env python3
# PlotSympyGeometryWithMatPlotLibExample.py by Erhy
from functools import singledispatch
from matplotlib import lines, patches, pyplot as plt
from sympy import geometry, pi as PI, Rational
def make_2d_line_from_points(points, linewidth):
return lines.Line2D(
[point.x for point in points],
[point.y for point in points],
linewidth=linewidth,
)
@singledispatch
def convert_to_artist(geometry_entity, _plot_area):
raise ValueError(f"unknown geometry entity {geometry_entity!r}")
@convert_to_artist.register(geometry.line.Segment2D)
def _convert_segment(segment, plot_area):
points = plot_area.intersection(segment)
if len(points) == 2:
return make_2d_line_from_points(points, 2)
elif len(points) == 1:
#
# Find the other point of the segment, which is inside the
# borders.
#
point_b = next(filter(plot_area.encloses_point, segment.points))
return make_2d_line_from_points([points[0], point_b], 2)
elif all(map(plot_area.encloses_point, segment.points)):
# Completely inside the borders.
return make_2d_line_from_points(segment.points, linewidth=2)
else:
return None
@convert_to_artist.register(geometry.line.Line2D)
def _convert_line(line, plot_area):
points = geometry.intersection(plot_area, line)
return make_2d_line_from_points(points, 1) if len(points) == 2 else None
@convert_to_artist.register(geometry.line.Ray2D)
def _convert_ray(ray, plot_area):
points = plot_area.intersection(ray)
if len(points) == 2:
return make_2d_line_from_points(points, 1)
elif len(points) == 1:
return make_2d_line_from_points([points[0], ray.source], 1)
else:
return None
@convert_to_artist.register(geometry.ellipse.Circle)
def _convert_circle(circle, _plot_area):
return patches.Circle(
circle.center, circle.radius, linewidth=1, fill=False
)
def convert_geometries_to_artists(plot_area, geometry_entities):
for entity in geometry_entities:
artist = convert_to_artist(entity, plot_area)
if artist is not None:
yield artist
def create_geometry_entities():
"""Example for visual check of angle computation."""
point_a = geometry.Point([Rational("0.04"), Rational("0.015")])
point_b = geometry.Point([Rational("0.135"), Rational("0.05")])
point_c = geometry.Point([Rational("0.210"), Rational("0.140")])
segment_a = geometry.Segment(point_a, point_b)
segment_b = geometry.Segment(point_b, point_c)
min_segment_length = min(segment_a.length, segment_b.length)
circle = geometry.Circle(point_b, min_segment_length)
# Line for visual test.
middle_line = geometry.Line(
segment_a.intersection(circle)[0], segment_b.intersection(circle)[0]
).parallel_line(point_b)
# Angle computation.
horizontal_line = geometry.Line(
geometry.Point([0, 0]), geometry.Point([1, 0])
)
segment_a_angle = horizontal_line.smallest_angle_between(segment_a)
segment_b_angle = horizontal_line.smallest_angle_between(segment_b)
angle_stretch = segment_a_angle + ((segment_b_angle - segment_a_angle) / 2)
gradient_angle = (
PI + segment_a_angle + ((angle_stretch - segment_a_angle) / 2)
)
gradient_ray = geometry.Ray(point_b, angle=gradient_angle)
return [segment_a, segment_b, circle, middle_line, gradient_ray]
def main():
#
# Plot area for conversion from sympy.geometry elements to MatPlotLib
# artists.
#
plot_max_x = Rational("0.300")
plot_max_y = Rational("0.255")
plot_area = geometry.Polygon(
(0, 0), (plot_max_x, 0), (plot_max_x, plot_max_y), (0, plot_max_y)
)
plot_artists = convert_geometries_to_artists(
plot_area, create_geometry_entities()
)
figure = plt.figure(figsize=(7, 7))
axis = figure.add_subplot(1, 1, 1, aspect=1)
axis.set_xlim(0, float(plot_max_x))
axis.set_ylim(0, float(plot_max_y))
for artist in plot_artists:
axis.add_artist(artist)
plt.show()
if __name__ == "__main__":
main()
Wie meinst du das? Der Blog in seinem Profil verlinkt. Sehe ich nicht so sehr als Outen, wenn man den auch hier im Thread nennt.ThomasL hat geschrieben: Sonntag 15. September 2019, 11:34 @Erhy Ob ihm das so recht ist, von dir identitätsmäßig geoutet zu werden?