2013-03-08 4 views
7

это, вероятно, не подходящее место для публикации, но я не знаю, где еще разместить его.Общая формула для вычисления трехмерных пространств равных расстояний

У меня есть 5 строк (d1 -> d5), равномерно распределенных друг от друга в 3d-перспективе, у меня есть значения (a) угла, (d1) и (b5). Мне нужно вычислить (b2, b3, b4, d2, d3, d4, d5) с jquery.

enter image description here

я могу вычислить d5 с:

d5 = d1 - (b5 * Math.tan(a)) 

, но я понятия не имею, как рассчитать b2, b3 и b4. (d1 разделен на 4 идентичных segaments (s)) любая помощь будет оценена.

+0

Это может быть http://math.stackexchange.com, что вы хотите. +1 для изображения в любом случае. – Popnoodles

+0

Первый - этот вопрос потрясающий. Второй - @popnoodles, вероятно, правильный. В-третьих, вы ищете значения длины для каждого сегмента линии? –

+0

@popnoodles: спасибо, я отправлю туда сейчас – razzak

ответ

2

Что вы ищете - это проективный масштаб. Самый простой способ сделать это вычислительно - использовать однородные координаты, взять прямоугольник (как на первом рисунке ниже), на котором V «бесконечно далеко вправо» и найти проективное преобразование, которое отображает этот прямоугольник в трапецию в вторая картина. Вершинами прямоугольника являются (0 | 0), (0 | d1), (b5 | d1), (b5 | 0) и соответствующие вершины трапеции: (0 | 0), (0 | d1), (b5 | d5), (b5 | 0).

Illustration of a projective transformation for obtaining a projective scale

Поскольку эти четыре точки которых не три не коллинеарны, мы можем найти уникальную матрицу (до масштабирования) M для этой трансформации. После некоторой математики, оказывается, что эта матрица:

[d1*b5,0,0] 
[0,b5*d5,0] 
[d1-d5,0,b5*d5] 

Если вы хотите, чтобы найти координаты b3 и d3, например, вы можете умножить эту матрицу с однородными координатами точки в середине строки , т. е. вектор (0,5 * b5, d1,1)^T и вы получите однородные координаты точки (b3 | d3), которые можно преобразовать в евклидовы координаты путем дегомогенизации, т. е. делить первые две компоненты на третью.

В общем случае, если у вас есть две точки (b1 | d1) и (bn | dn) и вы хотите знать координаты n-2 равноотстоящих точек между ними в таком проективном масштабе, вы можете вычислить координаты bi и ди, как, как это (в вашем случае, п будет 5, конечно):

let M := matrix [[d1*bn, 0, 0], [0, bn*dn, 0], [d1-dn, 0, bn*dn]] 
let v := ((i-1)/(n-1)*bn, d1, 1) 
let (x,y,z) := M*v 
let bi := x/z and di := y/z 

Как вы видите, это простой алгоритм для вычисления координат этих проективно равноудаленных точек, и это обобщающее красиво произвольных количество точек.

Если вы хотели бы иметь замкнутую формулу, можно вычислить би и ди непосредственно как:

let bi := (bn*d1*(i-1))/(dn*n+(d1-dn)*i-d1) 
let di := d1*dn*(n-1)/(dn*n+(d1-dn)*i-d1) 
+0

спасибо за ваш ответ, но как я могу использовать это в jquery ?! – razzak

+0

Не обижайтесь, но JavaScript - это язык прямо из ада, и я не буду трогать его. Тем не менее, я не вижу проблемы - все, что вам нужно сделать, это написать код JavaScript для последних двух строк кода, которые я опубликовал, что не должно быть трудно на любом языке программирования. Может быть, что-то вроде http://pastebin.com/T3yuyTW3. b [1], b [5], d [1], d [5] должны содержать соответствующие значения в начале программы, тогда остальные записи b и d будут заполнены в цикле. (я не знаю, является ли это действительным JavaScript, но это должно быть его суть) –

+0

, считая, что две формулы верны 'let bi: = (bn * d1 * (i-1))/(dn * n + (d1-dn) * i-d1) Пусть di: = d1 * dn * (n-1)/(dn * n + (d1-dn) * i-d1) ' , если я меняю угол (a) it похоже, не влияет на формулу! – razzak

0

enter image description here

Сначала мы должны вычислить, что длина смежной стороны всего треугольника d1 ->против ->с есть (левая вертикальная сторона этого):

tan(Θ) = opposite/adjacent 
opposite * tan(Θ) = adjacent 
adjacent = opposite * tan(Θ) 
adjacent = d1 * tan(a) 

Следующая вещь, которую мы должны это знать, сколько от земли каждая линия от против, когда он попадает в линию d1. Принимая во внимание, что переменная с является одинаковым для всех подразделений и предполагая N деления сегментов (в данном случае 3), наш счетчик я, который начинается с 1 и переходит к N:

opposite(i) = i * (d1/N) 

Теперь нам нужно угол, что линия от об для каждого маркера ов составляет:

tan(Θi) = opposite/adjacent 
Θi = arctan(opposite/adjacent) 
Θi = arctan(opposite(i)/adjacent) 
Θi = arctan((i * (d1/N))/(d1 * tan(a))) 

Используя некоторую геометрию/тригг, можно сказать, что угол от d1 до точки c наверх d5 есть (90 ° - a).Мы будем называть этот угол а «

a' = 90° - a 

Закон синусов говорит нам, что:

A'/sin(a') = opposite(i)/sin(b') 

так что теперь мы решаем для А», так как нам нужна помощь в получении размеров оранжевый квадрат :

A' = (opposite(i) * sin (a'))/sin(b') 

так Ь» = ( + thetas; i) это превращается в:

A' = (opposite(i) * sin (90° - a))/sin(a + Θi) 

То же самое применяется, но решение для ч в оранжевый треугольник (см рисунок):

h/sin(90°-Θi) = A'/sin(90°) 
h = (A' * sin(90°-Θi))/sin(90°)  
b2 = h 

Собираем все вместе (надеюсь, без копирования/вставки ошибки с моей стороны) и без упрощений:

b2 = ((((i * (d1/N)) * sin (90° - a))/sin(a + Θi)) * sin(90° - arctan((i * (d1/N))/(d1 * tan(a)))))/sin(90°)  

Теперь промыть/повторить для каждого значения i и превратиться в код (я бы это сделал, но я слишком устал) :)

+0

'tan (Θ) = противоположный/смежный - -> смежное = противоположное/tan (0) 'right? – razzak

+0

yup :) Что касается a ', то это потому, что треугольник из точек b5-> d5-> c имеет внутри себя 180 градусов. один из них - 90, а другой - a, поэтому остаточный угол равен 180-90-a = 90-a, хотя вы можете быть правы, поскольку он зависит от b5 –

Смежные вопросы