Я понял, что у вас могут быть разные DDL. Если это так, я предлагаю вам иметь таблицу для управления версиями. Используя эту таблицу, вы можете иметь уникальный номер версии каждый раз, когда у вас есть новый скрипт DDL / DML. Затем вы можете проверить, существует ли этот номер версии в таблице версий, и если это не так, вы можете выполнить сценарий DDL, после чего вам нужно вставить номер версии в таблицу версий.
BEGIN
DECLARE @version_number VARCHAR(30) DEFAULT 'V10298492';
DECLARE @VERSION_EXISTS INT ;
SELECT COUNT(*)
INTO @VERSION_EXISTS
FROM CMS_VERSION
WHERE VERSION_NUMBER = @version_number;
IF (@VERSION_EXISTS = 0)
RETURN;
END IF;
--DDL SCRIPT AFTER THIS POINT
...
--END OF DDL SCRIPT
INSERT INTO CMS_VERSION (VERSION_NUMBER)
VALUES (@version_number);
END;
Это - действительно просто простая проблема линейной алгебры, таким образом, можно сделать вычисление символически. Когда Вы займете место в значениях X и Y Ваших трех точек, Вы получите три линейных уравнения в трех неизвестных.
A x1^2 + B x1 + C = y1
A x2^2 + B x2 + C = y2
A x3^2 + B x3 + C = y3
Простой способ решить это состоит в том, чтобы инвертировать матрицу
x1^2 x1 1
x2^2 x2 1
x3^2 x3 1
и умножьте его на вектор
y1
y2
y3
Результат этого... хорошо, не точно все что прост ;-) Я сделал это в Mathematica и здесь являюсь формулами в псевдокоде:
denom = (x1 - x2)(x1 - x3)(x2 - x3)
A = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) / denom
B = (x3^2 * (y1 - y2) + x2^2 * (y3 - y1) + x1^2 * (y2 - y3)) / denom
C = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3) / denom
С другой стороны, если бы Вы хотели сделать матричную математику численно, то Вы обычно обращались бы к системе линейной алгебры (как ATLAS, хотя я не уверен, имеет ли это C#/C ++ привязка).
Спасибо David, я преобразовал Ваш псевдокод в следующий код C#:
public static void CalcParabolaVertex(int x1, int y1, int x2, int y2, int x3, int y3, out double xv, out double yv)
{
double denom = (x1 - x2) * (x1 - x3) * (x2 - x3);
double A = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) / denom;
double B = (x3*x3 * (y1 - y2) + x2*x2 * (y3 - y1) + x1*x1 * (y2 - y3)) / denom;
double C = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3) / denom;
xv = -B / (2*A);
yv = C - B*B / (4*A);
}
Это - то, что я хотел. Простое вычисление вершины параболы. Я обработаю целочисленное переполнение позже.
Вы получаете следующие три уравнения прямой заменой:
A*x1^2+B*x1+C=y1
A*x2^2+B*x2+C=y2
A*x3^2+B*x3+C=y3
Можно решить это путем отмечания, что это эквивалентно матричному произведению:
[x1^2 x1 1] [A] [y1]
|x2^2 x2 1|*|B| = |y2|
[x3^2 x3 1] [C] [y3]
Таким образом, можно получить A, B, и C путем инвертирования матрицы и умножения инверсии с вектором справа.
Я вижу, что, в то время как я отправлял этого John Rasch, связался с учебным руководством, которое входит в большую глубину при фактическом решении матричного уравнения, таким образом, можно следовать тем инструкциям для получения ответа. При инвертировании 3x3 матрица довольно легка, таким образом, это не должно быть слишком жестко.
Это пахнет как домашняя работа. "Попросите, чтобы Ученый" был прав на. Скажите, что Ваши 3 точки (x1, y1), (x2, y2), и (x3, y3). Затем Вы получаете три линейных уравнения:
| M11 M12 M13 | | A | | Z1 | | M21 M22 M23 | * | B | = | Z2 | | M31 M32 M33 | | C | | Z3 |
Где M11 = x12, M12 = x1, M13 = 1, Z1 = y1, и так же для других двух использований строк (x2, y2) и (x3, y3) вместо (x1, y1).
Решение этой системы 3 уравнений даст Вам решение для A, B, и C.