Вы должны использовать скалярное произведение. Скажем, у вас есть V ₁ = ( x ₁, y ₁, z ₁) и V ₂ = ( x ₂, y ₂, z ₂), то скалярное произведение, которое я обозначу через V ₁ · V ₂, рассчитывается как
V ₁ · V ₂ = x ₁ · x ₂ + y ₁ · y ₂ + z ₁ · z ₂ = | V ₁ | · | V ₂ | · Cos ( θ );
Это означает, что указанная слева сумма равна произведению абсолютных значений векторов на косинус угла между векторами. абсолютное значение векторов V ₁ и V ₂ рассчитывается как
| V ₁ | = √ ( x ₁² + y ₁² + z ₁²) и
| V ₂ | = √ ( x ₂² + y ₂² + z ₂²),
Итак, если вы переставите первое уравнение выше, Вы получите
cos ( θ ) = ( x ₁ · x ₂ + y ₁ · y ₂ + z ₁ · z ₂) ÷ (| V ₁ | · | V ₂ | ),
и вам просто нужна функция arccos (или обратный косинус), примененная к cos ( θ ), чтобы получить угол.
В зависимости от функции arccos угол может быть в градусах или радианах.
(Для двумерных векторов, просто забудьте про z -координаты и сделайте те же вычисления.)
Удачи,
Джон Донер
Изменить: упс! сделал ошибку во второй строке кода. - исправлено.
Иногда я ненавижу определять свойство источника данных.
Я думаю, что всякий раз, когда вы создаете и устанавливаете новую строку для "row", по какой-то странной причине старое значение удаляется. попробуйте не использовать экземпляр для хранения создаваемых вами строк:
int i;
i = gridViewParts.Rows.Add( new DataGridViewRow());
DataGridViewCell cellQuantity = new DataGridViewTextBoxCell();
cellQuantity.Value = item.Quantity;
gridViewParts.Rows[i].Cells["colQuantity"] = cellQuantity;
Похоже, что ячейки отлично работают с экземплярами ячеек. Я понятия не имею, почему для строк это другое. Могут потребоваться дополнительные проверки ...
Чтобы расширить этот вопрос, есть еще один способ добавить строку в DataGridView
, особенно, если столбцы всегда одинаковы:
object[] buffer = new object[5];
List<DataGridViewRow> rows = new List<DataGridViewRow>();
foreach (SaleItem item in this.Invoice.SaleItems)
{
buffer[0] = item.Quantity;
buffer[1] = item.Part.Description;
buffer[2] = item.Price;
buffer[3] = item.Quantity * item.Price;
buffer[4] = item.Part.Number;
rows.Add(new DataGridViewRow());
rows[rows.Count - 1].CreateCells(gridViewParts, buffer);
}
gridViewParts.Rows.AddRange(rows.ToArray());
Или, если вам нравится ParamArrays:
List<DataGridViewRow> rows = new List<DataGridViewRow>();
foreach (SaleItem item in this.Invoice.SaleItems)
{
rows.Add(new DataGridViewRow());
rows[rows.Count - 1].CreateCells(gridViewParts,
item.Quantity,
item.Part.Description,
item.Price,
item.Quantity * item.Price,
item.Part.Number
);
}
gridViewParts.Rows.AddRange(rows.ToArray());
Очевидно, что значения в буфере должны быть в том же порядке, что и столбцы (включая скрытые).
Это самый быстрый Я нашел способ получить данные в DataGridView
без привязки сетки к DataSource
. Связывание сетки на самом деле ускорит ее на значительное количество времени, и если у вас более 500 строк в сетке,