Должен Кватернион базировался, 3D Камеры накапливают Кватернионы или Euler углы?

Создайте собственный универсальный конвертер для сложных объектов в качестве выбранного элемента

. Balusc дает очень полезный обзорный обзор по этому вопросу. Но есть одна альтернатива, которую он не представляет: Roll-your-общий универсальный конвертер, который обрабатывает сложные объекты как выбранный элемент. Это очень сложно сделать, если вы хотите обрабатывать все случаи, но довольно просто для простых случаев.

В приведенном ниже коде содержится пример такого конвертера. Он работает в том же духе, что и OmniFaces SelectItemsConverter , поскольку он просматривает дочерние элементы компонента для объектов, содержащихся в UISelectItem(s). Разница в том, что он обрабатывает привязки только к простым коллекциям объектов сущности или к строкам. Он не обрабатывает группы элементов, коллекции SelectItem s, массивы и, возможно, много других вещей.

Сущности, к которым должен привязываться компонент, должны реализовать интерфейс IdObject. (Это можно решить другим способом, например, с помощью toString.)

Обратите внимание, что сущности должны реализовать equals таким образом, чтобы два объекта с одинаковым идентификатором сравнивались равными.

Единственное, что вам нужно сделать, чтобы использовать его, - это указать его как конвертер на компоненте select, привязать его к свойству сущности и списку возможных объектов:


  
  
  

Конвертер:

/**
 * A converter for select components (those that have select items as children).
 * 
 * It convertes the selected value string into one of its element entities, thus allowing
 * binding to complex objects.
 * 
 * It only handles simple uses of select components, in which the value is a simple list of
 * entities. No ItemGroups, arrays or other kinds of values.
 * 
 * Items it binds to can be strings or implementations of the {@link IdObject} interface.
 */
@FacesConverter("selectListConverter")
public class SelectListConverter implements Converter {

  public static interface IdObject {
    public String getDisplayId();
  }

  @Override
  public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if (value == null || value.isEmpty()) {
      return null;
    }

    return component.getChildren().stream()
      .flatMap(child -> getEntriesOfItem(child))
      .filter(o -> value.equals(o instanceof IdObject ? ((IdObject) o).getDisplayId() : o))
      .findAny().orElse(null);
  }

  /**
   * Gets the values stored in a {@link UISelectItem} or a {@link UISelectItems}.
   * For other components returns an empty stream.
   */
  private Stream getEntriesOfItem(UIComponent child) {
    if (child instanceof UISelectItem) {
      UISelectItem item = (UISelectItem) child;
      if (!item.isNoSelectionOption()) {
        return Stream.of(item.getValue());
      }

    } else if (child instanceof UISelectItems) {
      Object value = ((UISelectItems) child).getValue();

      if (value instanceof Collection) {
        return ((Collection) value).stream();
      } else {
        throw new IllegalStateException("Unsupported value of UISelectItems: " + value);
      }
    }

    return Stream.empty();
  }

  @Override
  public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value == null) return null;
    if (value instanceof String) return (String) value;
    if (value instanceof IdObject) return ((IdObject) value).getDisplayId();

    throw new IllegalArgumentException("Unexpected value type");
  }

}

16
задан Chris Blackwell 27 December 2008 в 00:05
поделиться

3 ответа

Умножение кватернионов собирается пострадать от накопления проблем округления с плавающей точкой (даже простые углы как 45 градусов не будут точны). Это - отличный способ составить вращения, но точность каждого из Ваших компонентов кватерниона идет в зону высадки пассажиров со временем. Проступание является одним побочным эффектом, визуально худший, хотя Ваш кватернион, мог начать включать масштабный коэффициент - для восстановления этого, необходимо будет повторно нормализовать назад к Euler углам в любом случае. Фиксированная точка Euler угол не собирается накапливать округление.

Перевычисление кватерниона на кадр минимально. Я не потрудился бы пытаться оптимизировать его. Вы могли, вероятно, позволить нескольким кватернионам накапливаться перед перенормализацией для возвращения точности, но это действительно не стоит усилия.

13
ответ дан 30 November 2019 в 22:31
поделиться

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

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

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

неприятность здесь - то, что quaterions, кажется, стали избыточными (для этого конкретного использования, по крайней мере). Вы все еще хотите кватернионы, хотя - интерполирующий с необработанной подачей/отклонением от курса/углами вращения может быть ужасным. Снова, это - вопрос о дизайне интерфейса: необходимо выяснить, где Вам будут нужны кватернионы, и как вложить их и...

4
ответ дан 30 November 2019 в 22:31
поделиться

Я видел, что оба привели доводы. Я думаю реальный вопрос, с которым необходимо будет иметь дело, гибкость в системе камеры по линии; отклонение от курса IMO обычно более интересно в представлении третьего лица (потому что Вы собираетесь вращаться о вертикальной оси символа). В то время как можно возможно "отклоняться от курса" вокруг вертикали в первоклассном представлении также, я не уверен, что это - действительно то же самое.

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

1
ответ дан 30 November 2019 в 22:31
поделиться
Другие вопросы по тегам:

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