open office draw split 3d object into lines

I volition use a slightly different case to demonstrate my method (which is in no way guaranteed to solve the problem perfect but just an approach).

Firt we generate $100$ random cuboids with unique color for each of them, and then we can have a bijection colorToIdxRules between the color set up colorSet and the indice of the cuboids

          numObj = 100; numRay = 50;  colorSet = Hue[#, .3, one] & /@ RandomReal[{0, 1}, numObj];  colorToIdxRules =   MapIndexed[ImageData[Rasterize[Graphics3D[{#i, Sphere[]}, Lighting -> {{"Ambient",White}},          Boxed -> False, ImageSize -> 40]], "Byte"][[20, 20]] -> #2[[1]] &, colorSet]  posObj = RandomReal[five {-i, 1}, {numObj, 3}] /.     pt_List /; NumericQ[pt[[1]]] :> {pt, pt + RandomReal[5 {-ane, 1}, 3]};  grObj = Flatten[ MapThread[         {EdgeForm[Lighter[#ane]], FaceForm[#i], Cuboid @@ #2} &,     {colorSet, posObj}]];                  

and $50$ rays beginning from the aforementioned point ptOrig and with their endpoints stored in ptEndSet.

          ptOrig = {0, 0, 0}; ptEndSet = RandomReal[{-10, 10}, {numRay, 3}]; grR = Line[{ptOrig, #}] & /@ ptEndSet;  Graphics3D[{grObj, grR}, Axes -> True,  AxesLabel -> (Style[#, Assuming, Darker[Blue], xx] & /@ {x, y, z}),  Lighting -> "Neutral"]                  

full graphics

For solving the problem, the idea is to travel forth a ray, say the 1st 1 in ptEndSet, with using PlotRange to restrict the considering region as local as possible, and then iff this ray intersects a surface, otherwise we won't meet the surface during the whole journey.

          Manipulate[  Graphics3D[{GeometricTransformation[     {grObj, grR, Red, Thick, Line[{ptOrig, ptEndSet[[k]]}]},     RotationTransform[{ptEndSet[[k]] - ptOrig, {0, 0, one}}, ptOrig]     ]},   Axes -> Truthful,   AxesLabel -> (Mode[#, Bold, Darker[Blue], 20] & /@ {x, y, z}),   Lighting -> "Neutral"],  {m, 1, Length@ptEndSet, 1}]                  

ray aligned to z

          With[{k = 1},  With[{zrangeFull = (RotationTransform[{ptEndSet[[k]] - ptOrig, {0, 0, 1}}, ptOrig] /@        {ptOrig, ptEndSet[[k]]})[[All, three]]},   Manipulate[    Graphics3D[{GeometricTransformation[       {grObj, grR, Red, Thick, Line[{ptOrig, ptEndSet[[k]]}]},       RotationTransform[{ptEndSet[[thousand]] - ptOrig, {0, 0, 1}}, ptOrig]       ]},     Axes -> True,      AxesLabel -> (Fashion[#, Bold, Darker[Blue], xx] & /@ {x, y, z}),     Lighting -> "Neutral",     PlotRange -> {ptOrig[[ane]] + δ {-1, one},        ptOrig[[two]] + δ {-1, 1}, zrange + δ {-ane, 1}}],    {{zrange, 2.356`}, zrangeFull[[one]], zrangeFull[[2]]},    {{δ, 0.01`}, 0.01, 10, .01}    ]]]                  

neighborhood region

For sake of higher efficiency, we don't really travel forth it. Instead, we consider a cylindrical neighbourhood of the ray, with a special view setting (an judge orthogonal projection, I'm not certain how to use ViewMatrix to realize an exactly orthogonal project for this plot.. Settings from here seems behave weird on my plot..), and then Rasterize it:

          SetOptions[$FrontEnd,   RenderingOptions -> {"HardwareAntialiasingQuality" -> 0.}]  With[{k = 1, δ = 10^-4, vp = x^10},  With[{zrangeFull = (RotationTransform[{ptEndSet[[thou]] - ptOrig, {0, 0, 1}}, ptOrig] /@        {ptOrig, ptEndSet[[chiliad]]})[[All, three]]},   img = Graphics3D[{EdgeForm[], GeometricTransformation[         grObj /. EdgeForm[_] :> EdgeForm[],         RotationTransform[{ptEndSet[[one thousand]] - ptOrig, {0, 0, 1}}, ptOrig]         ]},       Lighting -> {{"Ambient", White}},       ViewPoint -> vp {0, 1, -10^-ii}, ViewVertical -> {1, 0, 0},       Boxed -> Faux, BoxRatios -> {1, 1, 10},       PlotRange -> {ptOrig[[1]] + δ {-1, one}, ptOrig[[ii]] + δ {-1, 1}, zrangeFull},       ImageSize -> 2000] // Rasterize // ImageCrop   ]]                  

color spectrum

Finally nosotros extract colors of the surfaces presented, from left to right, which is according with the management of the ray:

          SetOptions[$FrontEnd,   RenderingOptions -> {"HardwareAntialiasingQuality" -> i.}]  DeleteCases[Union[#][[1]] & /@    Split[ImageData[img, "Byte"][[      Round[ImageDimensions[img][[two]]/twenty]      ]]],   {255, 255, 255}] /. colorToIdxRules                  

{45, 73, 45, 73, 30, thirty, 61, 41, 75, 75, 61, 41}

So from ptOrig to its endpoint in ptEndSet, this ray intersects successively with the 45th, 73rd, 45th over again, ... cuboids.


Here I packed the code above to a part crossObjFunc:

          Clear[crossObjFunc] crossObjFunc[grObj_, ptOrig_, ptEnd_, OptionsPattern["showImg" -> False]] :=  Module[{img, zrangeFull,    δ = 10^-4, vp = ten^10, δz = 10^-2, imgSize = 2000, boxRat = 10},   SetOptions[$FrontEnd, RenderingOptions -> {"HardwareAntialiasingQuality" -> 0.}];   zrangeFull = (RotationTransform[{ptEnd - ptOrig, {0, 0, 1}}, ptOrig] /@                         {ptOrig, ptEnd})[[All, 3]];   img = Graphics3D[{EdgeForm[], GeometricTransformation[         grObj /. EdgeForm[_] :> EdgeForm[],         RotationTransform[{ptEnd - ptOrig, {0, 0, one}}, ptOrig]         ]},       Lighting -> {{"Ambient", White}},       ViewPoint -> vp {0, 1, -δz}, ViewVertical -> {1, 0, 0},       Boxed -> Fake, BoxRatios -> {1, 1, boxRat},       PlotRange -> {ptOrig[[one]] + δ {-1, one}, ptOrig[[2]] + δ {-one, i}, zrangeFull},       ImageSize -> imgSize] // Rasterize // ImageCrop;   If[OptionValue["showImg"], Print[img]];   SetOptions[$FrontEnd, RenderingOptions -> {"HardwareAntialiasingQuality" -> 1.}];   DeleteCases[Union[#][[1]] & /@      Split up[ImageData[img, "Byte"][[        Round[ImageDimensions[img][[2]]/(2 boxRat)]        ]]],     {255, 255, 255}, ∞] /. colorToIdxRules]  crossObjFunc[grObj, ptOrig, ptEndSet[[1]], "showImg" -> Truthful]                  

(Graphics omitted)

{42, 42, 61, 41}

It volition take well-nigh 25 seconds for parsing all the rays on my desktop PC with a two.4G CPU and 8G RAM:

          AbsoluteTiming[crossSet = crossObjFunc[grObj, ptOrig, #] & /@ ptEndSet;][[1]]                  

25.542461

A summary for all rays:

summary


Disadvantage: When placing the 3D graphics to become a side view, there is possibility that ii surfaces close enough will cover one another. And also possibility that for some special directed surface, the viewpoint is well-nigh on its tangent plane, so its contour would exist likewise thin to be captured past Rasterize thus will be missed.

miss surface

Problem remain: When there are alpha channel in colorSet, I currently can't figure out how to construct a proper map to the alphabetize. Transparent 3D objects are converted to non-transparent raster prototype, with their colors more or less changed.

smithcreat1997.blogspot.com

Source: https://mathematica.stackexchange.com/questions/24211/graphics3d-finding-intersection-of-3d-objects-and-lines

0 Response to "open office draw split 3d object into lines"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel