@@ -259,43 +259,81 @@ end
259259"""
260260 $(SIGNATURES)
261261
262- Collect isoline snippets on triangles ready for linesegments!
262+ March through the given grid and extract points and values for given iso-line levels and/or given intersection lines.
263+ From the returned point list and value list a line plot can be created.
264+
265+ Input:
266+ coord: matrix storing the coordinates of the grid
267+ cellnodes: connectivity matrix
268+ func: function on the grid nodes to be evaluated
269+ lines: vector of line definitions [a,b,c], s.t., ax + by + c = 0 defines a line
270+ levels: vector of levels for the iso-surface
271+ Tc: scalar type of coordinates
272+ Tp: vector type of coordinates
273+ Tv: scalar type of function values
274+
275+ Output:
276+ points: vector of 2D points of the intersections of the grid with the iso-surfaces or lines
277+ adjacencies: vector of 2D vectors storing connected points in the grid
278+ value: interpolated values of `func` at the intersection points
279+
280+ Note that passing both nonempty `lines` and `levels` will create a result with both types of points mixed.
263281"""
264282function marching_triangles (
265- coord:: Matrix{Tv } ,
283+ coord:: Matrix{T } ,
266284 cellnodes:: Matrix{Ti} ,
267285 func,
286+ lines,
268287 levels;
269- Tc = Float32,
270- Tp = SVector{2 , Tc}
271- ) where {Tv <: Number , Ti <: Number }
272- return marching_triangles ([coord], [cellnodes], [func], levels; Tc, Tp)
288+ Tc = T,
289+ Tp = SVector{2 , Tc},
290+ Tv = Float64
291+ ) where {T <: Number , Ti <: Number }
292+ return marching_triangles ([coord], [cellnodes], [func], lines, levels; Tc, Tp, Tv)
273293end
274294
295+
296+ """
297+ $(SIGNATURES)
298+
299+
300+ Variant of `marching_triangles` with multiple grid input
301+ """
275302function marching_triangles (
276- coords:: Vector{Matrix{Tv }} ,
303+ coords:: Vector{Matrix{T }} ,
277304 cellnodes:: Vector{Matrix{Ti}} ,
278305 funcs,
306+ lines,
279307 levels;
280- Tc = Float32,
281- Tp = SVector{2 , Tc}
282- ) where {Tv <: Number , Ti <: Number }
308+ Tc = T,
309+ Tp = SVector{2 , Tc},
310+ Tv = Float64
311+ ) where {T <: Number , Ti <: Number }
283312 points = Vector {Tp} (undef, 0 )
313+ values = Vector {Tv} (undef, 0 )
314+ adjacencies = Vector {SVector{2, Ti}} (undef, 0 )
284315
285316 for igrid in 1 : length (coords)
286317 func = funcs[igrid]
287318 coord = coords[igrid]
288319
289- function isect (nodes)
320+ # pre-allcate memory for triangle values (3 nodes per triangle)
321+ objective_values = Vector {Tv} (undef, 3 )
322+
323+ # the objective_func is used to determine the intersection (line equation or iso levels)
324+ # the value_func is used to interpolate values at the intersections
325+ function isect (tri_nodes, objective_func, value_func)
290326 (i1, i2, i3) = (1 , 2 , 3 )
291327
292- f = (func[nodes[1 ]], func[nodes[2 ]], func[nodes[3 ]])
328+ # 3 values of the objective function
329+ f = objective_func
293330
331+ # sort f[i1] ≤ f[i2] ≤ f[i3]
294332 f[1 ] <= f[2 ] ? (i1, i2) = (1 , 2 ) : (i1, i2) = (2 , 1 )
295333 f[i2] <= f[3 ] ? i3 = 3 : (i2, i3) = (3 , i2)
296334 f[i1] > f[i2] ? (i1, i2) = (i2, i1) : nothing
297335
298- (n1, n2, n3) = (nodes [i1], nodes [i2], nodes [i3])
336+ (n1, n2, n3) = (tri_nodes [i1], tri_nodes [i2], tri_nodes [i3])
299337
300338 dx31 = coord[1 , n3] - coord[1 , n1]
301339 dx21 = coord[1 , n2] - coord[1 , n1]
@@ -305,35 +343,67 @@ function marching_triangles(
305343 dy21 = coord[2 , n2] - coord[2 , n1]
306344 dy32 = coord[2 , n3] - coord[2 , n2]
307345
308- df31 = f[i3] != f[i1] ? 1 / (f[i3] - f[i1]) : 0.0
309- df21 = f[i2] != f[i1] ? 1 / (f[i2] - f[i1]) : 0.0
310- df32 = f[i3] != f[i2] ? 1 / (f[i3] - f[i2]) : 0.0
311-
312- for level in levels
313- if (f[i1] <= level) && (level < f[i3])
314- α = (level - f[i1]) * df31
315- x1 = coord[1 , n1] + α * dx31
316- y1 = coord[2 , n1] + α * dy31
317-
318- if (level < f[i2])
319- α = (level - f[i1]) * df21
320- x2 = coord[1 , n1] + α * dx21
321- y2 = coord[2 , n1] + α * dy21
322- else
323- α = (level - f[i2]) * df32
324- x2 = coord[1 , n2] + α * dx32
325- y2 = coord[2 , n2] + α * dy32
326- end
327- push! (points, SVector {2, Tc} ((x1, y1)))
328- push! (points, SVector {2, Tc} ((x2, y2)))
346+ df31 = f[i3] != f[i1] ? 1 / (f[i1] - f[i3]) : 0.0
347+ df21 = f[i2] != f[i1] ? 1 / (f[i1] - f[i2]) : 0.0
348+ df32 = f[i3] != f[i2] ? 1 / (f[i2] - f[i3]) : 0.0
349+
350+ if (f[i1] <= 0 ) && (0 < f[i3])
351+ α = f[i1] * df31
352+ x1 = coord[1 , n1] + α * dx31
353+ y1 = coord[2 , n1] + α * dy31
354+ value1 = value_func[n1] + α * (value_func[n3] - value_func[n1])
355+
356+ if (0 < f[i2])
357+ α = f[i1] * df21
358+ x2 = coord[1 , n1] + α * dx21
359+ y2 = coord[2 , n1] + α * dy21
360+ value2 = value_func[n1] + α * (value_func[n2] - value_func[n1])
361+ else
362+ α = f[i2] * df32
363+ x2 = coord[1 , n2] + α * dx32
364+ y2 = coord[2 , n2] + α * dy32
365+ value2 = value_func[n2] + α * (value_func[n3] - value_func[n2])
329366 end
367+
368+ push! (points, SVector {2, Tc} ((x1, y1)))
369+ push! (points, SVector {2, Tc} ((x2, y2)))
370+ push! (values, value1)
371+ push! (values, value2)
372+ # connect last two points
373+ push! (adjacencies, SVector {2, Ti} ((length (points) - 1 , length (points))))
330374 end
375+
331376 return
332377 end
333378
334379 for itri in 1 : size (cellnodes[igrid], 2 )
335- @views isect (cellnodes[igrid][:, itri])
380+
381+ # nodes of the current triangle
382+ tri_nodes = @views cellnodes[igrid][:, itri]
383+
384+ for level in levels
385+ # objective func is iso-level equation
386+ @views @fastmath map! (
387+ inode -> (func[inode] - level),
388+ objective_values,
389+ tri_nodes
390+ )
391+ @views isect (tri_nodes, objective_values, func)
392+ end
393+
394+ for line in lines
395+ @fastmath line_equation (line, coord) = coord[1 ] * line[1 ] + coord[2 ] * line[2 ] + line[3 ]
396+
397+ # objective func is iso-level equation
398+ @views @fastmath map! (
399+ inode -> (line_equation (line, coord[:, inode])),
400+ objective_values,
401+ tri_nodes
402+ )
403+ @views isect (tri_nodes, objective_values, func)
404+ end
405+
336406 end
337407 end
338- return points
408+ return points, adjacencies, values
339409end
0 commit comments