diff --git a/math/py-isosurfaces/Makefile b/math/py-isosurfaces/Makefile index 483527331f55..a547923ffd2d 100644 --- a/math/py-isosurfaces/Makefile +++ b/math/py-isosurfaces/Makefile @@ -1,31 +1,30 @@ PORTNAME= isosurfaces -DISTVERSION= 0.1.0 -PORTREVISION= 1 +DISTVERSION= 0.1.1 CATEGORIES= math MASTER_SITES= PYPI PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} MAINTAINER= yuri@FreeBSD.org COMMENT= Construct isolines/isosurfaces over a 2D/3D scalar field WWW= https://github.com/jared-hughes/isosurfaces LICENSE= MIT RUN_DEPENDS= ${PYNUMPY} TEST_DEPENDS= ${PYTHON_PKGNAMEPREFIX}cairo>0:graphics/py-cairo@${PY_FLAVOR} \ ${PYNUMPY} \ xdg-open:devel/xdg-utils USES= python USE_PYTHON= distutils autoplist NO_ARCH= yes TEST_ENV= ${MAKE_ENV} PYTHONPATH=${STAGEDIR}${PYTHONPREFIX_SITELIBDIR} do-test: @cd ${TEST_WRKSRC} && \ ${SETENV} ${TEST_ENV} ${PYTHON_CMD} ${FILESDIR}/isoline_demo.py && \ - xdg-open ${TEST_WRKSRC}/demo.svg + xdg-open ${TEST_WRKSRC}/out/demo.svg .include diff --git a/math/py-isosurfaces/distinfo b/math/py-isosurfaces/distinfo index f4588b9ff108..edfbd388daff 100644 --- a/math/py-isosurfaces/distinfo +++ b/math/py-isosurfaces/distinfo @@ -1,3 +1,3 @@ -TIMESTAMP = 1674236137 -SHA256 (isosurfaces-0.1.0.tar.gz) = fa1b44e5e59d2f429add49289ab89e36f8dcda49b7badd99e0beea273be331f4 -SIZE (isosurfaces-0.1.0.tar.gz) = 10122 +TIMESTAMP = 1708879297 +SHA256 (isosurfaces-0.1.1.tar.gz) = 18aab4ec7148a8376097b49006ea0e9ec07e468fa5fc6133d7d9eef977fe384d +SIZE (isosurfaces-0.1.1.tar.gz) = 11333 diff --git a/math/py-isosurfaces/files/isoline_demo.py b/math/py-isosurfaces/files/isoline_demo.py index 53bd1a51da61..a66bc0a0bf06 100644 --- a/math/py-isosurfaces/files/isoline_demo.py +++ b/math/py-isosurfaces/files/isoline_demo.py @@ -1,133 +1,186 @@ -# from examples/isoline_demo.py +# from isoline_demo.py """ Code for demo-ing and experimentation. Prepare for a mess """ -from isosurfaces import plot_isoline -from isosurfaces.isoline import ( - Cell, - build_tree, - Triangulator, - CurveTracer, -) -import numpy as np + +import os + import cairo +import numpy as np + +from isosurfaces import plot_isoline +from isosurfaces.isoline import Cell, CurveTracer, Triangulator, build_tree min_depth = 5 pmin = np.array([-8, -6]) pmax = np.array([8, 6]) def f(x, y): return y * (x - y) ** 2 - 4 * x - 8 # Here we directly use plot_implicit internals in order to see the quadtree fn = lambda u: f(u[0], u[1]) tol = (pmax - pmin) / 1000 quadtree = build_tree(2, fn, pmin, pmax, min_depth, 5000, tol) -triangles = Triangulator(quadtree, fn).triangulate() +triangles = Triangulator(quadtree, fn, tol).triangulate() curves = CurveTracer(triangles, fn, tol).trace() def g(x, y): - return x ** 3 - x - y ** 2 + return x**3 - x - y**2 # Typical usage curves1 = plot_isoline( lambda u: g(u[0], u[1]), pmin, pmax, min_depth=4, max_quads=1000, ) def h(x, y): - return x ** 4 + y ** 4 - np.sin(x) - np.sin(4 * y) + return x**4 + y**4 - np.sin(x) - np.sin(4 * y) curves2 = plot_isoline(lambda u: h(u[0], u[1]), pmin, pmax, 4, 1000) +def tanm(x, y): + return np.tan(x**2 + y**2) - 1 + + +curves3 = plot_isoline(lambda u: tanm(u[0], u[1]), pmin, pmax, 6, 5000) + + WIDTH = 640 HEIGHT = 480 def setup_context(c): # reflection to change math units to screen units scale = min(WIDTH / (pmax[0] - pmin[0]), HEIGHT / (pmax[1] - pmin[1])) c.scale(scale, -scale) c.translate(WIDTH / scale / 2, -HEIGHT / scale / 2) c.set_line_join(cairo.LINE_JOIN_BEVEL) def draw_axes(c): c.save() c.set_line_width(0.1) c.move_to(0, -100) c.line_to(0, 100) c.stroke() c.move_to(-100, 0) c.line_to(100, 0) c.stroke() c.restore() def draw_quad(c, quad: Cell): width = 0 if quad.depth <= min_depth: width = 0.02 elif quad.depth == min_depth + 1: width = 0.01 else: width = 0.005 c.set_line_width(0.5 * width) if quad.children: c.move_to(*((quad.vertices[0].pos + quad.vertices[1].pos) / 2)) c.line_to(*((quad.vertices[2].pos + quad.vertices[3].pos) / 2)) c.move_to(*((quad.vertices[0].pos + quad.vertices[2].pos) / 2)) c.line_to(*((quad.vertices[1].pos + quad.vertices[3].pos) / 2)) c.stroke() for child in quad.children: draw_quad(c, child) def draw_quads(c): c.save() draw_quad(c, quadtree) c.restore() +def draw_triangles(c): + c.save() + c.set_line_width(0.001) + for tri in triangles: + c.move_to(*tri.vertices[0].pos) + c.line_to(*tri.vertices[1].pos) + c.line_to(*tri.vertices[2].pos) + c.line_to(*tri.vertices[0].pos) + c.stroke() + c.restore() + + +def draw_signs(c): + c.save() + for tri in triangles: + for vert in tri.vertices: + vert.drawn = False + for tri in triangles: + for vert in tri.vertices: + if vert.drawn: + continue + vert.drawn = True + if vert.val > 0: + c.set_source_rgb(0.2, 0.2, 1) + else: + c.set_source_rgb(1, 0.2, 0.2) + w = 0.01 + c.rectangle(vert.pos[0] - w, vert.pos[1] - w, 2 * w, 2 * w) + c.fill() + c.restore() + + def draw_bg(c): c.save() c.set_source_rgb(1, 1, 1) c.paint() c.restore() def draw_curves(c, curves_list, rgb): - print( - "drawing", sum(map(len, curves_list)), "segments in", len(curves_list), "curves" - ) + print("drawing", sum(map(len, curves_list)), "segments in", len(curves_list), "curves") c.set_source_rgb(*rgb) # draw curves c.save() c.set_line_width(0.03) for curve in curves_list: c.move_to(*curve[0]) - for v in curve: + for v in curve[1:]: c.line_to(*v) c.stroke() c.restore() -with cairo.SVGSurface("demo.svg", WIDTH, HEIGHT) as surface: +def draw_curve_vertices(c, curves_list, rgb): + c.set_source_rgb(*rgb) + c.save() + w = 0.01 + for curve in curves_list: + for v in curve: + c.rectangle(v[0] - w, v[1] - w, 2 * w, 2 * w) + c.fill() + c.restore() + + +if not os.path.exists("out"): + os.mkdir("out") +with cairo.SVGSurface("out/demo.svg", WIDTH, HEIGHT) as surface: c = cairo.Context(surface) setup_context(c) draw_bg(c) draw_axes(c) # draw_quads(c) + # draw_triangles(c) + # draw_signs(c) draw_curves(c, curves, [0.1, 0.1, 0.8]) + # draw_curve_vertices(c, curves, [0.5, 0.8, 0.6]) draw_curves(c, curves1, [0.8, 0.1, 0.1]) draw_curves(c, curves2, [0.1, 0.6, 0.1]) + # draw_curves(c, curves3, [0.1, 0.4, 0.5])