Рассмотрим следующие игровые данные:
clear
input double x1 float y1
0 0
.0013440860215053765 .02503477
.0013440860215053765 .05006954
.005376344086021506 .0751043
.009408602150537635 .10013908
.01747311827956989 .12482615
.03225806451612903 .1498609
.056451612903225805 .1748957
.07661290322580645 .19993046
.09946236559139784 .22496523
.15725806451612903 .25
.2110215053763441 .2750348
.32661290322580644 .3000695
.3803763440860215 .3251043
.4986559139784946 .3497914
.603494623655914 .3748261
.706989247311828 .3998609
.7661290322580645 .4248957
.8064516129032258 .4499305
.885752688172043 .4749652
.9099462365591398 .5
1 .5250348
.9811827956989247 .5500696
.8870967741935484 .5751043
.7661290322580645 .5997913
.6599462365591398 .6248261
.5873655913978495 .6498609
.5282258064516129 .6748957
.40053763440860213 .6999304
.3279569892473118 .7249652
.2163978494623656 .75
.15053763440860216 .7750348
.09408602150537634 .8000696
.06586021505376344 .8247566
.04973118279569892 .8497913
.024193548387096774 .8748261
.025537634408602152 .8998609
.006720430107526882 .9248957
.002688172043010753 .9499304
.004032258064516129 .9749652
0 1
end
twoway scatter y1 x1
Когда я пытаюсь повернуть весь график, скажем, на 20
градусов прилавок по часовой стрелке:
local theta = 0.349066
generate x2 = (x1 * cos(`theta') ) - (y1 * sin(`theta') )
generate y2 = (x1 * sin(`theta') ) - (y1 * cos(`theta') )
Координаты преобразуются следующим образом:
clear
input float(x2 y2)
0 0
-.007299372 -.023065284
-.01586177 -.04659027
-.020635087 -.06873614
-.025408404 -.09088202
-.026273714 -.11132205
-.02094281 -.12979028
-.006770712 -.14504059
.0036123034 -.16167
.016521374 -.17738
.06226916 -.1811377
.10422786 -.1862745
.20428585 -.1702649
.24624455 -.1754017
.3489475 -.1581459
.4389013 -.14581393
.527592 -.13394167
.57460284 -.13723963
.6039312 -.1469735
.6698875 -.1433759
.6840596 -.1586262
.76012 -.151351
.7338752 -.18131188
.6369009 -.23701614
.51478493 -.3015878
.4064434 -.3614295
.3296775 -.4097785
.26554185 -.45353055
.13699183 -.52072746
.06022594 -.5690765
-.05316776 -.630757
-.12361852 -.6768075
-.1852281 -.7196401
-.22019514 -.7524921
-.24391386 -.7815335
-.2764738 -.8137929
-.28377315 -.8368582
-.3100179 -.8668191
-.3223694 -.8917232
-.3296688 -.9147884
-.3420203 -.9396926
end
twoway scatter y2 x2
Что мне не хватает?
Обратите внимание, что я также попытался сначала центрировать значения вокруг определенной точки.
Кроме того, я также хотел бы, чтобы решение учитывало различные масштабы осей и соотношение сторон графика.
Например:
clear
input float y double x
-2013 .001
-1941 .0010053763440860215
-1869 .0010053763440860215
-1797 .0010215053763440861
-1725 .0010376344086021505
-1654 .0010698924731182796
-1582 .0011290322580645162
-1510 .0012258064516129032
-1438 .0013064516129032257
-1366 .0013978494623655914
-1294 .0016290322580645162
-1222 .0018440860215053765
-1150 .0023064516129032257
-1078 .0025215053763440864
-1007 .0029946236559139786
-935 .003413978494623656
-863 .003827956989247312
-791 .004064516129032258
-719 .004225806451612904
-647 .004543010752688172
-575 .004639784946236559
-503 .005
-431 .0049247311827956995
-359 .004548387096774194
-288 .004064516129032258
-216 .0036397849462365592
-144 .003349462365591398
-72 .0031129032258064514
0 .0026021505376344085
72 .002311827956989247
144 .0018655913978494624
216 .0016021505376344087
288 .0013763440860215053
359 .0012634408602150537
431 .0011989247311827958
503 .0010967741935483872
575 .0011021505376344087
647 .0010268817204301076
719 .001010752688172043
791 .0010161290322580644
863 .001
end
twoway scatter y x
y-xis
этого графика составляет 4
дюймов, а x-axis
— 5.5
дюймов (соотношение сторон 1.375
).
Я ознакомился с рядом сообщений, включая следующие:
Я надеюсь, что то, что я пытаюсь сделать, ясно, но я буду рад уточнить дальше.
Формулы вращения следующие:
generate x2 = (x1 * cos(`theta') ) - (y1 * sin(`theta') )
generate y2 = (x1 * sin(`theta') ) + (y1 * cos(`theta') )
Они выполняют вращение вокруг точки (0,0)
.
Чтобы сделать вращение вокруг определенной центральной точки (cx, cy)
, можно применить следующий подход:
generate x2 = cx + ((x1 - cx) * cos(`theta') ) - ((y1 - cy) * sin(`theta') )
generate y2 = cy + ((x1 - cx) * sin(`theta') ) + ((y1 - cy) * cos(`theta') )
Приведенные выше формулы представляют собой матрицу аффинного преобразования. Чтобы учесть масштаб осей, вы должны умножить матрицу результата на матрицу масштабирования - это очень просто, просто умножьте x
или y
на коэффициент в соответствии с соотношением оси/оси.
Но кажется, вы хотите повернуть уже растянутое визуальное представление. Допустим, ваш сюжет растянут в OX
в 5
раз. В этом случае сначала умножьте x-координаты внутренних данных на 5
, сделайте поворот (примечание - центр вращения масштаба тоже), затем разделите на 5
.
Для вашего первого примера x-axis
в ~1.5
раз длиннее. Таким образом, мы можем умножить x
-столбец на 1.5
, повернуть на 20
градусов и разделить на 1.5
. Если оси сохранят свою длину, мы должны увидеть тот же график, повернутый на 20
градусов. Однако диапазоны данных изменились, а размер графика изменен! Угол не 20
градусов точно. Этот эффект будет более заметен на втором примере с большой разницей масштабов осей.
Если диапазоны остаются прежними после поворота, я ожидаю, что описанный подход должен давать правильные углы. Это можно проверить с помощью простого пиксельного графика, но я боюсь, что эта симуляция не будет воспроизводить поведение вашей системы построения графиков. При автоматических диапазонах осей точные углы невозможны.
Если диапазоны остаются прежними после поворота, я ожидаю, что описанный подход должен давать правильные углы. Это можно проверить с помощью простого пиксельного графика, но я боюсь, что эта симуляция не будет воспроизводить поведение вашей системы построения графиков.
Попробую и при необходимости снова вас побеспокою. Спасибо.
@DavisHerring Не стесняйтесь отвечать на вопрос, если у вас есть время.
@PearlySpencer: Помимо того факта, что вы должны увеличить у на (мой) в перед вращением (и при настройке центра) и уменьшить его после (я наспех подумал, что это было Икс ранее), я не вижу ничего упущенного из этот ответ и комментарии. Я отмечаю (более явно, чем этот ответ), что вы можете перемножить все три матрицы вместе, чтобы эффективно применить одно преобразование.
@PearlySpencer: заполнитель 5 — это «коэффициент наклона», который я определил в вашем связанном вопросе. Обратите внимание, что, поскольку ваша (физическая) область графика имеет прямоугольную форму, есть все шансы, что вы повернете данные за пределы кадра. Если вы расширите область графика асимметрично в ответ, вы, конечно, исказите свою повернутую форму.