6
$\begingroup$

The following code works for polygons. A square 4x4 is tried here:

 << NDSolve`FEM`
a = 2;
mesh1 = ToBoundaryMesh[Rectangle[{0, 0}, {2 a, 2 a}], 
   "MaxBoundaryCellMeasure" -> 1, "MeshOrder" -> 1];
pts = mesh1["Coordinates"]
ConvexHullMesh[pts, MeshCellLabel -> {0 -> "Index"}]`
ch = ConvexHull[pts];
pts[[ch]]
ConvexHullMesh[pts, MeshCellLabel -> {0 -> "Index"}]

But if part of the boundary is curved, the curved part is missed:

mesh2 = ToBoundaryMesh[
   RegionDifference[Rectangle[{0, 0}, {2 a, 2 a}], 
    Disk[{2 a, 2 a}, a]], "MaxBoundaryCellMeasure" -> 1, 
   "MeshOrder" -> 1];
pts = mesh2["Coordinates"]
ConvexHullMesh[pts, MeshCellLabel -> {0 -> "Index"}]
pts = mesh2["Coordinates"]
ch = ConvexHullMesh[pts]
$\endgroup$
2
  • 5
    $\begingroup$ mesh2 is not the convex region. $\endgroup$
    – cvgmt
    Mar 14 at 22:32
  • $\begingroup$ Welcome to Mathematica SE. To get started:1) take the introductory tour now,2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge,3) remember to accept the answer, if any, that solves your problem, by clicking checkmark sign,4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – kcr
    Mar 14 at 22:46

4 Answers 4

5
$\begingroup$

Get the list of vertex indices for lines in mesh2:

indices = mesh2["BoundaryElements"][[1, 1]];

Use FindHamiltonianPath on the list of pairs indices to find a path that starts at 1 and ends at 2:

hpath = FindHamiltonianPath[indices, 1, 2]
{1, 28, 27, 19, 18, 17, 16, 15, 14, 23, 24, 25, 26, 20, 21, 22, 13, 12, 11, 
 10, 9, 8, 7, 6, 5, 4, 3, 2}
reIndex = AssociationThread[hpath, Range[Length @ hpath]];

BoundaryMeshRegion[mesh2["Coordinates"][[hpath]], 
 Line /@ (indices /. reIndex),
 MeshCellStyle -> {0 -> Red}, 
 MeshCellLabel -> {0 -> "Index"}]

enter image description here

Additional ways to get hpath:

1. Using FindPath:

hpath2 = First @ FindPath[indices, 1, 2];

hpath2 == hpath
True

2. Using IncidenceGraph and the property "VertexBoundaryConnectivity" of mesh2:

hpath3 = FindHamiltonianPath[IncidenceGraph @ mesh2["VertexBoundaryConnectivity"], 1, 2];

hpath3 == hpath
True
$Version
"11.3.0 for Microsoft Windows (64-bit) (March 7, 2018)"
$\endgroup$
2
  • 1
    $\begingroup$ That's spectacular!!! $\endgroup$
    – bmf
    Mar 17 at 22:36
  • $\begingroup$ Dear bmf: Part of the misunderstanding is that I am new to this forum and had no idea about voting. Actually both of your answers (you and cvgmt) were useful to me. I have just upvoted both :) I also strongly agree with your comment about the contribution of kglr. $\endgroup$ Mar 18 at 19:07
6
$\begingroup$
<< NDSolve`FEM`
a = 2;
mesh2 = ToBoundaryMesh[
   RegionDifference[Rectangle[{0, 0}, {2 a, 2 a}], 
    Disk[{2 a, 2 a}, a]], "MaxBoundaryCellMeasure" -> 1, 
   "MeshOrder" -> 1];
mesh2["Wireframe"["MeshElement" -> "PointElements", 
   "MeshElementIDStyle" -> Red]];
HighlightMesh[
 BoundaryMeshRegion[mesh2], {Style[0, Red], Labeled[0, "Index"]}]

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ Thanks, cvgmt. But points are still not correctly numbered counterclockwise. $\endgroup$ Mar 15 at 8:10
6
$\begingroup$

You could reorder coordinates:

ch = BoundaryMeshRegion[mesh2];

order = FindCycle[MeshConnectivityGraph[ch, {0, 0}]][[1, All, 1, 2]];

ind = AssociationThread[order -> Range[MeshCellCount[ch, 0]]];

BoundaryMeshRegion[MeshCoordinates[ch][[order]], 
 MeshCells[ch, 1] /. ind, MeshCellLabel -> {0 -> "Index"}]

enter image description here

$\endgroup$
1
  • $\begingroup$ Nice and easy but unfortunately for my version 10, the function "MeshConnectivityGraph" does not work. $\endgroup$ Mar 16 at 12:07
5
$\begingroup$

This is based on the answer by @cvgmt.

Is this roughly what you were looking for?

<< NDSolve`FEM`
a = 2;
mesh2 = ToBoundaryMesh[
   RegionDifference[Rectangle[{0, 0}, {2 a, 2 a}], 
    Disk[{2 a, 2 a}, a]], "MaxBoundaryCellMeasure" -> 1, 
   "MeshOrder" -> 1];
mesh2["Wireframe"["MeshElement" -> "MeshElements", 
   "MeshElementIDStyle" -> Red]];
HighlightMesh[
 BoundaryMeshRegion[mesh2], {Style[1, Red], Labeled[1, "Index"]}]

mesh2

$\endgroup$
2
  • $\begingroup$ The order of numbers are now ok but they are shown as labels for elements not nodes. As I have said before, there is nothing wrong with the result by cvgmt except that my version of Mathematica does not have the function "MeshConnectivityGraph" $\endgroup$ Mar 17 at 18:29
  • $\begingroup$ Thanks for your comment. Just a clarification. I never implied that there's something wrong with the answer provided by @cvgmt. I have upvoted that and your question as well. I just saw the comment you left underneath said question, and thought to offer my help; thus re-arranged the numbers. I have even cited that particular answer to the response I gave. Anyway, if you and/or cvgmt are offended, I am happy to delete my reply. No worries. Please, do take into consideration that MeshConnectivityGraph is not used in this approach. I believe you confused yourself a bit with the other answer. $\endgroup$
    – bmf
    Mar 17 at 18:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.