Cross posted on Wolfram Community
Question
Given a list of points on a sphere and the sphere's radius, I'd like to plot a spherical polygon with those points as vertices.
And this needs to be fast, fast enough for the user to not "feel" generation time.
One should be able to style them too. Most importantly the surface, but an edge style would be nice as well.
What have I tried?
Motivation
I think it will be useful in many applications.
I don't have time for this but I thought it would be a nice feature to have to improve code I was playing with lately, mostly based on another J.M. answer - Voronoi grid on a sphere
arc[center_?VectorQ, {start_?VectorQ, end_?VectorQ}] := Module[{ang, co, r},
ang = VectorAngle[start - center, end - center]; co = Cos[ang/2]; r = EuclideanDistance[center, start]; {{start, center + r/co Normalize[(start + end)/2 - center], end}, co}
]
points = {2 π #1, ArcCos[2 #2 - 1]} & @@@ RandomReal[1, {10, 2}];
sp = Append[Sin[#2] Through[{Cos, Sin}[#1]], Cos[#2]] & @@@ points;
proc[] := (
ch = ConvexHullMesh[sp]; verts = MeshCoordinates[ch]; polys = First /@ MeshCells[ch, 2]; voro = Normalize[ Cross[verts[[#2]] - verts[[#1]], verts[[#3]] - verts[[#1]]]] & @@@ polys; edges = arc[{0, 0, 0}, voro[[##]]] & /@ Select[Subsets[Range[Length[polys]], {2}], Length[Intersection @@ polys[[#]]] >= 2 &];
);
proc[];
DynamicModule[{run = True}, Graphics3D[{ {Opacity[.75],
DynamicWrapper[EventHandler[Sphere[],
"MouseMoved" :> Module[{pos = MousePosition["Graphics3DBoxIntercepts", True], pt}, If[ Not @ TrueQ @ pos , pt = RegionIntersection[Sphere[], Line @ pos]; If[pt =!= EmptyRegion[3], sp[[-1]] = First@Nearest[pt[[1]], pos[[1]]]; proc[]] ]]]
, TrackedSymbols :> {run}
]
}
, {AbsoluteThickness[2], Dynamic[BSplineCurve[#, SplineDegree -> 2, SplineKnots -> {0, 0, 0, 1, 1, 1}, SplineWeights -> {1, #2, 1}] & @@@ edges]}, {Red, Sphere[Most @ sp, .02], Dynamic @ Sphere[Last @ sp, .02]}
}
, PlotRange -> 1.1 , SphericalRegion -> True , ImageSize -> 500]
]
To look more like this:
Comments
Post a Comment