TransWikia.com

Extrude 3D list with thickness n

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.

4 Answers

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]

ListPlot3D

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]

ListPlot3D with shards 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:

enter image description here

There are several types of substructures in the various subregion.

enter image description here

This shows this concave:

ListPlot3D[140 - %20, Mesh -> None, InterpolationOrder -> 0, 
 ColorFunction -> "SouthwestColors", Filling -> Bottom, Mesh -> None]

enter image description here

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"]

solution

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}]

smoothing by bilateral filerting

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}]

enter image description here

From straight line to steps. But some lines get more straight. Other lines appear and some inner points set appear.

enter image description here

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.} &)]

proximum

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.} &)]

new view of the data set

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]

Figure 1

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"]

Figure 2

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]

Figure 3

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.

Import and view the data

First, we will import the data and Standardizeit 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]

Original data

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.

Fitting the data to a plane

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]

Transformed data

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.

Cleanup of 2D 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}]

Image mesh

Conversion to Quad mesh and extrusion

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]}]

Final mesh region

Answered by Tim Laska on April 25, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP