столкновение круг-круг

Не совсем уверен, почему вы используете дженерики здесь.

Создание объекта с использованием отражения предполагает общее использование, но предположительно вы назовете create в какой-то момент и назначьте результат в String, в противном случае зачем использовать generics для управления возвращаемым типом.

Но если вы написали следующую реализацию Creator:

public class IntegerCreator implements Creator<Integer> 
{
  public Integer create() 
  { 
    ...
  }
}

И передали ее как аргумент, вы получите ClassCastException при вызове create и присвоении результата.

23
задан cletus 4 December 2009 в 14:32
поделиться

6 ответов

Столкновение между кругами легко. Представьте, что есть две окружности:

  • C1 с центром (x1, y1) и радиусом r1;
  • C2 с центром (x2, y2) и радиусом r2.

Представьте, что между этими двумя центральными точками проходит линия . Расстояние от центральных точек до края любого круга по определению равно их соответствующему радиусу. Итак:

  • если края кругов соприкасаются, расстояние между центрами равно r1 + r2;
  • любое большее расстояние, и круги не соприкасаются и не сталкиваются; и
  • меньше, а затем столкнуться.

Таким образом, вы можете обнаружить столкновение, если:

(x2-x1)^2 + (y1-y2)^2 <= (r1+r2)^2

означает, что расстояние между центральными точками меньше суммы радиусов.

Тот же принцип может быть применен к обнаружение столкновений между сферами в трех измерениях.

Изменить: если вы хотите вычислить точку столкновения, некоторые основы тригонометрии могут это сделать. У вас есть треугольник:

        (x1,y1)
        |\
        | \
        |  \ sqrt((x2-x1)^2 + (y2-y1)^2) = r1+r2
|y2-y1| |   \
        |    \
        |   X \
(x1,y2) +------+ (x2,y2)
         |x2-x1|

Выражения | x2-x1 | и | y2-y1 | являются абсолютными значениями. Итак, для угла X:

        |y2 - y1|
sin X =  -------
         r1 + r2

        |x2 - x1|
cos X =  -------
         r1 + r2

        |y2 - y1|
tan X =  -------
        |x2 - x1|

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

  +
  |\
  | \
b |  \ r2
  |   \
  |  X \
  +-----+
     a

где:

        a
cos X = --
        r2

так

a = r2 cos X

Из предыдущих формул:

       |x2 - x1|
a = r2 -------
        r1 + r2

Once у вас есть a и b, вы можете рассчитать точку столкновения с точки зрения (x2, y2) смещения на (a, b), если это необходимо. Для этого вам даже не нужно вычислять синусы, косинусы, обратные синусы или косинусы. Или любые квадратные корни в этом отношении. Так что это быстро.

Но если вам не нужен точный угол или точка столкновения, а просто нужен октант, вы можете оптимизировать его дальше, поняв кое-что о касательных, а именно:

  • 0 <= tan X <= 1 для 0 <= X <= 45 градусов;
  • tan X> = 1 для 45 <= X <= 90
  • 0> = tan X> = -1 для 0> = X => -45;
  • tan X <= -1 для -45> = X => - 90; и
  • tan X = tan (X + 180) = tan (X-180).

Эти четыре диапазона градусов соответствуют четырем октантам круга. Остальные четыре смещены на 180 градусов. Как показано выше, тангенс может быть вычислен просто как:

        |y2 - y1|
tan X =  -------
        |x2 - x1|

Потеряйте абсолютные значения, и это отношение скажет вам, в каком из четырех октантов находится столкновение (по указанным выше диапазонам касательных). Чтобы определить точный октант, просто сравните x1 и x2, чтобы определить крайний левый.

Октант столкновения на другом сингле смещен (октант 1 на C1 означает октант 5 на C2, 2 и 6, 3 и 7, 4 и 8 и т. Д.).

