Как вычислить вершину параболы, учитывая три точки

Я понял, что у вас могут быть разные 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;
16
задан AZDean 4 April 2009 в 20:30
поделиться

4 ответа

Это - действительно просто простая проблема линейной алгебры, таким образом, можно сделать вычисление символически. Когда Вы займете место в значениях 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 ++ привязка).

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

Спасибо 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);
}

Это - то, что я хотел. Простое вычисление вершины параболы. Я обработаю целочисленное переполнение позже.

30
ответ дан 30 November 2019 в 15:21
поделиться

Вы получаете следующие три уравнения прямой заменой:

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 матрица довольно легка, таким образом, это не должно быть слишком жестко.

2
ответ дан 30 November 2019 в 15:21
поделиться

Это пахнет как домашняя работа. "Попросите, чтобы Ученый" был прав на. Скажите, что Ваши 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.

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

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