Mathematica Asked on April 25, 2021
I have a 3 dimensional list of points which i would like to extrude in z coordinate with thickness n, i.e. z_{i} -> z_{i}+n for all points in z. There is a similar question concerning 2d list where the z coordinate is by default zero and obtains the thickness n, see Extrude two dimensional list with thickness n . The example list can be found here https://www.dropbox.com/s/mjewq4wnqlqczjb/AdvancedCase.xyz?dl=0
Generally speaking the object can contain holes and can also be an inclined planar. If someone can help me out i would much appreciate it.
Mathematica knows the xyz-file type: XYZ.
givenlist=Import["https://www.dropbox.com/s/mjewq4wnqlqczjb/AdvancedCase.xyz?dl=0"]
from this documentation page. There rest works as above. But this fails.
Loading this as ASCII shows this:
13.2577219009 -45.3633308411 136.8547973633
13.5088977814 -45.2704734802 136.8559722900
10.8333778381 -45.8802146912 136.6637573242
10.9468536377 -46.1600723267 136.5761871338
13.1572370529 -45.1396865845 136.6828918457
10.7912321091 -45.7505187988 136.6897125244
...
This is already a three-dimensional list. Rename the file type to txt and it is imported.
Import["./../AdvancedCase.txt", "Data"]
ListPlot3D[%20]
If the given surface would not have this much and heavy noise then ExtrudeMesh is the solution. This shows how to extrude a Rectangle
into a mesh volume in two steps.
allows making a control check whether enough points are considered for the convex hull.
Perhaps this is what You like:
ListPlot3D[%20, Mesh -> None, InterpolationOrder -> 0,
ColorFunction -> "SouthwestColors", Filling -> Bottom]
This is interpolation-free and assumes nothing that may spike. Each value is displayed on a shared basis. The extrusion is now taken to a common base plain. This looks rather different from top and bottom than from the sides views:
There are several types of substructures in the various subregion.
This shows this concave:
ListPlot3D[140 - %20, Mesh -> None, InterpolationOrder -> 0,
ColorFunction -> "SouthwestColors", Filling -> Bottom, Mesh -> None]
ListPlot3D[list, Method -> {"Extrusion" -> 0.5}, NormalsFunction -> ({0., 0., 1.} &)]
A nice solution too is
ListPlot3D[list/5, InterpolationOrder -> 0,
Method -> {"Extrusion" -> 0.1}, NormalsFunction -> ({0., 0., 1.} &),
ColorFunction -> "SouthwestColors"]
I added a scale down factor 0.2 and suppresssed interpolation. This is now a plain extrusion and has a structured downside.
I can not find this method option in my Mathematica documentation. So gratefull thanks to michael-e2!!!
OK! There is a lot of information now added by the comments.
This is a comparison for a methodology smoothing the supposed surface:
ListPointPlot3D[{data,
BilateralFilter[data, 2, .5, MaxIterations -> 25]},
PlotStyle -> {Thin, Red}]
This question offers the smoothing built-ins in Mathematica: remove noise from data
So some smoothing gives another impression of the given surfaces:
ListPointPlot3D[MeanShiftFilter[data, 5, .5, MaxIterations -> 25],
PlotStyle -> {Thin, Red}]
From straight line to steps. But some lines get more straight. Other lines appear and some inner points set appear.
It is time do ask again for more information about the intents of the question. The smoothed structures seem to fit to my first preconception of it.
The change is
ListPlot3D[MeanShiftFilter[data, 5, .5, MaxIterations -> 25],
Mesh -> None, InterpolationOrder -> 0,
ColorFunction -> "SouthwestColors", , Method -> {"Extrusion" -> 0.1},
NormalsFunction -> ({0., 0., 1.} &)]
Nice to communicate whether this is the right direction.
ListPlot3D[MeanShiftFilter[data, 5, .5, MaxIterations -> 25],
Mesh -> None, InterpolationOrder -> 0,
ColorFunction -> "SouthwestColors", Method -> {"Extrusion" -> 0.1},
NormalsFunction -> ({0., 0., 1.} &)]
Answered by Steffen Jaeschke on April 25, 2021
Since no MWE has been forthcoming, here is a demonstration that this functionality is built into ListPlot3D
.
Here's some data:
data = Flatten[
Table[{x, y, Sin[x + 3 Cos[y]]/2}, {x, -3., 3, 0.1}, {y, -3., 3, 0.1}],
1];
Dimensions@data
(* {3721, 3} *)
ListPlot3D[data]
To get vertical thickness added, use the NormalsFunction
option. The thickness is added in the direction of the normal vectors it returns. We can even punch a hole in the mesh with the RegionFunction
option.
DiscretizeGraphics@ListPlot3D[data,
RegionFunction -> Function[{x, y, z}, x^2 + y^2 + z^2 > 2.5],
Method -> {"Extrusion" -> 0.5}, (* set thickness *)
NormalsFunction -> ({0., 0., 1.} &)]
Answered by Michael E2 on April 25, 2021
This is illustration how to do it with ListPointPlot3D
and to show what kind of points we have to plot. Since list uploaded on https://www.dropbox.com/s/mjewq4wnqlqczjb/AdvancedCase.xyz?dl=0 is not structured we can't use it with ListPlot3D
. Also there is some noise in these data. Therefore we use first as Steffen recommends
data = Import["...AdvancedCase.txt", "Data"]
Then plot data
as
ListPointPlot3D[data]
Now we can prepare second list with
n = 2; data1 = Table[data[[i]] + {0, 0, n}, {i, Length[data]}];
We can also plot data
and data1
together
ListPointPlot3D[{data, data1}, ColorFunction -> "Rainbow"]
As we understand the question is about how we can prepare 3D object from two set of points data
and data1
. The simplest way to extrude data
along z
is prepare set of solid primitives (same as in FEM). We take small subset from data
and plot (in this example n=5
)
L = Length[data];
dataT = Take[data, {1, L, 25}];
g = Graphics3D[
Table[{EdgeForm[Directive[Thick, LightBlue]], Blue, Opacity[.5],
Cylinder[{dataT[[i]], dataT[[i]] + {0, 0, 5}}, .2]}, {i,
Length[dataT]}], Boxed -> False, Axes -> True]
Answered by Alex Trounev on April 25, 2021
As has been mentioned in the comments and previous posts 243594, the data has poor signal-to-noise and therefore requires some cleanup.
First, we will import the data and Standardize
it so that the points are centered on the mean.
d = Import["AdvancedCase.xyz", "Table"];
d1 = First@d;
(*Translate data to be centered about mean of points*)
d = Standardize[d, Mean, 1 &];
offset = d1 - First@d;
CoordinateBounds[d]
ListPointPlot3D[d, Axes -> True, BoxRatios -> Automatic]
From the ListPointPlot3D and the CoordinatesBounds, we see that about 20 times the variation is contained in the X and Y coordinates. Therefore, fitting the data to a plane will provide a first-order correction and capture much of the variation in the Z-direction.
The following code will fit the data to a plane and rotate it so that the normal aligns with a new z-axis.
(*Find plane that best fits data*)
lm = LinearModelFit[d, {x, y}, {x, y}];
(*Extract plane normal*)
normal = Normalize[{-#2, -#3, 1}] & @@ lm["BestFitParameters"];
(*Find transform function that rotates normal to new z-axis*)
tr = Last@
FindGeometricTransform[{{0, 0, 0}, {0, 0, 1}}, {{0, 0, 0}, normal}];
(*Rotate extrusion axis into new coordinate system*)
npz = tr[{0, 0, 1}];
(*Find inverse transform*)
itr = tr // InverseFunction;
(*Transform and plot the data*)
td = tr[d];
ListPointPlot3D[td, Axes -> True, BoxRatios -> Automatic]
If we compare this ListPlot image in the new coordinate system to the previous ListPlot image, we see that we have removed much of the variation in the Z direction. We will assume that the surface is flat and that we are only concerned with the X and Y directions. Now, the problem is 2D and it will be easier to apply filters to clean up the data.
We will convert the three-dimensional data into two-dimensional data and use image processing techniques to clean up the data as we did in the previously linked answer.
data2d = td[[All, {1, 2}]];
Graphics[{Black, PointSize[0.0025], Point[data2d]}]
{xr, yr} = {MinMax[data2d[[All, 1]]], MinMax[data2d[[All, 2]]]};
image = DeleteSmallComponents@
GaussianFilter[
ColorNegate@
Binarize@
Rasterize[Graphics[{Black, PointSize[0.0125], Point[data2d]}],
"Image"], 5]
im = ImageMesh[image, DataRange -> {xr, yr}]
Since I am not quite sure how to handle prisms, we will convert the 2D mesh into quads and then extrude the elements along the new $z'$-axis. Then, we will rotate the coordinates back into the old coordinate system and produce the final MeshRegion.
(*Import required FEM package*)
Needs["NDSolve`FEM`"];
(*Install MeshTools*)
(*Uncomment if not installed*)
(*ResourceFunction["GitHubInstall"]["c3m-labs","MeshTools"]*)
Needs["MeshTools`"]
(*Convert Triangle mesh into Quad mesh*)
Print["Smoothed Quad mesh"]
(mesh2d =
SmoothenMesh[
TriangleToQuadMesh[
ToElementMesh[im, "MeshOrder" -> 1]]])["Wireframe"]
len = 0.3;(*Extrusion length*)
(*Extract and extrude coordinates*)
crd = mesh2d["Coordinates"];
ncrd = Length@crd;
(*Convert 2D coordinates into 3D*)
crd3d = crd /. {x_, y_} :> {x, y, 0};
crd3dextrude = crd3d /. {x_, y_, z_} :> {x, y, z} + len npz;
(*Join coordinates an inverse transform into original coordinate
system*)
crd3d = # + offset & /@ itr[Join[crd3d, crd3dextrude]];
(*Convert quad elements into hexahedral elements*)
inc = ElementIncidents[mesh2d["MeshElements"]];
inc3d = First@(inc /. {i_, j_, k_, l_} :> {i, j, k, l, i + ncrd,
j + ncrd, k + ncrd, l + ncrd});
(*Create element mesh and convert into mesh region*)
Print["Mesh region"]
mesh3d = MeshRegion@
ToElementMesh["Coordinates" -> crd3d,
"MeshElements" -> {HexahedronElement[inc3d]}]
Answered by Tim Laska on April 25, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP