Добавлен , опубликован
Моя имплементация векторов (2D и 3D) с полным набором инструментария для работы с ними.

Исходники в тексте:
Vec2
struct Vec2 {
    public float x, y;

    public Vec2 setVal(float x, float y) {
        this.x = x;
        this.y = y;
        return this;
    }

    public Vec2 clear() {
        return this.setVal(0.0, 0.0);
    }

    // Constructors
    public static Vec2 create() {
        return Vec2.allocate().setVal(0.0, 0.0);
    }

    public static Vec2 createAt(float x, float y) {
        return Vec2.allocate().setVal(x, y);
    }

    public static Vec2 createRandom() {
        return Vec2.allocate().setVal(GetRandomReal(-1.0, 1.0), GetRandomReal(-1.0, 1.0));
    }

    // Transitional behavior
    public Vec2 clone() {
        return Vec2.allocate().setVal(this.x, this.y);
    }

    public Vec2 copy(Vec2 another) {
        return this.setVal(another.x, another.y);
    }

    // Math
    public Vec2 add(Vec2 another) {
        return this.setVal(this.x + another.x, this.y + another.y);
    }

    public Vec2 sub(Vec2 another) {
        return this.setVal(this.x - another.x, this.y - another.y);
    }

    public Vec2 scale(float number) {
        return this.setVal(this.x*number, this.y*number);
    }

    public Vec2 div(float number) {
        return this.scale(1.0/number);
    }

    public float dot(Vec2 another) {
        return this.x*another.x + this.y*another.y;
    }

    public float lengthSqr() {
        return this.x*this.x + this.y*this.y;
    }

    public float length() {
        return SquareRoot(this.x*this.x + this.y*this.y);
    }

    public float distToSqr(Vec2 another) {
        return (this.x - another.x)*(this.x - another.x) + (this.y - another.y)*(this.y - another.y);
    }

    public float distTo(Vec2 another) {
        return SquareRoot(this.distToSqr(another));
    }

    public float angle(Vec2 another) {
        return Acos(this.dot(another)/this.length()*another.length());  // radians
    }

    public Vec2 normalize() {
        debug if (this.length == 0.0) { BJDebugMsg("attempt to normalize vector with zero length"); return this; }
        return this.scale(1.0/this.length());
    }

    // Misc.
    public Vec2 reflect(Vec2 normal) {
        Vec2 temp = normal.clone().scale(2.0*this.dot(normal));
        this.sub(temp);
        temp.destroy();
        return this;
    }
}
Vec3
struct Vec3 {
    public float x, y, z;

    public Vec3 setVal(float x, float y, float z) {
        this.x = x;
        this.y = y;
        this.z = z;
        return this;
    }

    public Vec3 clear() {
        return this.setVal(0.0, 0.0, 0.0);
    }

    // Constructors
    public static Vec3 create() {
        return Vec3.allocate().setVal(0.0, 0.0, 0.0);
    }

    public static Vec3 createAt(float x, float y, float z) {
        return Vec3.allocate().setVal(x, y, z);
    }

    public static Vec3 createRandom() {
        return Vec3.allocate().setVal(GetRandomReal(-1.0, 1.0), GetRandomReal(-1.0, 1.0), GetRandomReal(-1.0, 1.0));
    }

    // Transitional behavior
    public Vec3 clone() {
        return Vec3.allocate().setVal(this.x, this.y, this.z);
    }

    public Vec3 copy(Vec3 another) {
        return this.setVal(another.x, another.y, another.z);
    }

    // Math
    public Vec3 add(Vec3 another) {
        return this.setVal(this.x + another.x, this.y + another.y, this.z + another.z);
    }

    public Vec3 sub(Vec3 another) {
        return this.setVal(this.x - another.x, this.y - another.y, this.z - another.z);
    }

    public Vec3 scale(float number) {
        return this.setVal(this.x*number, this.y*number, this.z*number);
    }

    public Vec3 div(float number) {
        return this.scale(1.0/number);
    }

    public float dot(Vec3 another) {
        return this.x*another.x + this.y*another.y + this.z*another.z;
    }

    public float lengthSqr() {
        return this.x*this.x + this.y*this.y + this.z*this.z;
    }

    public float length() {
        return SquareRoot(this.x*this.x + this.y*this.y + this.z*this.z);
    }

    public float distToSqr(Vec3 another) {
        return (this.x - another.x)*(this.x - another.x) + (this.y - another.y)*(this.y - another.y) + (this.z - another.z)*(this.z - another.z);
    }

