#! /usr/bin/python3 # Test program for module {path} # Last edited on 2021-09-30 13:12:40 by stolfi import raster import path import path_hp import rootray_shape import raster_example import path_example import move import move_parms import contact import hacks import palette import job_parms import rn import rmxn import pyx import sys from math import sqrt, sin, cos, floor, ceil, inf, nan, pi parms = job_parms.typical_js() parms['solid_raster_width'] = 1.0 parms['contour_trace_width'] = 0.5 mp_jump = move_parms.make_for_jumps(parms) mp_cont = move_parms.make_for_contours(parms) mp_fill = move_parms.make_for_fillings(parms) wd_fill = move_parms.width(mp_fill) def plot(OPHS, LKS, CTS, B, tag): # Plots the paths {OPHS}, the links {LKS}, and the contacts {CTS}. # Plot files are "tests/out/raster_regroup_TST_{tag}.{ext}" # where {ext} is "png", "jpg", "eps". nph = len(OPHS) nlk = len(LKS) nct = len(CTS) assert nph + nlk + nct > 0, "nothing to plot" # Grow the box as needed to include everything: B = rn.box_join(B, path.bbox(OPHS)) B = rn.box_join(B, path.bbox(LKS)) B = rn.box_join(B, contact.bbox(CTS)) dp = (0,0) frame = False grid = True c,szx,szy = hacks.make_canvas(B, dp, frame, grid, 1, 1) wd_axes = 0.05*wd_fill if nph > 0: CLRS_ph = hacks.trace_colors(nph) rwd_ph = 0.80 axes_ph = False dots_ph = False arrows_ph = True matter_ph = True path.plot_standard(c, OPHS, dp, None, CLRS_ph, rwd_ph, wd_axes, axes_ph, dots_ph, arrows_ph, matter_ph) if nlk > 0: CLRS_lk = hacks.link_colors(nph) rwd_lk = 0.60 axes_lk = True dots_lk = True arrows_lk = False matter_lk = False path.plot_standard(c, LKS, dp, None, CLRS_lk, rwd_lk, wd_axes, axes_lk, dots_lk, arrows_lk, matter_lk) if nct > 0: clr_ct = pyx.color.rgb(1.000, 0.100, 0.000) wd_ct = 2*wd_axes sz_tics_ct = 0 arrows_ct = False for ct in CTS: contact.plot_single(c, ct, dp, clr_ct, wd_ct, sz_tics_ct, arrows_ct) fname = "tests/out/raster_TST" "_" + tag hacks.write_plot(c, fname) return # ---------------------------------------------------------------------- def test_basic(): sys.stderr.write("--- testing {get_spacing_and_phase,scanline_index,sort_by_scanline,separate_by_scanline} ---\n") xdir = ( cos(pi/6), sin(pi/6) ) ydir = ( -xdir[1], +xdir[0] ) ystep_exp = wd_fill yphase_exp = 0.48*wd_fill eps = 0.15*wd_fill OPHS = raster_example.rasters_A(mp_fill, xdir, ydir, yphase_exp, eps) nph = len(OPHS) assert nph == 8 ystep, yphase = raster.get_spacing_and_phase(OPHS, xdir, ydir) sys.stderr.write("ystep = %20.16f yphase = %20.16f\n" % (ystep, yphase)) assert abs(ystep - ystep_exp) <= 0.5*eps assert abs(yphase - yphase_exp) <= 0.5*eps assert raster.scanline_index(OPHS[0], xdir, ydir, ystep, yphase) == 0 assert raster.scanline_index(OPHS[1], xdir, ydir, ystep, yphase) == 0 assert raster.scanline_index(OPHS[2], xdir, ydir, ystep, yphase) == 1 assert raster.scanline_index(OPHS[3], xdir, ydir, ystep, yphase) == 2 assert raster.scanline_index(OPHS[4], xdir, ydir, ystep, yphase) == 2 assert raster.scanline_index(OPHS[5], xdir, ydir, ystep, yphase) == 2 assert raster.scanline_index(OPHS[6], xdir, ydir, ystep, yphase) == 3 assert raster.scanline_index(OPHS[7], xdir, ydir, ystep, yphase) == 3 # Scramble the paths: OPHS_scr = [ OPHS[3], OPHS[4], OPHS[5], OPHS[2], OPHS[6], OPHS[0], OPHS[1], OPHS[7], ] # Sort them: OPHS_srt = raster.sort_by_scanline(OPHS_scr, xdir, ydir, ystep, yphase) assert len(OPHS_srt) == nph for k in range(nph): assert OPHS_srt[k] == OPHS[k] # Separate by scanline: SCS = raster.separate_by_scanline(OPHS, xdir, ydir, ystep, yphase) sys.stderr.write("len(SCS) = %d\n" % len(SCS)) sys.stderr.write("SCS = %s\n" % SCS) assert len(SCS) == 4 assert len(SCS[0]) == 2 assert SCS[0][0] == 0 assert SCS[0][1] == 1 assert len(SCS[1]) == 1 assert SCS[1][0] == 2 assert len(SCS[2]) == 3 assert SCS[2][0] == 3 assert SCS[2][1] == 4 assert SCS[2][2] == 5 assert len(SCS[3]) == 2 assert SCS[3][0] == 6 assert SCS[3][1] == 7 return # ---------------------------------------------------------------------- def test_links(): sys.stderr.write("--- testing {make_raster_raster_link,create_all_raster_raster_links} ---\n") xdir = ( cos(pi/6), sin(pi/6) ) ydir = ( -xdir[1], +xdir[0] ) yphase = 0.48*wd_fill eps = 0.03*wd_fill OPHS = raster_example.rasters_A(mp_fill, xdir, ydir, yphase, eps) assert len(OPHS) == 8 sys.stderr.write(" ... raster elements ...\n") path.show_list(sys.stderr, OPHS, True, 2) mp_link = mp_fill for oph in OPHS: path_hp.clear_links(oph) lk00 = raster.make_raster_raster_link(OPHS[0], OPHS[2], mp_link, "foo") sys.stderr.write("lk00 = %s\n" % lk00) assert lk00 != None assert path.pini(lk00) == path.pini(OPHS[0]) assert path.pfin(lk00) == path.pini(OPHS[2]) LKS0ini = path.get_links(OPHS[0]) LKS2ini = path.get_links(OPHS[2]) sys.stderr.write("get_links(OPHS[0]) = %s\n" % LKS0ini) sys.stderr.write("get_links(OPHS[2]) = %s\n" % LKS2ini) assert tuple(LKS0ini) == ( path.rev(lk00), ) assert tuple(LKS2ini) == ( lk00, ) lk20 = raster.make_raster_raster_link(path.rev(OPHS[1]), path.rev(OPHS[2]), mp_link, "bar") sys.stderr.write("lk20 = %s\n" % lk20) assert lk20 != None assert path.pini(lk20) == path.pfin(OPHS[1]) assert path.pfin(lk20) == path.pfin(OPHS[2]) LKS1fin = path.get_links(path.rev(OPHS[1])) LKS2fin = path.get_links(path.rev(OPHS[2])) sys.stderr.write("get_links(~OPHS[1]) = %s\n" % LKS1fin) sys.stderr.write("get_links(~OPHS[2]) = %s\n" % LKS2fin) assert tuple(LKS1fin) == ( path.rev(lk20), ) assert tuple(LKS2fin) == ( path.spin(lk20,0), ) lk23 = raster.make_raster_raster_link(path.rev(OPHS[4]), path.rev(OPHS[7]), mp_link, "qux") sys.stderr.write("lk23 = %s\n" % lk23) assert lk23 != None assert path.pini(lk23) == path.pfin(OPHS[4]) assert path.pfin(lk23) == path.pfin(OPHS[7]) # ??? Check {get_links} etc. more ??? for oph in OPHS: path.clear_links(oph) LKS = raster.create_all_raster_raster_links(OPHS, xdir, ydir, mp_link) sys.stderr.write(" ... link paths ...\n") path.show_list(sys.stderr, LKS, True, 2) # ??? Check {get_links} etc. more ??? plot(OPHS, LKS, [], None, "test_links") return # ---------------------------------------------------------------------- def test_contacts(): sys.stderr.write("--- testing {create_all_raster_raster_contacts} ---\n") xdir = ( cos(pi/6), sin(pi/6) ) ydir = ( -xdir[1], +xdir[0] ) yphase = 0.48*wd_fill eps = 0.03*wd_fill OPHS = raster_example.rasters_A(mp_fill, xdir, ydir, yphase, eps) assert len(OPHS) == 8 sys.stderr.write(" ... raster elements ...\n") path.show_list(sys.stderr, OPHS, True, 2) for oph in OPHS: path_hp.clear_contacts(oph) CTS = raster.create_all_raster_raster_contacts(OPHS, xdir, ydir) sys.stderr.write(" ... contacts ...\n") contact.show_list(sys.stderr, CTS, 2) # ??? Check {get_contacts} etc. more ??? plot(OPHS, [], CTS, None, "test_contacts") return # ---------------------------------------------------------------------- def test_from_shape_aux(SH, B, xdir,ydir, tag): ystep = wd_fill yphase = 0.48*wd_fill sys.stderr.write("... sub-test %s...\n" % tag) PTRS = raster.endpoints_from_shape(SH, B, xdir, ydir, ystep, yphase) OPHS = raster.from_endpoints(PTRS, mp_fill) plot(OPHS, [], [], B, "test_from_shape_" + tag) return # ---------------------------------------------------------------------- def make_rect_shape(name, plo, phi, mag, sgn): # Makes a closed rectangular path with those two corners, scaled by {mag}. # If {sgn} is {+1} the path is CCW, if {sgn} is {-1} it is CW. S = rootray_shape.box(rn.scale(mag, plo), rn.scale(mag, phi)) if sgn == -1: S = rootray_shape.complement(S) return S # ---------------------------------------------------------------------- def make_circ_shape(name, ctr, R, mag, sgn): C = rootray_shape.quadric(2, 2, -1) Rm = mag*R Adir = ((Rm, 0), (0, Rm)); bdir = rn.scale(mag,ctr) Ainv = ((1/Rm, 0), (0, 1/Rm)); binv = rn.scale(-1, rmxn.map_row(bdir, Ainv)) S = rootray_shape.affine(C, Ainv, binv) if sgn == -1: S = rootray_shape.complement(S) return S # ---------------------------------------------------------------------- def test_from_shape(): sys.stderr.write("--- testing {from_shape} ---\n") xdir = ( 1, 0 ) ydir = ( 0, 1 ) Box = ((-1,-1), (60,35)) # Some nested contours: A = make_rect_shape("A", ( 0, 0), (16,10), 3, +1) B = make_rect_shape("B", ( 1, 1), ( 2, 9), 3, -1) C = make_rect_shape("C", ( 3, 1), (10, 9), 3, -1) D = make_rect_shape("D", (11, 6), (15, 9), 3, -1) E = make_circ_shape("E", (13, 3), 2, 3, -1) F = make_rect_shape("F", ( 4, 6), ( 9, 8), 3, +1) G = make_rect_shape("G", ( 4, 2), ( 5, 5), 3, +1) H = make_rect_shape("H", ( 6, 2), ( 9, 5), 3, +1) I = make_rect_shape("I", ( 7, 3), ( 8, 4), 3, -1) J = make_circ_shape("J", (13, 3), 1, 3, +1) U = make_rect_shape("U", (17, 0), (19, 4), 3, +1) V = make_rect_shape("V", (17, 8), (19,10), 3, +1) # ---------------------------------------------------------------------- SH = J test_from_shape_aux(SH, Box, xdir,ydir, "10_circ") # ---------------------------------------------------------------------- SH = rootray_shape.union([ A, U ]) test_from_shape_aux(SH, Box, xdir,ydir, "20_2sqr") # ---------------------------------------------------------------------- SH = rootray_shape.intersection([ A, C ]) test_from_shape_aux(SH, Box, xdir,ydir, "30_sqhole") # ---------------------------------------------------------------------- SH = rootray_shape.intersection([ A, rootray_shape.complement(F) ]) test_from_shape_aux(SH, Box, xdir,ydir, "40_revhole") # ---------------------------------------------------------------------- xdir = ( cos(pi/6), sin(pi/6) ) ydir = ( -xdir[1], +xdir[0] ) HI = rootray_shape.intersection([ H, I ]) EJ = rootray_shape.union([ E, J ]) CFGHI = rootray_shape.union([ C, F, G, HI ]) BCDEFGHIJ = rootray_shape.intersection([ B, CFGHI, D, EJ ]) ABCDEFGHIJ = rootray_shape.intersection([ A, BCDEFGHIJ ]) ABCDEFGHIJUV = rootray_shape.union([ ABCDEFGHIJ, U, V ]) # SH = EJ # SH = CFGHI # SH = BCDEFGHIJ # SH = ABCDEFGHIJ SH = ABCDEFGHIJUV # Rotate the shape so sides are parallel to {xdir,ydir}: Adir = (xdir, ydir); bdir = (0,0) Ainv = ((xdir[0], ydir[0]), (xdir[1],ydir[1])); binv = (0,0) SH = rootray_shape.affine(SH, Ainv, binv) Box = rmxn.box_affine(Box, Adir, bdir) test_from_shape_aux(SH, Box, xdir,ydir, "50_bigtilt") return # ---------------------------------------------------------------------- # test_basic() # test_links() # test_contacts() test_from_shape()