1 единица измерения Unity обычно считается равной 1 метру, однако, как только вы прочитали, это зависит от вашей реализации, в этом случае похоже, что вы на самом деле экспортируете из САПР с единицей 1 дюйм = 1, поскольку ваши результаты кажутся похоже, но немного не так.
Причина, по которой вы получаете неточности, заключается, скорее всего, в том, что система столкновений Unity не очень точная, большинство коллайдеров на самом деле немного больше, чем сетка, которую они представляют, что значительно отбросит ваши точно настроенные измерения, и вдобавок к этому Точность Unity будет намного ниже, чем у САПР, поскольку Unity - игровой движок, который должен работать в режиме реального времени, данные о 3D-координатах не очень точны (примерно с 4 цифрами они становятся довольно туманными), а на самом деле значительно ухудшаются во время путешествий. вдали от источника.
Я бы не советовал пытаться использовать Unity для каких-либо точных проектных работ, особенно при представлении реального мира, но если вы не уверены, что вы можете увеличить ваши объекты в 10 или 100 раз чтобы держать ваши цифры ближе к десятичной запятой, чтобы уменьшить ошибку с плавающей запятой, это, очевидно, хак.
Возможно, вы также захотите взглянуть на свои настройки физики: https://docs.unity3d.com/Manual/class-PhysicsManager.html В частности, может иметь значение «Смещение контакта по умолчанию» (хотя я я не уверен, влияет ли это на raycasts)
PS: я бы опубликовал это в качестве комментария, но система повторов не позволит мне, ваше описание измерений между каждой средой действительно сбивает с толку, возможно, в следующий раз Попробуйте отформатировать его в виде таблицы или еще чего-нибудь?
В отличие от этого, zip
, Python map
автоматически расширяет более короткие последовательности с помощью None
.
map(lambda a, b: b if a is None else a,
choicesTxt,
['Choice %i' % n for n in range(1, 10)])
Вы могли упростить лямбду до
map(lambda a, b: a or b,
choicesTxt,
['Choice %i' % n for n in range(1, 10)])
если это должно хорошо рассматривать другие подобные лжи объекты в choicesTxt
то же как None
.
>>> in_list = ["a","b",None,"c"]
>>> new = ['choice ' + str(i + 1) if j is None else j for i, j in enumerate(in_list)]
>>> new.extend(('choice ' +str(i + 1) for i in range(len(new), 9)))
>>> new
['a', 'b', 'choice 3', 'c', 'choice 5', 'choice 6', 'choice 7', 'choice 8', 'choice 9']
Хорошо в одной строке:
[a or 'Choice %d' % i for a,i in map(None,["a","b",None,"c"],range(10))]
Хотя это заменит что-либо, что оценивает ко Лжи (например, Ни один", 0 и т.д.) с "Выбором n". Лучше всего заменять "a or 'Choice %d' % i"
с функцией, если yuo не хотят это.
Ключевая вещь - это map
с аргументом Ни одного может использоваться для расширения списка до длины, необходимой ни с Одним в необходимых местах.
Более опрятное (больше pythonic) версия было бы:
def extend_choices(lst,length):
def replace_empty(value,index):
if value is None:
return 'Choice %d' % index
return value
return [replace_empty(value,index) for value,index in map(None,lst,range(length))]
Я также рекомендовал бы использовать xrange вместо диапазона. Функция xrange генерирует числа по мере необходимости. Диапазон генерирует их заранее. Для маленьких наборов это не имеет большого значения, но для больших спектров сбережения могут быть огромными.
def choice_n(index):
return "Choice %d" % (index + 1)
def add_choices(lst, length, default=choice_n):
"""
>>> add_choices(['a', 'b', None, 'c'], 9)
['a', 'b', 'Choice 3', 'c', 'Choice 5', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9']
"""
for i, v in enumerate(lst):
if v is None:
lst[i] = default(i)
for i in range(len(lst), length):
lst.append(default(i))
return lst
if __name__ == "__main__":
import doctest
doctest.testmod()
Если Вы не возражаете заменять что-нибудь, что оценивает ко Лжи с "Выбором %d", то result
работы для Python 2.4.
Если Вы действительно возражаете и имеете Python 2.5 и выше затем использования result2_5_plus
с питанием троичных if
.
Если Вы не любите или не можете использовать троичный если, то используйте в своих интересах факт это True == 1
и False == 0
, использование результата x is None
индексировать список.
x = ["Blue", None, 0, "", "No, Yelloooow!"]
y = [None]*9
result = [(t or "Choice %d" % (i+1))\
for i, t in enumerate(x + y[len(x):])]
result2_5_plus = [(t if t is not None else "Choice %d" % (i+1))\
for i, t in enumerate(x + y[len(x):])]
result_no_ternary_if = [[t, "Choice %d" % (i+1)][t is None]\
for i, t in enumerate(x + y[len(x):])]
['Blue', 'Choice 2', 'Choice 3', 'Choice 4', 'No, Yelloooow!', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9']
['Blue', 'Choice 2', 0, '', 'No, Yelloooow!', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9']
Вы могли пойти более простые с пониманием списка:
extendedChoices = choices + ([None] * (10 - len(choices)))
newChoices = ["Choice %d" % (i+1) if x is None else x
for i, x in enumerate(extendedChoices)]
Это добавляет None
к Вашему списку выбора, пока это не имеет по крайней мере 10 объектов, перечисляет через результат и вставляет "Выбор X", если элемент Xth отсутствует.
choices[:] = ([{False: x, True: "Choice %d" % (i + 1)}[x is None] for i, x in enumerate(choices)] +
["Choice %d" % (i + 1) for i in xrange(len(choices), 9)])
Я сделал бы
for i, c in enumerate(choices):
if c is None:
choices[i] = 'Choice X'
choices += ['Choice %d' % (i+1) for i in range(len(choices), 10)]
который только заменяет фактический None
значения (ничто, что оценивает как ложь), и расширяют список на разделенном шаге, который я думаю, более ясно.
Что относительно этого (кажется, dict - не список - когда это неполно),
a = {1:'a', 2:None, 5:'e'} #test data
[a[x] if x in a and a[x] is not None else 'Choice %d'%x for x in xrange(1,10)]
Редактирование еще раз: Если это - действительно список (не dict):
b=['a',None,'b']
[b[x] if len(b)>x and b[x] is not None else 'Choice %d'%x for x in xrange(10)]
потребности Python 2.5 я думаю (из-за тернарного оператора)?
(Благодаря joeforker, зафиксированному это, это использует ключи 1 - 10 а не от 0 до 10 больше; благодаря SilentGhost: в больше pythonic, чем has_key () или len ()),
Я немного неясен о том, почему Вы используете диапазон (1, 10); так как Вы используете choicesTxt [я], который заканчивает тем, что пропустил проверку Ни одного на первый элемент в Вашем списке.
Кроме того, существуют, очевидно, более легкие способы сделать это, если Вы создаете новый список, но Вы просите конкретно добавлять к существующему списку.
Я не думаю, что это - действительно инструмент для очистки или быстрее, но это - другая идея для Вас думать о.
for i, v in enumerate(choicesTxt):
choicesTxt[i] = v or "Choice " + str(i + 1)
choicesTxt.extend([ "Choice " + str(i) for i in range(len(choicesTxt) + 1, 10) ])
Самый простой и большая часть pythonic для меня:
repl = lambda i: "Choice %d" % (i + 1) # DRY
print ([(x or repl(i)) for i, x in enumerate(aList)]
+ [repl(i) for i in xrange(len(aList), 9)])
Вы могли использовать карту (словарь) вместо списка:
choices_map = {1:'Choice 1', 2:'Choice 2', 3:'Choice 12'}
for key in xrange(1, 10):
choices_map.setdefault(key, 'Choice %d'%key)
Затем у Вас есть карта, заполненная Вашими данными.
Если Вы хотите список вместо этого, можно сделать:
choices = choices_map.values()
choices.sort() #if you want your list to be sorted
#In Python 2.5 and newer you can do:
choices = [choices_map[k] for k in sorted(choices_map)]
Я думаю, что необходимо рассматривать изменение размеров массива как отдельный шаг. Для этого в случае массив слишком короток, звонить choicesTxt=choicesTxt+[None]*(10-len(choicesTxt))
. None
переназначение выбора может быть сделано с помощью пониманий списка.
Я нахожу, что, когда понимания списка становятся долгими, лучше просто использовать стандарт для цикла. Почти то же как другие, но так или иначе:
>>> in_list = ["a","b",None,"c"]
>>> full_list = in_list + ([None] * (10 - len(in_list)))
>>> for idx, value in enumerate(full_list):
... if value == None:
... full_list[idx] = 'Choice %d' % (idx + 1)
...
>>> full_list
['a', 'b', 'Choice 3', 'c', 'Choice 5', 'Choice 6', 'Choice 7', 'Choice 8', 'Choice 9', 'Choice 10']
Моя первоначальная реакция должна была разделить расширение списка и "восполняющий пробелы" в отдельные части как так:
for i, v in enumerate(my_list):
my_list[i] = v or "Choice %s" % (i+1)
for j in range(len(my_list)+1, 10):
my_list.append("Choice %s" % (j))
# maybe this is nicer for the extension?
while len(my_list) < 10:
my_list.append("Choice %s" % (len(my_list)+1))
Если Вы действительно придерживаетесь с try...except
приблизьтесь, действительно поймайте определенное исключение как шоу Douglas. Иначе Вы поймаете все: KeyboardInterrupts
, RuntimeErrors
, SyntaxErrors
.... Вы не хотите делать это.
Править: фиксированная 1-индексируемая ошибка списка - благодарит DNS!
Править: добавленное альтернативное расширение списка
Я думаю, что сделал бы что-то в значительной степени как этот, но с несколькими опрятными взлетами:
for i in range(0,10):
try:
if choicesTxt[i] is None:
choicesTxt[i] = "Choice %d"%i
except IndexError:
choicesTxt.append("Choice %d"%i)
Из которых единственные важные два должны только поймать IndexError
вместо любого исключения, и индексировать от 0.
И единственная настоящая проблема с оригиналом состояла бы в том если choicesTxt
пусто, когда добавленный выбор будет выключен одним.