    public float distTo(Vec3 another) {
        return SquareRoot(this.distToSqr(another));
    }

    public float angle(Vec3 another) {
        return Acos(this.dot(another)/this.length()*another.length());
    }

    public Vec3 normalize() {
        debug if (this.length == 0.0) { BJDebugMsg("attempt to normalize vector with zero length"); return this; }
        return this.scale(1.0/this.length());
    }

    public static Vec3 cross(Vec3 edge1, Vec3 edge2) {
        return Vec3.createAt(edge1.y*edge2.z - edge1.z*edge2.y, edge1.z*edge2.x - edge1.x*edge2.z, edge1.x*edge2.y - edge1.y*edge2.x);
    }

    // Misc.
    public Vec3 reflect(Vec3 normal) {
        Vec3 temp = normal.clone().scale(2.0*this.dot(normal));
        this.sub(temp);
        temp.destroy();
        return this;
    }

    public static Vec3 triangleNormal(Vec3 a, Vec3 b, Vec3 c) {
        Vec3 edge1 = b.clone().sub(a);
        Vec3 edge2 = c.clone().sub(a);
        Vec3 result = Vec3.cross(edge1, edge2).normalize();
        edge1.destroy();
        edge2.destroy();
        return result;
    }
}
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
30
6 лет назад
0
Я бы вообще сделал вектор неизменяемым.
И пересоздавал каждый раз? Это ещё тяжелее может оказаться. Кроме того, длинна может вообще быть не нужна в системе, и будет храниться мёртвым грузом.

в варкрафте нет
Когда делал демку физики, доводил до 3к физических объектов, в пике нагрузки жило до 4к векторов, так что даже в варкрафте можно ощутимый импакт на потребление памяти увидеть.
2
37
6 лет назад
2
Ну вон xcoll / xdestr вроде всегда хранит и передаёт 3 коорды, чтобы было ещё легче (локалки быстрее глобалок и быстрее обращений к массиву)
11
4
6 лет назад
11
Опять один бородатый программист написал никому не нужную фигню, чтобы обсудить это с двумя другими бородатыми программистами, которые занимаются той же ахинеей.
0
28
6 лет назад
0
abidin, это ты конечно зря сейчас сказал, хоть и частично правда.
1
29
6 лет назад
1
PrincePhoenix, почему частично?)
Как способ отточить свой скилл в векторах - да, стоит хоть раз в жизни написать свой солвер.
Как солвер для других - тысячу и один раз уже все было сделано до нас, со статьями причем.
0
30
6 лет назад
0
Msey, конкретно здесь самая визуально приятная реализация, на мой взгляд. Вон выше кидали «тоже самое» из DGUI, жесть же.

почему частично?)
Потому что я не бородатый!
Ну и ещё потому что векторы всё-таки полезная тема и много где нужная.
2
17
6 лет назад
2
Я бы предложил переименовать конструктор
public static Vec3 createAt(float x, float y, float z)
в
public static Vec3 create(float x, float y, float z)
А в свою очередь обычный
public static Vec3 create() 
в
public static Vec3 createZero() 
И добавить метод
    public string toString() {
        return "Vec3[" + R2S(x) + ", " + R2S(y) + ", "  + R2S(z) + "]";
    }
Аналогично для Vec2
0
30
6 лет назад
Отредактирован Clamp
0
GetLocalPlayer, хотел сохранить конструктор create() без параметров, чтобы поведение класса было максимально предсказуемым. Про toString идея неплохая, и я думал её реализовать, но потом понял, что не вижу ни одного юзкейса, где это было бы нужно, даже для дебага. Тоже самое про equals(Vec3), кстати.
0
26
6 лет назад
0
abidin:
Опять один бородатый программист написал никому не нужную фигню, чтобы обсудить это с двумя другими бородатыми программистами, которые занимаются той же ахинеей.
Такие темы могут быть интересны для общей информации. Например:
ScorpioT1000:
(локалки быстрее глобалок и быстрее обращений к массиву)
0
28
6 лет назад
Отредактирован Феникс
0
8gabriel8, Это всё опять же заморочки кодеров, для обычного картостроителя эта инфа настолько мизерна, что даже не знаю.

Но! Такие треды, в первую очередь, помогают тем, кто хочет развиться дальше варкрафта и уйти в геймдев.
0
4
6 лет назад
0
PrincePhoenix, лучше тогда в статью про геймдев закинуть в целях обучения. Там он был бы чуть
полезнее, если бы были ещё и картинки. А так данные методы написаны для лентяев, которые не хотят ничего учить, а хотят дергать за рычаги и получать результат.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.