и
  • tan X = tan (X + 180) = tan (X-180).
  • Эти четыре диапазона градусов соответствуют четырем октантам круга. Остальные четыре смещены на 180 градусов. Как показано выше, тангенс может быть вычислен просто как:

            |y2 - y1|
    tan X =  -------
            |x2 - x1|
    

    Потеряйте абсолютные значения, и это соотношение скажет вам, в каком из четырех октантов находится столкновение (по указанным выше диапазонам касательных). Чтобы определить точный октант, просто сравните x1 и x2, чтобы определить крайний левый.

    Октант столкновения на другом сингле смещен (октант 1 на C1 означает октант 5 на C2, 2 и 6, 3 и 7, 4 и 8 и т. Д.).

    и
  • tan X = tan (X + 180) = tan (X-180).
  • Эти четыре диапазона градусов соответствуют четырем октантам круга. Остальные четыре смещены на 180 градусов. Как показано выше, тангенс может быть вычислен просто как:

            |y2 - y1|
    tan X =  -------
            |x2 - x1|
    

    Потеряйте абсолютные значения, и это отношение скажет вам, в каком из четырех октантов находится столкновение (по указанным выше диапазонам касательных). Чтобы определить точный октант, просто сравните x1 и x2, чтобы определить крайний левый.

    Октант столкновения на другом сингле смещен (октант 1 на C1 означает октант 5 на C2, 2 и 6, 3 и 7, 4 и 8 и т. Д.).

            |y2 - y1|
    tan X =  -------
            |x2 - x1|
    

    Потеряйте абсолютные значения, и это соотношение скажет вам, в каком из четырех октантов происходит столкновение (по указанным выше диапазонам касательных). Чтобы определить точный октант, просто сравните x1 и x2, чтобы определить крайний левый.

    Октант столкновения на другом сингле смещен (октант 1 на C1 означает октант 5 на C2, 2 и 6, 3 и 7, 4 и 8 и т. Д.).

            |y2 - y1|
    tan X =  -------
            |x2 - x1|
    

    Потеряйте абсолютные значения, и это соотношение скажет вам, в каком из четырех октантов происходит столкновение (по указанным выше диапазонам касательных). Чтобы определить точный октант, просто сравните x1 и x2, чтобы определить крайний левый.

    Октант столкновения на другом сингле смещен (октант 1 на C1 означает октант 5 на C2, 2 и 6, 3 и 7, 4 и 8 и т. Д.).

    111
    ответ дан 20 November 2019 в 01:50
    поделиться

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

    Ball 1:  center: p1=(x1,y1)  radius: r1
    Ball 2:  center: p2=(x2,y2)  radius: r2
    
    collision distance: R= r1 + r2
    actual distance:    r12= sqrt( (x2-x1)^2 + (y2-y2)^2 )
    

    Столкновение будет происходить всякий раз, когда (r12 < R). Как говорит Артелий, на самом деле они не должны сталкиваться по осям X / Y, они сталкиваются под определенным углом. За исключением того, что вы на самом деле не хотите этого угла; Вы хотите вектор столкновения. Это разница между центрами двух окружностей, когда они сталкиваются:

    collision vector: d12= (x2-x1,y2-y1) = (dx,dy)
    actual distance:  r12= sqrt( dx*dx + dy*dy )
    

    Обратите внимание, что вы уже вычислили dx и dy выше при расчете фактического расстояния, так что вы могли бы также отслеживать их для цели как это. Вы можете использовать этот вектор столкновений для определения новой скорости шаров - в конечном итоге вы масштабируете вектор столкновений по некоторым факторам и добавляете это к старым скоростям ... но, чтобы вернуться к фактическому столкновению Точка:

    collision point:  pcollision= ( (x1*r2+x2*r1)/(r1+r2), (y1*r2+y2*r1)/(r1+r2) )
    

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

    О, и если все еще хотите придерживаться вещи оси x / y, я думаю, что вы правильно поняли:

    if( abs(dx) > abs(dy) ) then { x-axis } else { y-axis }
    

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

    10
    ответ дан comingstorm 4 December 2009 в 14:32
    поделиться

    Точка, в которой они сталкиваются, находится на линии между средними точками двух окружностей, а расстояние от любой средней точки является радиусом этой соответствующей окружности.

    1
    ответ дан Carl Smotricz 4 December 2009 в 14:32
    поделиться

    Этот сайт объясняет физику , выводит алгоритм и предоставляет код для столкновений двумерных шаров.

    Вычислить октант после того, как эта функция вычислит следующее: положение точки столкновения относительно центра масс тела a; положение точки столкновения относительно центра масс тела a

    /**
    This function calulates the velocities after a 2D collision vaf, vbf, waf and wbf from information about the colliding bodies
    @param double e coefficient of restitution which depends on the nature of the two colliding materials
    @param double ma total mass of body a
    @param double mb total mass of body b
    @param double Ia inertia for body a.
    @param double Ib inertia for body b.
    @param vector ra position of collision point relative to centre of mass of body a in absolute coordinates (if this is
                     known in local body coordinates it must be converted before this is called).
    @param vector rb position of collision point relative to centre of mass of body b in absolute coordinates (if this is
                     known in local body coordinates it must be converted before this is called).
    @param vector n normal to collision point, the line along which the impulse acts.
    @param vector vai initial velocity of centre of mass on object a
    @param vector vbi initial velocity of centre of mass on object b
    @param vector wai initial angular velocity of object a
    @param vector wbi initial angular velocity of object b
    @param vector vaf final velocity of centre of mass on object a
    @param vector vbf final velocity of centre of mass on object a
    @param vector waf final angular velocity of object a
    @param vector wbf final angular velocity of object b
    */
    CollisionResponce(double e,double ma,double mb,matrix Ia,matrix Ib,vector ra,vector rb,vector n,
        vector vai, vector vbi, vector wai, vector wbi, vector vaf, vector vbf, vector waf, vector wbf) {
      double k=1/(ma*ma)+ 2/(ma*mb) +1/(mb*mb) - ra.x*ra.x/(ma*Ia) - rb.x*rb.x/(ma*Ib)  - ra.y*ra.y/(ma*Ia)
        - ra.y*ra.y/(mb*Ia) - ra.x*ra.x/(mb*Ia) - rb.x*rb.x/(mb*Ib) - rb.y*rb.y/(ma*Ib)
        - rb.y*rb.y/(mb*Ib) + ra.y*ra.y*rb.x*rb.x/(Ia*Ib) + ra.x*ra.x*rb.y*rb.y/(Ia*Ib) - 2*ra.x*ra.y*rb.x*rb.y/(Ia*Ib);
      double Jx = (e+1)/k * (Vai.x - Vbi.x)( 1/ma - ra.x*ra.x/Ia + 1/mb - rb.x*rb.x/Ib)
         - (e+1)/k * (Vai.y - Vbi.y) (ra.x*ra.y / Ia + rb.x*rb.y / Ib);
      double Jy = - (e+1)/k * (Vai.x - Vbi.x) (ra.x*ra.y / Ia + rb.x*rb.y / Ib)
         + (e+1)/k  * (Vai.y - Vbi.y) ( 1/ma - ra.y*ra.y/Ia + 1/mb - rb.y*rb.y/Ib);
      Vaf.x = Vai.x - Jx/Ma;
      Vaf.y = Vai.y - Jy/Ma;
      Vbf.x = Vbi.x - Jx/Mb;
      Vbf.y = Vbi.y - Jy/Mb;
      waf.x = wai.x - (Jx*ra.y - Jy*ra.x) /Ia;
      waf.y = wai.y - (Jx*ra.y - Jy*ra.x) /Ia;
      wbf.x = wbi.x - (Jx*rb.y - Jy*rb.x) /Ib;
      wbf.y = wbi.y - (Jx*rb.y - Jy*rb.x) /Ib;
    }
    
    8
    ответ дан 20 November 2019 в 01:50
    поделиться

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

    Если это то, что вы реализуете, то вы получаете правильный ответ на вопрос «Столкновение осей X или Y?». Но я думаю, что причина, по которой вы получаете здесь так много ответов, которые, похоже, не можете использовать, заключается в том, что либо

    • вы задаете неправильный вопрос (не здесь - в вашей программе); или

    • вы неправильно используете ответ.

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

    0
    ответ дан 20 November 2019 в 01:50
    поделиться

    Я согласен с предоставленными ответами, они очень хороши.
    Я просто хочу указать вам на небольшую ловушку: если скорость мячей высока, вы можете просто пропустить столкновение, потому что круги никогда не пересекаются на заданных шагах.
    Решение состоит в том, чтобы решить уравнение движения и найти правильный момент столкновения.

    В любом случае, если бы вы реализовали свое решение (сравнение по осям X и Y), вы бы получили старый добрый пинг-понг! http://en.wikipedia.org/wiki/Pong
    :)

    1
    ответ дан 20 November 2019 в 01:50
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: