быстро геометрический предикат близости

Из-за способа, которым вы настроили изображение вашего меню в первом. Вы обернули изображение в другой TouchableOpacity, что означает, что внутренний TouchableOpacity воспринимает событие касания пользователя. На самом деле это не то поведение, которое вы хотите, потому что вы хотите, чтобы TouchableOpacity в headerLeft был получателем ввода. Так что просто удалите «лишнее» TouchableOpacity.

// Inside Header
navigationOptions: ({ navigation }) => ({
    headerLeft:
    <TouchableOpacity onPress={() => {navigation.dispatch(DrawerActions.toggleDrawer())} }>
        <MenuImage navigation={navigation}/>
    </TouchableOpacity>,

//Created component and added inside navigationOptions
const MenuImage = ({navigation}) => {
    if(!navigation.state.isDrawerOpen){
        // No need of Touchable here. Since you want the above Touchable to pick up the onPress event.
        return <Image source={require('../assets/images/menu.png')} style={{width: 24, height: 24, resizeMode: 'contain' ,marginLeft: 15}}/>. 
    }else{
        return <MenuIcon style={{paddingLeft: 10, paddingRight: 10}} name="md-arrow-back" size={30} color="black"/>
    }
}

Причина, по которой работает второй пример, заключается просто в том, что нет дополнительной Touchable обработки события onPress.

5
задан BCS 1 November 2008 в 00:09
поделиться

5 ответов

Если Ваш набор (A, B, d) в фиксированном, можно вычислить пару матриц для каждого для перевода системы координат, так, чтобы строка, AB становится осью X и средней точкой AB, была источником.

Я думаю, что это - простой способ создать матрицы:

trans = - ((A + B) / 2)        // translate midpoint of AB to origin

rot.col1 = AB / AB.mag         // unit vector in AB direction

                        0 -1    
rot.col2 = rot.col1 * (      ) // unit vector perp to AB
                        1  0 

rot = rot.inverse()            // but it needs to be done in reverse

Затем Вы просто берете каждого X и делаете rot * (X + trans).

Рассматриваемый регион на самом деле симметричен в обоих оси X и Y теперь, таким образом, можно принять абсолютное значение координаты x, и координаты y.

Затем просто необходимо проверить:

y < d && x < AB.mag/2            //"along" the line segment
|| (x - AB.mag/2)^2 + y^2 < d^2  // the "end cap".

Можно сделать другой прием; матрица может уменьшиться фактором AB.mag/2 (помните, что матрицы только вычисляются однажды на (A, B) подразумевать, что лучше, что нахождение их медленнее, чем сама фактическая проверка). Это означает, что Ваша проверка становится:

y < 2*d/AB.mag && x < 1
|| (x - 1)^2 + y^2 < (2*d/AB.mag)^2

Заменив два экземпляра AB.mag/2 с постоянным 1, это могло бы быть касание быстрее. И конечно можно предварительно вычислить 2*d/AB.mag и (2*d/AB.mag)^2 также.

Удастся ли это быстрее, чем другие методы зависят от исходных данных, Вы даете его. Но если длина AB является большой по сравнению с d, я думаю, что это окажется значительно быстрее, чем метод, который Вы отправили.

2
ответ дан 14 December 2019 в 04:50
поделиться

Hmmmmmmm.... Какова частота успешных обращений? Как часто действительно указывает "X", отвечают требованиям близости?

Я думаю, что Ваш существующий алгоритм хорош, и любая дополнительная оптимизация произойдет от настройки до реальных данных. Например, если эти "X" точка встречает тест близости 99% времени, то я думаю, что Ваша стратегия оптимизации должна значительно отличаться, чем если бы это только проходит тест 1% времени.


Кстати, когда Вы переходите к сути дела, куда Вы выполняете этот алгоритм с тысячами точек, необходимо организовать все точки в Дерево K-Dimensional (или KDTree). Это делает вычисление "ближайшего соседа" намного более простым.

Ваша проблема немного более сложна, чем основное ближайшего соседа (потому что Вы проверяете proximity-to-a-line-segment, а не просто proximity-to-a-point), но я все еще думаю, что KDTree будет удобен.

2
ответ дан 14 December 2019 в 04:50
поделиться

Если я считал это правильно, то это - почти то же как классический тест на пересечение луча/сферы, как используется в 3D трассировке лучей.

В этом случае у Вас есть сфера в местоположении X из радиуса d, и Вы пытаетесь узнать, пересекает ли строка AB сферу. Одно различие с трассировкой лучей - то, что в этом случае у Вас есть определенная строка AB, тогда как в трассировке лучей луч обычно обобщается как как origin + distance * direction, и Вы не заботитесь как далеко вдоль бесконечной строки AB+ это.

В псевдокоде от моего собственного трассировщика лучей (на основе алгоритма, данного во "Введении в Трассировку лучей" (редактор Glassner):

Vector v = X - A
Vector d = normalise(B - A)  // unit direction vector of AB
double b = dot(v, B - A)
double discrim = b^2 - dot(v, v) + d^2
if (discrim < 0)
     return false            // definitely no intersection

Если Вы имеете настолько далеко, то существует некоторый шанс, что Ваше условие соблюдают. Просто необходимо выяснить, является ли пересечением (пересечениями) на строке AB:

discrim = sqrt(discrim)
double t2 = b + discrim
if (t2 <= 0)
    return false             // intersection is before A

double t1 = b  - discrim

result = (t1 < length(AB) || (t2 < length(AB))
2
ответ дан 14 December 2019 в 04:50
поделиться

Этот код закончит тем, что был выполнен для большого набора P и большого набора триплетов A/B/d с намерением нахождения всех P, которые передают по крайней мере для одного A/B/d, таким образом, я подозреваю, что существует способ уменьшить в целом стоимость на основе этого, но я еще не изучил это.

В случае, когда d ~ AB, для данной точки X, можно сначала протестировать, принадлежит ли X одной из многих сфер радиуса d и центра Ai или висмут. Посмотрите на изображение:

     ......        .....
  ...........   ...........
 ...........................
.......A-------------B.......
 ...........................
  ...........   ...........
     .....         .....

Первые два теста

If d^2 > AX.mag^2 return true
If d^2 > BX.mag^2 return true

самые быстрые, и если d ~ AB, за которым они - также те с самой высокой вероятностью для следования (учитывая, что тест успешно выполняется вообще). Учитывая X, можно сделать все "тесты сферы" сначала и затем все заключительные:

Return (BX.mag)^2 - (dot(AB,BX)/AB.mag)^2 
1
ответ дан 14 December 2019 в 04:50
поделиться

Если # наборов A/B/d являются большими, и Вы находитесь определенно в 2D, рассматриваете использование R-деревьев (или их восьмиугольные эквиваленты), где каждая запись в R-дереве является минимальной ограничительной рамкой A/B/d трижды. Это позволило бы, Вы устранить необходимость протестировать много A/B/d утраиваетесь, и сфокусируйте свою мощность ЦП только на нескольких, где каждая точка X в ограничительных рамках A/B/d трижды. Затем сделайте более подробный тест как тот, который Вы упоминаете.

1
ответ дан 14 December 2019 в 04:50
поделиться
Другие вопросы по тегам:

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