# Affine transform of sparse list (x,y,z) to a region of x^2 + y^2 + z^2 = 1.0

I have list of x,y,z points (somewhat random) that leads to the image shown below:

I am trying to map this data to essentially a sphere shape using an affine transform. My original attempt was to use a Rescaling transform as shown in the code below:

t = RescalingTransform[{
{min[[1]], max[[2]]}, {min[[2]], max[[2]]}, {min[[3]], max[[3]]}      },
{{-0.5, 0.01}, {-.6, .6}, {-1, 1}}]


Where min/max values are from the x,y,z list (see below), and I manually adjusted the limits of the re-scaled data ({{-0.5, 0.01}, {-.6, .6}, {-1, 1}}) to try and produce a circle.

min = Min /@ Transpose[Data]
max = Max /@ Transpose[Data]


The transform is applied through a table and the new data plotted (see table and plot below)

final = Table[ t[Data[[i]] ] // Simplify, {i, 1, Length[Data]} ];


The results are not great, and I tried to use the actual AffineTransform[] where the tensors (if I can call them that) were manually adjusted but with not much better results.

tA = MatrixForm[ AffineTransform[ MatrixForm[{{0.0004, 0.0002, 0.001}, {-0.002, 0.001,
0.002}, {0.002, -0.001, 0.0003}}]]];


I also repeated the process from Noisey Multivariate Data which worked (from a programming perspective) but could not provide much better results than manual attempts:

Any advice (if possible) is greatly appreciated.

• Your title makes it sound like you just want to flatten them onto a unit sphere so you'd do Normalize/@points. But what you're doing in the body of the question sounds more like you want the points on the interior of a unit ball. Could you clarify what it means to map this data to essentially a sphere shape ? Sep 6, 2020 at 17:59
• @flinty. I apologize if my comments are unclear. I am attempting to see if I can transform the coordinates of the points such they tend to fill a void, the interior of a unit ball - approximately. Scaling in x, y, and z directions, applying shear, and rotations. I am not entirely sure if it is possible. But the basic question is iif there is any advice on how to handle it as opposed to my trial and error with shear, rotation, and scaling. Sep 6, 2020 at 19:48
• You could use PrincipalComponents or a KarhunenLoeveDecomposition. There's also ellipsoid = BoundingRegion[points, "FastEllipsoid"]. Then you could center your points by subtracting the center of the ellipsoid and stretch/squash by the lengths of the semimajor axes such that the ellipsoid becomes a sphere and the points fill this sphere. If you provide the points I could show this in an answer. Sep 6, 2020 at 20:26
• @flinty. I will give it a shot first. To see if I can do it. If it does not work, and with your acceptance at that time, I can try and send you the data points. Thanks very much for the repsonse. it helps Sep 7, 2020 at 20:40

You must first center the data, so that the center of gravity is at the origin. Then you can scale it. There are different possibilities for this. You may e.g. use the mean distance from the center as scaling factor:

n = 50;
dat = Flatten[RandomReal[10 {-1, 1}, {n, n, 3}], 1];
center = Mean /@ Transpose@dat;
centered = (# - center) & /@ dat;
scale = Mean[Norm /@ centered];
newcoord = centered/scale;
ListPointPlot3D[newcoord, PlotRange -> All]


Or you may,if necessary, scale each axis separately:

n = 50;
dat = Flatten[RandomReal[10 {-1, 1}, {n, n, 3}], 1];
center = Mean /@ Transpose@dat;
centered = (# - center) & /@ dat;
scale = Mean /@ Abs@Transpose@centered
newcoord = (#/scale) & /@ centered;
ListPointPlot3D[newcoord, PlotRange -> All]


Because all this transformations are linear, they do not actually change the form of the distribution, which is box-like in our examples. If you want to change it to a spherical distribution, you would need a non-linear transformation. But I do not know if this is necessary.

• thanks @Daniel Huber. I will give it a go. Sep 7, 2020 at 20:39