FuncViz examples
Generalized bitree/quadtree/octree library
Loading...
Searching...
No Matches
implicit_curve_2d.cpp
Go to the documentation of this file.
1// -*- Mode:C++; Coding:us-ascii-unix; fill-column:158 -*-
2/*******************************************************************************************************************************************************.H.S.**/
3/**
4 @file implicit_curve_2d.cpp
5 @author Mitch Richling http://www.mitchr.me/
6 @date 2024-07-13
7 @brief Sampleing on a 2D grid to extract an implicit curve.@EOL
8 @std C++23
9 @copyright
10 @parblock
11 Copyright (c) 2024, Mitchell Jay Richling <http://www.mitchr.me/> All rights reserved.
12
13 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
14
15 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
16
17 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation
18 and/or other materials provided with the distribution.
19
20 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software
21 without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
28 DAMAGE.
29 @endparblock
30 @filedetails
31
32 For many of us our first exposure to an implicit curve was the unit circle in high school algebra, @f$x^2+y^2=1@f$, where we were ask to graph @f$y@f$ with
33 respect to @f$x@f$ only to discover that @f$y@f$ didn't appear to be a function of @f$x@f$ because @f$y@f$ had TWO values for some values of @f$x@f$! But
34 we soon discovered that a great many interesting curves could be defined this way, and that we could represent them all by thinking of the equations as a
35 functions of two variables and the curves as sets of zeros. That is to say, we can always write an implicit equation in two variables in the form
36 @f$F(x,y)=0@f$, and think of the implicit curve as the set of roots, or zeros, of the function @f$F@f$. We can then generalize this
37 idea to "level sets" as solutions to @f$F(x,y)=L@f$ -- i.e. the set of points where the function is equal to some "level" @f$L@f$.
38
39 Many visualization tools can extract a "level set" from a mesh. For 2D meshes (surfaces), the level sets are frequently 1D sets (curves). The trick to
40 obtaining high quality results is to make sure the triangulation has a high enough resolution. Of course we could simply sample the 2D grid uniformly
41 with a very fine mesh. A better way is to detect where the curve is, and to sample at higher resolution near the curve.
42
43 Currently we demonstrate a couple ways to refine the mesh near the curve:
44 - Using cell_cross_range_level() to find cells that cross a particular level (zero in this case)
45 - Using cell_cross_sdf() instead -- which generally works just like cell_cross_range_level() with a level of zero.
46
47 Today we extract the curve with Paraview, but I hope to extend MR_rt_to_cc to extract level sets in the future:
48 - Extract "standard" midpoint level sets (TBD)
49 - Solve for accurate edge/function level intersections, and construct high quality level sets. (TBD)
50*/
51/*******************************************************************************************************************************************************.H.E.**/
52/** @cond exj */
53
54////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
55#include "MR_rect_tree.hpp"
56#include "MR_cell_cplx.hpp"
57#include "MR_rt_to_cc.hpp"
58
59////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60typedef mjr::tree15b2d1rT tt_t;
61typedef mjr::MRccT5 cc_t;
62typedef mjr::MR_rt_to_cc<tt_t, cc_t> tc_t;
63
64////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65// This function is a classic "difficult case" for implicit curve algorithms.
66tt_t::rrpt_t f(tt_t::drpt_t xvec) {
67 double x = xvec[0];
68 double y = xvec[1];
69 double z = ((2*x*x*y - 2*x*x - 3*x + y*y*y - 33*y + 32) * ((x-2)*(x-2) + y*y + 3))/3000;
70 if (z>1.0)
71 z=1.0;
72 if (z<-1.0)
73 z=-1.0;
74 return z;
75}
76
77////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
78int main() {
79 tt_t tree({-10.0, -6.5},
80 { 10.0, 6.5});
81 cc_t ccplx;
82
83 // First we sample the top cell. Just one cell!
84 tree.sample_cell(f);
85
86 // Now we recursively refine cells that seem to cross over the curve
87 tree.refine_leaves_recursive_cell_pred(7, f, [&tree](tt_t::diti_t i) { return (tree.cell_cross_range_level(i, 0, 0.0)); });
88
89 // We could have used the function f as an SDF, and achieved the same result with the following:
90 // tree.refine_leaves_recursive_cell_pred(7, f, [&tree](tt_t::diti_t i) { return (tree.cell_cross_sdf(i, f)); });
91
92 tree.dump_tree(20);
93
94 // Convert the geometry into a 3D dataset so we can see the contour on the surface
95 tc_t::construct_geometry_fans(ccplx,
96 tree,
97 2,
98 {{tc_t::val_src_spc_t::FDOMAIN, 0},
99 {tc_t::val_src_spc_t::FDOMAIN, 1},
100 {tc_t::val_src_spc_t::FRANGE, 0}});
101
102 ccplx.create_named_datasets({"x", "y", "f(x,y)"});
103
104 ccplx.write_xml_vtk("implicit_curve_2d.vtu", "implicit_curve_2d");
105}
106/** @endcond */
int main()
double f(double x, double y)