Из-за способа, которым вы настроили изображение вашего меню в первом. Вы обернули изображение в другой 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.
Если Ваш набор (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, я думаю, что это окажется значительно быстрее, чем метод, который Вы отправили.
Hmmmmmmm.... Какова частота успешных обращений? Как часто действительно указывает "X", отвечают требованиям близости?
Я думаю, что Ваш существующий алгоритм хорош, и любая дополнительная оптимизация произойдет от настройки до реальных данных. Например, если эти "X" точка встречает тест близости 99% времени, то я думаю, что Ваша стратегия оптимизации должна значительно отличаться, чем если бы это только проходит тест 1% времени.
Кстати, когда Вы переходите к сути дела, куда Вы выполняете этот алгоритм с тысячами точек, необходимо организовать все точки в Дерево K-Dimensional (или KDTree). Это делает вычисление "ближайшего соседа" намного более простым.
Ваша проблема немного более сложна, чем основное ближайшего соседа (потому что Вы проверяете proximity-to-a-line-segment, а не просто proximity-to-a-point), но я все еще думаю, что KDTree будет удобен.
Если я считал это правильно, то это - почти то же как классический тест на пересечение луча/сферы, как используется в 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))
Этот код закончит тем, что был выполнен для большого набора 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
Если # наборов A/B/d являются большими, и Вы находитесь определенно в 2D, рассматриваете использование R-деревьев (или их восьмиугольные эквиваленты), где каждая запись в R-дереве является минимальной ограничительной рамкой A/B/d трижды. Это позволило бы, Вы устранить необходимость протестировать много A/B/d утраиваетесь, и сфокусируйте свою мощность ЦП только на нескольких, где каждая точка X в ограничительных рамках A/B/d трижды. Затем сделайте более подробный тест как тот, который Вы упоминаете.