gsl-shell.git - gsl-shell

index : gsl-shell.git
gsl-shell
summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat
-rw-r--r--contour.lua 3
-rw-r--r--examples/hpcontour-ex.lua 4
-rw-r--r--hpcontour.lua 369
3 files changed, 112 insertions, 264 deletions
diff --git a/contour.lua b/contour.lua
index 1731c852..4c49c4ed 100644
--- a/contour.lua
+++ b/contour.lua
@@ -718,7 +718,8 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
end
local function color(a)
- return rgba(0.9, 0.9 - 0.9*a, 0, 0.8)
+ -- return rgba(0.9, 0.9 - 0.9*a, 0, 0.8)
+ return rgba(0.91 - 0.565*a, 0.898 - 0.753*a, 0.85 - 0.25*a, 0.8)
end
local function curve_draw(pl, id)
diff --git a/examples/hpcontour-ex.lua b/examples/hpcontour-ex.lua
index d1cb3910..7623afcb 100644
--- a/examples/hpcontour-ex.lua
+++ b/examples/hpcontour-ex.lua
@@ -109,7 +109,7 @@ fthreepeaks = fpeaksmake {{6, 0, 0, 1, 1}, {-5, 1.5, 1, 1.45, 1.15}, {1.5, 2, -2
-- contour.plot(ftwopeaks, {-4, -4}, {5, 4}, 40, 40, 10)
-- contour.plot(fthreepeaks, {-4, -4}, {5, 4}, 40, 40, 15)
-- contour.plot(fsincos(0.1,0.3), {0, 0}, {14, 14}, 20, 20, 13)
--- contour.plot(fsincos(0.1,0.3), {-14, -14}, {14, 14}, 20, 20, 9)
+contour.plot(fsincos(0.1,0.3), {-14, -14}, {14, 14}, 20, 20, 10)
-- contour.plot(fsincos(0,0), {0, 0}, {4*pi, 4*pi}, 60, 60, 10)
-- contour.plot(flin, {-4, -4}, {4, 4})
-- contour.plot(fsqr, {-4, -4}, {4, 4})
@@ -124,6 +124,6 @@ for k=1,nlev do
end
contour.plot(frosenbrock, {-1.5, -0.5}, {1.5, 2}, 20, 20, zlev)
--- contour.plot(fpeaksmake {{6, 0, 0, 1, 1}, {-5, 1.5, 1, 1.45, 1.15}, {4, 2, -2, 0.8, 0.8}}, {-2, -4}, {5, 4}, 20, 20, 9)
+contour.plot(fpeaksmake {{6, 0, 0, 1, 1}, {-5, 1.5, 1, 1.45, 1.15}, {4, 2, -2, 0.8, 0.8}}, {-2, -4}, {5, 4}, 20, 20, 9)
-- NICE PLOT WITH THREE PEAKS
-- contour.plot(fpeaksmake {{6, 0, 0, 1, 1}, {-5, 1.5, 1, 1.45, 1.15}, {4, 2, -2, 0.8, 0.8}}, {-4, -4}, {5, 4}, 20, 20, 9)
diff --git a/hpcontour.lua b/hpcontour.lua
index b97c78f8..10e9ec76 100644
--- a/hpcontour.lua
+++ b/hpcontour.lua
@@ -24,14 +24,22 @@ local M = {}
local insert = table.insert
+local function reverse(ls)
+ local k, n = 1, #ls
+ while k < n do
+ ls[k], ls[n] = ls[n], ls[k]
+ k, n = k+1, n-1
+ end
+end
+
local function order_add_relation(t, a, b)
- if not t[a] then t[a] = {inf= {}} end
- if not t[b] then t[b] = {inf= {}} end
- t[b].inf[a] = true
+ if not t[a] then t[a] = {} end
+ if not t[b] then t[b] = {} end
+ t[b][a] = true
end
local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
- local cross, roots, lncross = {}, {}, {h= {}, v= {}}
+ local cross, roots, lncross = {}, {}, {}
local g = {z= {}, zmin= f(left), zmax= f(right)}
local dx = vector {(right[1] - left[1]) / nx, 0}
local dy = vector {0, (right[2] - left[2]) / ny}
@@ -58,8 +66,6 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
local function index(i,j) return j + i * (nx+1) end
- local function index_lookup(si) return divmod(si, nx+1) end
-
local function segment_index_i(i1, j1, i2, j2)
if i2 < i1 then i1, i2 = i2, i1 end
if j2 < j1 then j1, j2 = j2, j1 end
@@ -99,19 +105,6 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
return s
end
- local function bord_main_index(si)
- local i1, j1, i2, j2 = segment_index_lookup_i(si)
- local s, k
- if i1 == i2 then
- if i1 == 0 then s, k = 0, j1 elseif i1 == ny then s, k = 2, nx-j2
- else error 'not a boundary point' end
- else
- if j1 == 0 then s, k = 3, ny-i2 elseif j1 == nx then s, k = 1, i1
- else error 'not a boundary point' end
- end
- return s, k
- end
-
local function bord_point_index(p)
local epsilon = 1e-4 * ds
local DD = {right[1] - left[1], right[2] - left[2]}
@@ -179,7 +172,7 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
local nodes, nodes_order = {}, {}
local function add_node(p, id, level)
local nid = #nodes+1
- nodes[nid] = {p= p, curveid= id, level= level}
+ nodes[nid] = {p= p, curveid= id, level= level, theta= bord_point_index(p)}
return nid
end
@@ -197,10 +190,9 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
end
local function nodes_border_points(nid1, nid2)
- local n1, n2 = nodes[nid1], nodes[nid2]
+ local th1 = nodes[nid1].theta
+ local th2 = nodes[nid2].theta
- local th1 = bord_point_index(n1.p)
- local th2 = bord_point_index(n2.p)
if th2 < th1 then th2 = th2 + 4 end
return function()
@@ -211,6 +203,7 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
th1 = i1 + 1
return x, y
elseif th1 < th2 then
+ local n2 = nodes[nid2]
x, y = n2.p[1], n2.p[2]
th1 = th2
return x, y
@@ -218,28 +211,13 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
end
end
- local domains, domain_marks = {}, {}
+ local domains = {}
local function domain_add(dom)
local domid = #domains + 1
domains[domid] = dom
-
- local a0, a, b
for i, join in ipairs(dom) do
local curve = curves[join.id]
- local bp = b
- a, b = curve_extrema(curve, join.direction)
-
- curve.domain[join.direction]= domid
-
- if i == 1 then
- a0 = a
- else
- insert(domain_marks, {domid= domid, a= bp, b= a})
- end
-
- if i == #dom then
- insert(domain_marks, {domid= domid, a= b, b= a0})
- end
+ curve.domain[join.direction] = domid
end
return domid
end
@@ -248,26 +226,21 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
local th = bord_point_index(grid_point(i, j))
local function is_member(nid1, nid2)
- local th1 = bord_point_index(nodes[nid1].p)
- local th2 = bord_point_index(nodes[nid2].p)
- return angle_is_between(th, th1, th2)
+ return angle_is_between(th, nodes[nid1].theta, nodes[nid2].theta)
end
for domid, dom in ipairs(domains) do
- local it, term = {}, nil
- it.f, it.s, it.i = ipairs(dom)
- it.i, term = it.f(it.s, it.i)
- if not it.i then return domid end
- local nid0, nid1 = curve_extrema(curves[term.id], term.direction)
- while true do
- it.i, term = it.f(it.s, it.i)
- if not it.i then break end
-
- local nida, nidb = curve_extrema(curves[term.id], term.direction)
- if is_member(nid1, nida) then return domid end
- nid1 = nidb
+ local nid0, nid1
+ for _, term in ipairs(dom) do
+ if nid1 then
+ local nida, nidb = curve_extrema(curves[term.id], term.direction)
+ if is_member(nid1, nida) then return domid end
+ nid1 = nidb
+ else
+ nid0, nid1 = curve_extrema(curves[term.id], term.direction)
+ end
end
- if is_member(nid1, nid0) then return domid end
+ if not nid1 or is_member(nid1, nid0) then return domid end
end
error ('no domain found')
@@ -306,8 +279,7 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
for j=1,#nodes do nodes_order[j] = j end
local function nfsort(aidx, bidx)
- local a, b = nodes[aidx].p, nodes[bidx].p
- return bord_point_index(a) < bord_point_index(b)
+ return nodes[aidx].theta < nodes[bidx].theta
end
table.sort(nodes_order, nfsort)
@@ -353,18 +325,6 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
return i >= 0 and i <= ny and j >= 0 and j <= nx
end
- local function grid_iter_vertices()
- local i, j = 0, 0
- return function()
- if i <= ny then
- local ia, ja = i, j
- j = j + 1
- if j > nx then i, j = i+1, 0 end
- return ia, ja
- end
- end
- end
-
local function grid_iter_segments()
local s = {}
local cnt, n = 0, 2*nx+1
@@ -388,23 +348,28 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
local function grid_iter_intersects(level)
local sgm_iter = grid_iter_segments()
return function()
- local s, si
- repeat
- s = sgm_iter()
- if s then si = segment_index(s) else return end
- until check_cross(si, level, 'undef')
- return s, si
+ local si
+ for s in sgm_iter do
+ si = segment_index(s)
+ if check_cross(si, level, 'undef') then return s, si end
+ end
end
end
- for i, j in grid_iter_vertices() do
- local p = grid_point(i, j)
- local z = f(p)
- if z < g.zmin then g.zmin = z end
- if z > g.zmax then g.zmax = z end
- g.z[index(i,j)] = z
+ local function zmap()
+ for i=0, ny do
+ for j=0, nx do
+ local p = grid_point(i, j)
+ local z = f(p)
+ if z < g.zmin then g.zmin = z end
+ if z > g.zmax then g.zmax = z end
+ g.z[index(i,j)] = z
+ end
+ end
end
+ zmap()
+
zlevels = {}
if type(nlevels_or_levels) == 'table' then
table.sort(nlevels_or_levels)
@@ -472,20 +437,15 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
a, b = curve_extrema(crv, dir)
c = node_acw_next(b)
end
+
return dom
end
for id, crv in ipairs(curves) do
if not crv.closed then
local m1, m2 = divmod(mark[id], 2)
- if m2 > 0 then
- local dom = domain_join(id, 1)
- domain_add(dom)
- end
- if m1 > 0 then
- local dom = domain_join(id, -1)
- domain_add(dom)
- end
+ if m2 > 0 then domain_add(domain_join(id, 1)) end
+ if m1 > 0 then domain_add(domain_join(id, -1)) end
end
end
@@ -568,107 +528,28 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
return false
end
- local function curve_join(s0, level, id)
- local z0 = zlevels[level]
- local si0 = segment_index(s0)
-
- local irt, jrt = s0.i1, s0.j1
- if s0.i1 == s0.i2 then irt = nil else irt = nil end
- local cw = 0
-
- local function segment_lookup(s, idx0)
- segment_pivot(s)
-
- if not point_is_valid(s.i2, s.j2) then return 'boundary' end
-
- for cnt = 1,3 do
- local si = segment_index(s)
- if si == idx0 then return 'close' end
-
- if check_cross(si, level, 'undef') then
- assign_cross_at_index(si, level, id)
- return 'success'
- end
-
- segment_pivot(s)
- end
-
- error 'failed to find direction'
- end
-
- local function run(c, s, idx0)
- local status
-
- repeat
- status = segment_lookup(s, idx0)
- if status == 'success' then
- local p
- if s.i1 == irt and s.i1 == s.i2 then
- p = (s.j1 - s0.j1) * (s.j2 - s.j1)
- elseif s.j1 == jrt and s.j1 == s.j2 then
- p = (s.i1 - s0.i1) * (s.i2 - s.i1)
- end
- if p then cw = cw + (p < 0 and 1 or -1) end
- end
- segment_invert(s)
- until status ~= 'success'
-
- return status
- end
-
- local function curve_reverse(c)
- local j, n = 1, #c
- while j < n do
- c[j], c[n] = c[n], c[j]
- j, n = j+1, n-1
- end
- end
-
- local curve = {domain= {}, level= level}
- curve_register(curve)
-
- assign_cross_at_index(si0, level, id)
-
- local s = segment_copy(s0)
- local inner = inner_level_sign(s, level)
- local status = run(curve, s, si0)
- if status == 'boundary' then
- curve_reverse(curve)
- s = segment_copy(s0)
- segment_invert(s)
- status = run(curve, s, si0)
- else
- if cw < 0 then inner = -inner end
- if inner < 0 then curve.level = curve.level - 1 end
- curve.closed = cw
- end
-
- return curve
- end
-
local function curve_join_implicit(s0, level, id)
local z0 = zlevels[level]
local si0 = segment_index(s0)
local cw = 0
- local function step_check (stepper, dir)
+ local function step_check (stepper, p0, dir)
local ps = stepper.point()
- local p = ps:copy()
stepper.advance(dir)
- local i, j, di, dj = grid_snap(p)
+ local i, j, di, dj = grid_snap(p0)
- if dj == 0 and ps[1] < p[1] then j = j - 1 end
- if di == 0 and ps[2] < p[2] then i = i - 1 end
+ if dj == 0 and ps[1] < p0[1] then j = j - 1 end
+ if di == 0 and ps[2] < p0[2] then i = i - 1 end
if not (i >= 0 and i < ny and j >= 0 and j < nx) then
- grid_remove_cross(p, level, id)
- stepper.set(p)
+ grid_remove_cross(p0, level, id)
+ stepper.set(p0)
return true
end
- if grid_cross_check(i, j, p, ps, level, id) then
+ if grid_cross_check(i, j, p0, ps, level, id) then
return true
end
end
@@ -686,14 +567,14 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
local stepper = plcurve.stepper(f, p0, ds, zstep)
local points = curve.points
local start = true
-
+
local sg = segment_index_lookup(si0)
local oi = (sg.j1 == sg.j2 and 1 or 2)
local oj = (sg.j1 == sg.j2 and 2 or 1)
repeat
set(pa, stepper.point())
- local boundary_cross = step_check (stepper, dir)
+ local boundary_cross = step_check (stepper, pa, dir)
local pb = stepper.point()
if not start and plcurve.does_close(pa, pb, p0, 0.3 * ds) then
@@ -739,21 +620,6 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
return false
end
- local function curve_reverse(c)
- local j, n = 1, #c
- while j < n do
- c[j], c[n] = c[n], c[j]
- j, n = j+1, n-1
- end
-
- local ps = c.points
- j, n = 1, #ps
- while j < n do
- ps[j], ps[n] = ps[n], ps[j]
- j, n = j+1, n-1
- end
- end
-
local curve = {domain= {}, level= level}
curve_register(curve)
@@ -777,8 +643,12 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
local is_closed = run(curve, si0, 1)
if not is_closed then
- curve_reverse(curve)
+ reverse(curve.points)
status = run(curve, si0, -1)
+
+ local a, b = curve.points[1], curve.points[#curve.points]
+ curve.a = add_node(a, id, level)
+ curve.b = add_node(b, id, level)
else
if cw < 0 then curve.level = curve.level - 1 end
if cw == 0 then error 'error in curve closure determination' end
@@ -833,77 +703,60 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
local function order_curves()
print('ORDER CURVES')
- searchlist = {}
+ searchlist, treated = {}, {}
for id, _ in ipairs(curves) do
if curves[id].closed then insert(searchlist, id) end
end
- table.sort(searchlist, function(ia, ib) return #curves[ia] < #curves[ib] end)
-
- local function make_col_iter(j)
- local i = 0
- return function()
- if i+1 <= ny then
- local si = segment_index_i(i, j, i+1, j)
- i = i+1
- return si
- end
- end
- end
+ table.sort(searchlist, function(ia, ib)
+ return #curves[ia] < #curves[ib]
+ end)
local order_tree = {}
- function list_val_remove(ls, id)
- for k, cid in ipairs(ls) do
- if cid == id then
- table.remove(ls, k)
- break
- end
- end
- end
-
- while #searchlist > 0 do
- local id = searchlist[1]
- if not id then break end
-
- local i1, j1, i2, j2
+ for _, id in ipairs(searchlist) do
+ if not treated[id] then
+ local i1, j1, i2, j2
- for _, si in ipairs(curves[id]) do
- i1, j1, i2, j2 = segment_index_lookup_i(si)
- if j1 == j2 then break end
- end
+ for _, si in ipairs(curves[id]) do
+ i1, j1, i2, j2 = segment_index_lookup_i(si)
+ if j1 == j2 then break end
+ end
- if not j1 then error 'cannot find vertical cross' end
+ if not j1 then error 'cannot find vertical cross' end
- local kf
- kf, i1 = vline_scan_points_iter(j1), 0
+ local kf
+ kf, i1 = vline_scan_points_iter(j1), 0
- local st = {}
- local domid = bord_domain_lookup(i1, j1)
- for id, _ in kf do
- if not curves[id].closed then
- if not is_member_of_domain(domid, id) then
- -- DEBUG DEBUG DEBUG
- print('ERROR: curve', id, 'does not match domain', domid)
+ local st = {}
+ local domid = bord_domain_lookup(i1, j1)
+ for id, _ in kf do
+ if not curves[id].closed then
+ if not is_member_of_domain(domid, id) then
+ -- DEBUG DEBUG DEBUG
+ print('ERROR: curve', id, 'does not match domain', domid)
+ else
+ domid = curve_opposite_domain(id, domid)
+ print('> domain:', domid)
+ if #st ~= 0 then
+ error 'wrong curve stack in curve_order'
+ end
+ end
else
- domid = curve_opposite_domain(id, domid)
- print('> domain:', domid)
- if #st ~= 0 then error 'wrong curve stack in curve_order' end
- end
- else
- print('curve', id)
- list_val_remove(searchlist, id)
+ print('curve', id)
+ treated[id] = true
- if id == st[#st] then
- table.remove(st)
- local sup = #st > 0 and st[#st] or ('D' .. domid)
- order_add_relation(order_tree, id, sup)
- else
- insert(st, id)
+ if id == st[#st] then
+ table.remove(st)
+ local sup = #st > 0 and st[#st] or ('D' .. domid)
+ order_add_relation(order_tree, id, sup)
+ else
+ insert(st, id)
+ end
end
end
+ print('SCAN OK')
end
- print('SCAN OK')
end
-- DEBUG DEBUG DEBUG
@@ -914,7 +767,7 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
end
for id, c in pairs(order_tree) do
- print('> curve', id, 'inf:', set_to_string(c.inf))
+ print('> curve', id, 'inf:', set_to_string(c))
end
return order_tree
@@ -925,13 +778,6 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
for s, _ in grid_iter_intersects(level) do
local id = curve_next_id()
local curve = curve_join_implicit(s, level, id, true)
-
- if not curve.closed then
- local a, b = curve.points[1], curve.points[#curve.points]
- local aid = add_node(a, id, level)
- local bid = add_node(b, id, level)
- curve.a, curve.b = aid, bid
- end
end
end
@@ -1041,7 +887,8 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
end
local function color(a)
- return rgba(0.9, 0.9 - 0.9*a, 0, 0.8)
+ -- return rgba(0.9, 0.9 - 0.9*a, 0, 0.8)
+ return rgba(0.91 - 0.565*a, 0.898 - 0.753*a, 0.85 - 0.25*a, 0.8)
end
local function curve_draw(pl, id)
@@ -1049,7 +896,7 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
curve_add_path(ln, id, 'acw')
local tree = order_tree[id]
if tree then
- for sid, _ in pairs(tree.inf) do
+ for sid, _ in pairs(tree) do
curve_add_path(ln, sid, 'cw')
curve_draw(pl, sid)
end
@@ -1063,7 +910,7 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
local dpath = domain_draw_path(domid)
local tree = order_tree['D' .. domid]
if tree then
- for sid, _ in pairs(tree.inf) do
+ for sid, _ in pairs(tree) do
curve_add_path(dpath, sid, 'cw')
curve_draw(pl, sid)
end
@@ -1073,7 +920,7 @@ local function grid_create(f, left, right, nx, ny, nlevels_or_levels)
-- DEBUG DEBUG DEBUG
local cls = {}
- if tree then for sid, _ in pairs(tree.inf) do insert(cls, sid) end end
+ if tree then for sid, _ in pairs(tree) do insert(cls, sid) end end
print('domain', domid, 'curves:', cls)
-- io.read('*l')
end
generated by cgit v1.2.3 (git 2.25.1) at 2025年10月02日 04:59:54 +0000

AltStyle によって変換されたページ (->オリジナル) /