Обнаружение столкновения XNA - Vector2.Reflect - Справка по вычислению нормали спрайта круга - C # - PullRequest
3 голосов
/ 06 февраля 2010

У меня возникают проблемы, когда я думаю о том, как рассчитать нормаль для движущегося круга в 2-мерном пространстве. Я дошел до того, что, как мне кажется, я рассчитал Норму Скорости (Направленной Скорости) объекта, но там мой мозг алгебры колледжа перегревается, любой, с которым я работаю, к 2d Кругу, которые у меня есть центральная точка, радиус, скорость и положение.

В конечном итоге я хочу использовать метод Vector2.Reflect, чтобы получить немного более реалистичную физику из этого упражнения.

спасибо заранее.

РЕДАКТИРОВАТЬ: Добавлен некоторый код, пробующий предложение (безрезультатно), возможно, неправильно понимающее предложение. Здесь я использую баскетбол и бейсбол, поэтому база и корзина. У меня также есть Position и Velocity, которые добавляются к позиции для создания движения.

if ((Vector2.Distance(baseMid, basketMid)) < baseRadius + basketRadius)
{
    Vector2 baseNorm = basketMid - baseMid;
    baseNorm.Normalize();
    Vector2 basketNorm = baseMid - basketMid;
    basketNorm.Normalize();
    baseVelocity = Vector2.Reflect(baseVelocity, baseNorm);
    basketVelocity = Vector2.Reflect(basketVelocity, basketNorm);
}

basePos.Y += baseVelocity.Y;
basePos.X += baseVelocity.X;
basketPos.Y += basketVelocity.Y;
basketPos.X += basketVelocity.X;
basketMid = new Vector2((basketballTex.Width / 2 + basketPos.X), (basketballTex.Height / 2 + basketPos.Y));
baseMid = new Vector2((baseballTex.Width / 2 + basePos.X), (baseballTex.Height / 2 + basePos.Y));

Ответы [ 3 ]

5 голосов
/ 09 февраля 2010

Сначала отражение. Если я правильно читаю ваш код, второй аргумент Vector2.Reflect является нормалью к поверхности. Пол уровня имеет нормаль (0,1), и мяч со скоростью (4, -3) попадает в него и улетает со скоростью (4,3). Это правильно? Если это не так, то нам придется изменить тело оператора if. (Обратите внимание, что вы можете сохранить некоторые циклы, установив basketNorm = -baseNorm.)

Теперь физика. Как написано, когда два шара сталкиваются, каждый отскакивает, как будто он ударил стеклянную стенку, касательную к обеим сферам, и это нереально. Представьте себе игру в пул: быстрый красный шар попадает в неподвижную точку с синим шаром. Красный шар отскакивает и оставляет синий шар там, где он был? Нет, синий шар сбивается, а красный теряет большую часть своей скорости (все в идеальном случае). Как насчет пушечного ядра и мяча для гольфа, которые движутся с одинаковой скоростью, но в противоположных направлениях, сталкиваясь в лоб? Будут ли они оба подпрыгивать одинаково? Нет, пушечное ядро ​​будет продолжаться, едва заметив удар, но мяч для гольфа поменяет направление и улетит быстрее, чем он появился .

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

Vector2 CMVelocity = (basket.Mass*basket.Velocity + base.Mass*base.Velocity)/(basket.Mass + base.Mass);

baseVelocity -= CMVelocity;
baseVelocity = Vector2.Reflect(baseVelocity, baseNorm);
baseVelocity += CMVelocity;

basketVelocity -= CMVelocity;
basketVelocity = Vector2.Reflect(basketVelocity, basketNorm);
basketVelocity += CMVelocity;
1 голос
/ 06 февраля 2010

Нормаль окружности в данной точке на ее краю будет направлением от его центра к этой точке. Предполагая, что вы работаете со столкновениями окружностей здесь, тогда один простой «сокращенный» способ решить эту проблему состоит в том, что во время столкновения (когда круги касаются), будет выполняться следующее:

Пусть A - центр одного круга, а B - центр другого. Нормаль для круга A будет нормализована (B-A), а нормаль для круга B будет нормализована (A-B). Это верно, потому что точка, в которой они соприкасаются, всегда будет коллинеарна центрам двух окружностей.

0 голосов
/ 15 февраля 2010

Предостережение: я не собираюсь предполагать, что это совершенно правильно. Физика не моя специальность.

Движение не влияет на нормаль. Как правило, нормаль - это просто нормализованный (длина 1) вектор, указывающий направление, обычно направление, с которым поли смотрит на трехмерный объект.

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

То, что кажется правильным для двумерной физики, это то, что вы берете скорость * массу (энергию) сферы и умножаете ее на нормализованный вектор для другой сферы. Добавьте результат к энергии сферы назначения, вычтите ее из энергии исходной сферы и разделите каждую по отдельности на массу, чтобы получить результирующую скорость. Если другая сфера движется, сделайте то же самое в обратном порядке. Конечно, вы можете упростить математику, но уже поздно, и мне не хочется этого делать:)

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

Это просто математика, но она дает правильные результаты. И, эй, я когда-то самостоятельно вычислял углы Эйлера, так что иногда моя математика «из-под салфетки» действительно срабатывает.

Это также предполагает совершенно упругие столкновения.

Если я ошибаюсь, я был бы рад узнать, где:)

...