Javascript: стрелка компаса - вращение прыгает от 0 до 359. Как исправить? [Дубликат]

Предположим, у вас есть большой проект, написанный на c ++, который содержит тысячу файлов .cpp и тысячу файлов .h. И давайте предположим, что проект также зависит от десяти статических библиотек. Скажем, мы работаем над Windows, и мы строим наш проект в Visual Studio 20xx. Когда вы нажимаете Ctrl + F7 Visual Studio, чтобы начать компиляцию всего решения (предположим, что у нас есть только один проект в решении)

В чем смысл компиляции?

  • Visual Studio выполните поиск в файле .vcxproj и начните компилировать каждый файл с расширением .cpp. Порядок компиляции не определен. Поэтому вы не должны предполагать, что файл main.cpp скомпилирован сначала
  • . Если файлы .cpp зависят от дополнительных файлов .h, чтобы найти символы, которые могут или не могут быть определены в файл .cpp
  • Если существует один .cpp-файл, в котором компилятор не смог найти один символ, ошибка времени компилятора вызывает сообщение Символ x не может быть найден
  • Для каждого файла с расширением .cpp создается объектный файл .o, а также Visual Studio записывает вывод в файл с именем ProjectName.Cpp.Clean.txt , который содержит все объектные файлы, которые должны обрабатывается компоновщиком.

Второй этап компиляции выполняется Linker.Linker должен объединить весь объектный файл и построить окончательно вывод (который может быть исполняемым или библиотекой)

Шаги при связывании проекта

  • Разберите все объектные файлы и найдите определение, которое было объявлено только в заголовках (например: Код одного метода класса, как указано в p повторные ответы или событие инициализация статической переменной, которая является членом внутри класса)
  • Если один символ не может быть найден в объектных файлах, он также выполняется в дополнительных библиотеках. Для добавления новой библиотеки в project Свойства конфигурации -> Каталоги VC ++ -> Библиотечные каталоги, и здесь вы указали дополнительную папку для поиска библиотек и Свойства конфигурации -> Linker -> Input для указания имени библиотеки. -Если линкер не смог найти символ, который вы пишете в одном .cpp, он вызывает ошибку времени компоновщика, которая может звучать как error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ)

Наблюдение

  1. После того, как Linker найдет один символ, он не ищет в других библиотеках для него
  2. Порядок ссылок на библиотеки имеет значение.
  3. Если Linker находит внешний символ в одной статической библиотеке, он включает в себя символ на выходе проекта. Однако, если библиотека является общей (динамической), он не включает в себя код (символы) на выходе, но Run-Time могут возникнуть сбои

Как решить эту ошибку

Ошибка времени компилятора:

  • Убедитесь, что вы правильно выполнили синтаксический проект c ++.

Ошибка времени компоновщика

  • Определите все символы, которые вы объявляете в ваших файлах заголовков.
  • Используйте #pragma once, чтобы компилятор не включал один заголовок если он уже был включен в текущий .cpp, который скомпилирован
  • Убедитесь, что ваш exter nal library не содержит символов, которые могут вступать в конфликт с другими символами, которые вы определили в ваших файлах заголовков.
  • Когда вы используете шаблон, чтобы убедиться, что вы включаете определение каждой функции шаблона в файл заголовка для разрешения компилятор для создания соответствующего кода для любых экземпляров.
4
задан elbarto132 27 October 2013 в 15:45
поделиться

2 ответа

Преобразование делает именно то, что вы говорите.

Он начинается с 359deg и переходит на 1deg. Вы ищете «rollover» 360deg назад до 1deg, что на самом деле 361deg. Способ преобразования преобразований состоит в том, что он интерполирует между значениями.

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

var rot = 0;  // lets start at zero, you can apply whatever later

значение поворота, значение изменения:

rot = 359;
// note the extra brackets to ensure the expression is evaluated before
//   the string is assigned this is require in some browsers
element.style.transform = ("rotate( " + rot + "deg )");

, поэтому, если вы это сделаете:

rot = 1;
element.style.transform = ("rotate( " + rot + "deg )");

он возвращается. Таким образом, вам нужно увидеть, если он ближе к 360 или 0 независимо от того, сколько оборотов прошло. Вы делаете это, проверяя значение element.style.transform, которое является текущим значением rot, а затем сравнивается с новым значением rot. Тем не менее, вам нужно сделать это в отношении того, сколько вращений может существовать, поэтому:

var apparentRot = rot % 360;

Теперь, независимо от того, сколько у него было спинов, вы знаете, как далеко от него, отрицательные значения равны к значению + 360:

if ( apparentRot < 0 ) { apparentRot += 360; } 

Теперь вы нормализуете любые отрицательные значения и можете спросить, требуется ли положительное вращение (через 360 градусов в вашем случае) или отрицательный. Поскольку вы, кажется, даете новое значение вращения как 0-360deg, это упрощает вашу проблему. Вы можете спросить, находится ли новое вращение + 360 ближе к старому значению, чем новое вращение:

var aR,          // what the current rotation appears to be (apparentRot shortened)
    nR,          // the new rotation desired (newRot)
    rot;         // what the current rotation is and thus the 'counter'

// there are two interesting events where you have to rotate through 0/360
//   the first is when the original rotation is less than 180 and the new one
//   is greater than 180deg larger, then we go through the apparent 0 to 359...
if ( aR < 180 && (nR > (aR + 180)) ) {
    // rotate back
    rot -= 360;
} 

//   the second case is when the original rotation is over 180deg and the new
//   rotation is less than 180deg smaller
if ( aR >= 180 && (nR <= (aR - 180)) ) {
    // rotate forward
    rot += 360;
}

Кроме этого просто добавление значения нового вращения к rot - это все, что необходимо:

rot += (nR - aR); //  if the apparent rotation is bigger, then the difference is
                  //  'negatively' added to the counter, so the counter is
                  //  correctly kept, same for nR being larger, the difference is
                  //  added to the counter

Немного почистить его:

var el, rot;

function rotateThis(element, nR) {
    var aR;
    rot = rot || 0; // if rot undefined or 0, make 0, else rot
    aR = rot % 360;
    if ( aR < 0 ) { aR += 360; }
    if ( aR < 180 && (nR > (aR + 180)) ) { rot -= 360; }
    if ( aR >= 180 && (nR <= (aR - 180)) ) { rot += 360; }
    rot += (nR - aR);
    element.style.transform = ("rotate( " + rot + "deg )");
}

// this is how to intialize  and apply 0
el = document.getElementById("elementYouWantToUse");
rotateThis(el, 0);

// now call function
rotateThis(el, 359);
rotateThis(el, 1);

Счетчик может идти положительно или отрицательно, это не имеет значения, просто используйте значение между 0- 359 для нового вращения.

15
ответ дан thisiate 28 August 2018 в 01:10
поделиться

Посмотрите, можете ли вы использовать отрицательные числа. Переход от -1deg к 0deg по часовой стрелке, переход от 359deg к 0deg против часовой стрелки.

0
ответ дан RoryKoehein 28 August 2018 в 01:10
поделиться
Другие вопросы по тегам:

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