forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Математика (http://forum.boolean.name/forumdisplay.php?f=85)
-   -   [js] Vec2 (двумерный вектор) (http://forum.boolean.name/showthread.php?t=18863)

moka 17.01.2014 04:05

[js] Vec2 (двумерный вектор)
 
Двумерный Вектор (Vec2), на JavaScript.

Весьма "грубое" решение расширить Float32Array, т.к. IE9 не держит их, лечиться правда очень просто - условием что если Float32Array нету, присваиваем к нему Array, и всё работает даже на древних платформах.

Исходники: https://gist.github.com/Maksims/8464888

Список поддерживаемых методов:
PHP код:

new, delete, clone
equal, equalS, equalXY,
set, setS, setR, setXY,
add, addS, addXY,
lerp, lerpS, lerpXY,
sub, subS, subXY,
mul, mulS, mulXY,
div, divS, divXY,
len,
dist, distXY,
dot, dotXY,
norm,
radians,
rot, rotR, rotXY,
sat,
floor, round, ceil 

Метод без приставки обычно принимает другой вектор.
Приставка S - метод принимает один аргумент - число.
Приставка R - принимает один аргумент - угол в radians.
Приставка XY - принимает два аргумента, x и y.

Вот пример реализации 2д камеры pick (координаты экрана курсора преобразуем в координаты мира), с учётом - позиции, поворота и приближения камеры:
PHP код:

Camera.prototype.pick = function(viewport, v) {
    return 
v.clone()                    // копируем точку клика
        
.sub(viewport.middle)           // централизуем на центр области обзора
        
.rotS(-this.rotation.radians()) // поворачиваем
        
.divS(this.zoom)                // приближаем
        
.mulXY(1, -1)                   // реверсия Y координаты
        
.add(this.position)             // сдвигаем
};

// ...

var pointInWorld = camera.pick(Vec2.new(mouseX, mouseY)); 

Бенчмарк с glMatrix (больше - лучше), как видим с кешем мы в 11 раз шустрее, без кеша почти вдвое.

ABTOMAT 17.01.2014 06:28

Ответ: [js] Vec2 (двумерный вектор)
 
Изобрёл велосипед, не поискав готовых решений.

http://glmatrix.net/docs/2.2.0/

mat2
mat2d
mat3
mat4
quat
vec2
vec3
vec4

Уже давно есть и работает везде.

moka 18.01.2014 01:49

Ответ: [js] Vec2 (двумерный вектор)
 
Я давно вкурсе про glMatrix ещё до имплементации данной библиотеки.
Но если ты работал с glMatrix, то ты отметишь для себя что данная библиотека не поддерживает chaining, а имеено то что я указал в примере, т.к. классы (по факту объекты) - лишь имеют функции а не методы над данными (не прототип над массивом).

Следственно твой аргумент не уместен по причине отличия решений, и по факту невозможность chain'ить мат. выражения - является первопричиной разработки своей библиотеки.
Также не имеет никакого "прозрачного" кеша для тебя, что прийдётся расширять библиотеку и переписывать методы копирования, инициализации и т.п.

Моё решение решает только одну задачу: vec2, то что мне требуется.
Да и моя библиотека рвёт glMatrix по производительности в клочья.

ABTOMAT 18.01.2014 11:37

Ответ: [js] Vec2 (двумерный вектор)
 
Цитата:

Сообщение от moka (Сообщение 272686)
Да и моя библиотека рвёт glMatrix по производительности в клочья.

Проводились тесты?

moka 18.01.2014 21:39

Ответ: [js] Vec2 (двумерный вектор)
 
Вложений: 1
Коментарии излишни...
(больше - лучше)
http://jsperf.com/glmatrix-vec2-vs-vec2


Даже без кеша, выийгрывает почти вдвое, с кешем, выйгрывает в 11+ раз.
Я уже не говорю о разнице того как код выглядит...

glMatrix:
PHP код:

Camera_g.prototype.pick = function(point) {
    
point = vec2.clone(point);
    
vec2.sub(point, point, this.middle);
    
    
// there is no rotate vector methods in glMatrix vec2,
    // alternative would be to use matrix for such operation,
    // but that would be overkill, and would reduce performance even more
    
var rotVec = vec2.clone(this.rotation);
    
vec2.normalize(rotVec, rotVec);
    var 
t = point[0] * rotVec[0] - point[1] * rotVec[1];
    
point[1] = point[1] * rotVec[0] + point[0] * rotVec[1];
    
point[0] = t;

    
vec2.div(point, point, vec2.fromValues(this.zoom, this.zoom));

    
point[1] *= -1;

    
vec2.add(point, point, this.position);

    return 
point;
}; 

Моё решение:
PHP код:

Camera.prototype.pick = function(point) {
    return 
point.clone()
        .
sub(this.middle)
        .
rot(this.rotation)
        .
divS(this.zoom)
        .
mulXY(1, -1)
        .
add(this.position)
}; 

Далее, я использую уже библиотеку не в первом проекте, следственно она доказала свою стабильность и удобство на самом деле реально выше в разы.

Честно сказать это было и до тестов очевидно, если ты заглядывал в то как glMatrix работает и в моё решение, а не задавал бы подобных вопросов.

И ещё факт того что я написал данную либу - позволило мне изучить как на самом деле работает математика каждой функции при работе с 2D векторами, и я считаю это огромный бенефит.

johnk 28.02.2014 21:17

Ответ: [js] Vec2 (двумерный вектор)
 
что понимается под кэшированием вектора?

SBJoker 28.02.2014 23:15

Ответ: [js] Vec2 (двумерный вектор)
 
не хватает сравнения с кешироваными матрицами.

moka 28.02.2014 23:44

Ответ: [js] Vec2 (двумерный вектор)
 
Цитата:

Сообщение от johnk (Сообщение 275662)
что понимается под кэшированием вектора?

В JS есть свой сборщик мусора, но стоимость создания Float32Array - обычно более 50% всей стоимости работы с векторами. Следственно заместо отдачи вектора на сборку мусорщиком, мы храним уже не использованный вектор в отдельном массиве (cache), и когда создаём новый вектор, проверяем если в кеше есть не используемый вектор, если есть, переиспользуем.
Тем самым мы экономим огромное количество производительности.

SBJoker, угу, там разница была бы ещё в разы круче. Но данная библиотека имплиментирует только 2ух мерный вектор, и матриц в ней нету.


Часовой пояс GMT +4, время: 10:12.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Перевод: zCarot