Добавлен , опубликован
Моя имплементация векторов (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;
    }
}
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
4
30
6 лет назад
4
Залили в ресурсы WC3, пользуйтесь на здоровье!
0
28
6 лет назад
Отредактирован PT153
0
Не понимаю этой моды на вычисление длины методом. Почему нельзя её вычислить 1 раз во время создания вектора, записав в переменную, и менять её только в том случае, если вектор был изменён?

Хотят тут, конечно, зависит от использования. Если я часто буду изменять векторы, и редко брать длину, то тогда лучше длину каждый раз считать. Если наоборот, то тогда лучше рассчитывать только при создании и изменении вектора. Я бы вообще сделал вектор неизменяемым.
0
37
6 лет назад
0
PT153, лишняя память. Вектор - такой объект, который может создаваться миллионами единиц (в варкрафте нет).
0
30
6 лет назад
0
Я бы вообще сделал вектор неизменяемым.
И пересоздавал каждый раз? Это ещё тяжелее может оказаться. Кроме того, длинна может вообще быть не нужна в системе, и будет храниться мёртвым грузом.

в варкрафте нет
Когда делал демку физики, доводил до 3к физических объектов, в пике нагрузки жило до 4к векторов, так что даже в варкрафте можно ощутимый импакт на потребление памяти увидеть.
2
37
6 лет назад
2
Ну вон xcoll / xdestr вроде всегда хранит и передаёт 3 коорды, чтобы было ещё легче (локалки быстрее глобалок и быстрее обращений к массиву)
11
4
6 лет назад
11
Опять один бородатый программист написал никому не нужную фигню, чтобы обсудить это с двумя другими бородатыми программистами, которые занимаются той же ахинеей.
0
27
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), кстати.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.