Rotate the drawn ellipse points to define a circle

I have an ellipsoidal distribution, which, I think, is a conical section. I want to rotate the dots so that the distribution becomes round, as if I were looking at the conical section directly above the top of the cone.

Here are some sample data (generated using a function here )

X_df <- structure(list(x = c(550.685479223573, 411.808342674744, 125.337513241526, -46.6813176776531, 54.1090479024869, 335.045593380922, 538.806846993829, 476.123346783785, 207.359201714354, -23.3704356149293, -1.06902389582398, 252.471032092766, 502.461757269191, 522.09464005165, 290.954504794153, 22.4116013413886, -37.4399705577234, 166.122770874069, 446.874779008936, 547.271442128866, 372.271299246978, 84.7905677157295, -50.074206596271, 90.757431249567, 378.201298931732, 547.145608993239, 443.947162007208, 161.476775837252, -38.5517112166543, 25.2627436553199, 296.503160027896, 524.775126009974, 500.784559912938, 245.712512645379, -4.31860487373257, -21.9661658669887, 211.218663607589, 479.198761786515, 535.314989389215, 330.010941011427, 50.0215808044216, -46.3823119064223, 130.383487121344, 416.170638042649, 549.268852072098, 407.813005658263, 119.940919946473, -46.978590114418, 57.7409750579334, 340.505587064792, 539.650771180236, 472.254339573695, 201.890629521184, -25.163386210777, 1.25193046435474, 256.776302252232, 506.305676724803, 520.004964534048, 284.257495593069, 18.8183745840118, -35.9075114459174, 172.662124500953, 452.343060560759, 546.468842888411, 367.193523099128, 81.9151159445705, -49.726312730029, 95.1883131124973, 382.503271032958, 548.377552998115, 439.474201456606, 157.248088356873, -39.8634174011649, 28.665422852919, 301.243788141946, 526.815879166266, 497.683488701185, 240.939374274905, -7.78381612220116, -19.3411744866129, 217.640180353188, 483.134755325255, 534.947529479343, 324.801587123232, 45.3957868762181, -45.0069945691924, 134.781896592204, 420.833721926428, 550.278658272823, 403.464000037755, 116.273973349216, -48.5483252399878, 62.3918399072614, 345.924165684106, 540.282415561272, 468.621672005007, 195.304995872248, -28.2738679786754, 4.25351768918281, 262.272866287766, 509.296144374104), y = c(150.522375543584, 317.792592638159, 332.783726315973, 177.890614907595, -1.30774215535761, -41.9959828735621, 94.0557252742373, 281.491416261009, 347.931229803675, 232.411150772918, 41.2498141860971, -50.240758928064, 42.4333078345691, 233.202857825371, 347.930304275537, 279.801242902484, 93.7702821671593, -42.9605564915062, -0.128821245055916, 179.228629398932, 331.853832274807, 317.39347890031, 147.731418574477, -19.2449921421865, -31.3298018420377, 123.222814177221, 301.499351173211, 340.662811705721, 204.270915882133, 17.5570334546183, -47.8527634953491, 69.1925023774197, 260.846781070028, 350.702299892942, 255.267980339802, 64.3048063206447, -47.7550214881633, 21.0575085383169, 209.247480999408, 342.716023607699, 298.578792586917, 118.053124236616, -33.3190320226709, -16.5618829502486, 154.097078032767, 319.940208485997, 330.141085013461, 175.063055837321, -4.17911647131882, -40.77087978947, 96.7492568480405, 284.629419943293, 347.18869555741, 228.951107374031, 37.6230640656836, -49.9549156886126, 45.2896584936418, 236.96620488459, 349.2183672397, 277.259838492706, 88.5019845874813, -43.1419505604449, 1.98249146234145, 183.766146834555, 334.721418603224, 314.869389642466, 144.917094343997, -21.0615467657252, -29.137753346726, 126.928148173889, 305.196445845808, 339.338402720207, 201.609402013064, 15.0779976117978, -47.1046400880924, 71.7191693530443, 263.543031729657, 350.145628648054, 252.792513384296, 61.2531942049295, -49.0697852698499, 24.2068045114243, 212.793083656477, 343.533262533366, 295.969945687212, 115.135250419503, -34.4145910896749, -14.7817206225652, 156.282366465729, 322.116360452784, 328.626788731125, 171.323808201914, -6.54021515590322, -40.1360134761796, 101.492490333309, 286.854230399582, 347.010792855229, 226.829162028581, 35.3880363162166, -50.8418314561365, 48.893760376765 )), .Names = c("x", "y"), row.names = c(NA, -101L), class = "data.frame") 

Build an ellipse, it resembles my actual data:

 ggplot(X_df, aes(x, y)) + geom_point() + coord_equal() 

enter image description here

I want to apply the function to the xy coordinates to rotate the ellipse around its long axis, moving the top of the ellipse to me and the bottom of the ellipse from me to get something like this (with an equal size along the x axis as the ellipse is higher, but different dimensions along the y axis):

enter image description here

I want to rotate my data, as this ellipse is rotated to create a circle where I see the maximum distance between the top and bottom of the figure (that is, the longest axis perpendicular to the long axis), because the shape rotates the long axis around it.

How can i do this?

+3
source share
1 answer

You seem to say that if I looked at the edge of the circle, for example, x = -1000, y = 0, I would see that the line is rotated counterclockwise (from the xy plane) from the y axis. The goal is to rotate the circle back on the y axis.

The rotation angle is acos(1/ratio) (0.839 radians or 48.06 degrees in this case), where ratio diff(range(X_df$x))/diff(range(X_df$y)) (if the rotation axis is in the xy plane and parallel x axis, and your data includes points on the x axis on either side of the circle).

To essentially rotate the circle back to the xy plane, you can simply multiply the y-points by ratio , and then to maintain the same center, subtract (ratio - 1) * mean(X_df$y) (where I took the given points evenly distributed in a circle).

In other words (or in code, actually):

 ratio = diff(range(X_df$x))/diff(range(X_df$y)) X_df$ynew = ratio * X_df$y - (ratio - 1) * mean(X_df$y) ggplot(X_df, aes(x, ynew)) + geom_point() + coord_equal() 

Compare the original with "rotated":

enter image description here

+2
source

All Articles