У меня есть очень простой вопрос о MATLAB. Что является самым легким способом найти точку пересечения между двумя векторами. Я не знаком с различными функциями MATLAB - кажется, что должно быть один для этого.
Например, если у меня есть один вектор от (0,0) до (6,6) и другой вектор от (0,6) до (6,0), я должен решить, что они пересекаются в (3,3).
Боюсь, это не сработает, поскольку объявленные вами два лямбда-выражения (и делегаты) фактически являются разными объектами и возвращают разные ссылки. Следовательно, удаление обработчика ( - =
) всегда будет неуспешным.
Общим решением этой проблемы (где необходимо удалить обработчик) является просто переформатирование выражения лямбы в правильный метод. Альтернативой является сохранение переменной класса для делегата обработчика событий и добавление и удаление этого, хотя лично я не являюсь его поклонником. (Это больше хлопот, чем просто создание обычного метода, если что.)
-121--1019982-// Uses the compiler's type inference mechanisms for generics to find out the type
// 'self' was declared with in the current scope.
static public Type GetDeclaredType<TSelf>(TSelf self)
{
return typeof(TSelf);
}
void Main()
{
// ...
Foo bar;
bar = null;
Type myType = GetDeclaredType(bar);
Console.Write(myType.Name);
}
Принты:
Foo
Я разместил это также на аналогичную тему, я надеюсь, что это может быть использовано для вас.; -)
-121--933713-Одним из решений является использование уравнений, полученных в данном руководстве, для нахождения точки пересечения двух линий в 2-D ( обновление: это ссылка на архив в Интернете, поскольку сайт больше не существует). Сначала можно создать две матрицы: одну для хранения координат x конечных точек линии и одну для сохранения координат y.
x = [0 0; 6 6]; %# Starting points in first row, ending points in second row
y = [0 6; 6 0];
Уравнения из вышеуказанного источника можно затем кодировать следующим образом:
dx = diff(x); %# Take the differences down each column
dy = diff(y);
den = dx(1)*dy(2)-dy(1)*dx(2); %# Precompute the denominator
ua = (dx(2)*(y(1)-y(3))-dy(2)*(x(1)-x(3)))/den;
ub = (dx(1)*(y(1)-y(3))-dy(1)*(x(1)-x(3)))/den;
Теперь можно вычислить точку пересечения двух строк:
xi = x(1)+ua*dx(1);
yi = y(1)+ua*dy(1);
Для примера в вопросе приведенный выше код дает xi = 3
и yi = 3
, как и ожидалось. Если требуется проверить, что точка пересечения лежит между конечными точками линий (т.е. они являются конечными отрезками ), необходимо просто проверить, что значения ua
и ub
лежат между 0 и 1:
isInSegment = all(([ua ub] >= 0) & ([ua ub] <= 1));
Еще несколько точки из учебного пособия, к которому я ссылался выше:
den
равен 0, то две линии параллельны. ua
и ub
0, то две строки совпадают. Благодаря Кевину, Митчу и Нафтоли Гугенхайму и Даниэлю Собралу из списка рассылки пользователей, у меня есть хороший ответ. Два предыдущих ответа работают, но приводят к экспоненциальному взрыву в количестве признаков, классов и конструкторов. Однако использование имплицитов и границ просмотра позволяет избежать этой проблемы. Шаги решения:
1) Задать нормальный параметр типа, представляющий тип его аргумента. 2) Определите импликты, принимающие Normal с правильным типом аргумента для того, который реализует соответствующий алгоритм. Например, makeImpression принимает нормальное значение [Важность] и создает нормальное значение важности. 3) Имплицитам нужно дать привязку типа. Причина в том, что без ограничения типа, если вы пытаетесь передать нормальный [T] makeImpression, где T является подтипом важности, он не будет работать, потому что нормальный [T] не является подтипом нормального [важности], потому что нормальный не является ковариантным. 4) Эти границы типа должны быть границами просмотра, чтобы позволить имплицитам связываться.
Вот полное решение:
class Model
trait Importance extends Model {
def forward: Int
}
trait MCMC extends Model {
def propose: String
}
class Normal[T <% Model](val arg: T) extends Model
class NormalImportance(arg: Importance) extends Normal(arg) with Importance {
def forward = arg.forward + 1
}
class NormalMCMC(arg: MCMC) extends Normal(arg) with MCMC {
def propose = arg.propose + "N"
}
object Normal {
def apply[T <% Model](a: T) = new Normal[T](a)
}
object Importance {
implicit def makeImportance[T <% Importance](n: Normal[T]): Importance =
new NormalImportance(n.arg)
}
object MCMC {
implicit def makeMCMC[T <% MCMC](n: Normal[T]): MCMC = new NormalMCMC(n.arg)
}
object Uniform extends Model with Importance with MCMC {
def forward = 4
def propose = "Uniform"
}
def main(args: Array[String]) {
val n = Normal(Normal(Uniform))
println(n.forward)
println(n.propose)
}
-121--3926565- SELECT *
FROM mytable
ORDER BY
column1 DESC, column2 ASC
-121--1786312- Ну, у вас действительно есть две точки на двух разных прямых, и вы хотите найти пересечение. Самый простой способ - найти уравнения двух прямых и затем вычислить пересечение.
Уравнение прямой задается как y = mx + b , где m - наклон, а b - y-перехват. Для одной прямой у вас есть две точки, которые дают два уравнения. Таким образом, можно решить для констант m и b . Это дает следующие два уравнения:
0 = 0*m + 1*b % Using the first point x=y=0 into y=m*x+b
6 = 6*m + 1*b % Using the second point x=y=6
Или в матричной форме:
[ 0 ] = [ 0 1 ]* [ m ]
[ 6 ] [ 6 1 ] [ b ]
Для первой строки константы могут быть вычислены в MATLAB
C1 = inv([0 1;6 1]*[1;0]; % m=C1(1) and b=C(2)
Теперь, когда у вас есть уравнение для двух прямых, вы можете решить для пересечения путем решения следующей системы уравнений (которые получены путем манипулирования уравнением для прямой):
m_1*x-y = -b_1
m_2*x-y = -b_2
Все, что осталось, это написать вышеуказанную систему уравнений в матричной форме и решить:
[x] = inv [m_1 -1] * [-b_1]
[y] [m_2 -1] [-b_2]
Или в синтаксисе MATLAB:
I = inv([m_1 -1; m_2 -1])*[-b_1;-b_2]; % I is the intersection.
Примечания
В соответствии с комментарием gnovice, если линии на самом деле являются сегментами линий, необходимо проверить, находится ли пересечение между конечными точками сегментов линий.
Если два наклона равны, m_1 = m_2, то пересечений либо не будет, либо будет бесконечно много.
Для общего многоразмерного решения вы действительно делаете, решает серию линейных систем.
Сначала вам нужно уменьшить уравнения к линейной форме: AX + by = C
(расширить размеры по мере необходимости)
для двух точек:
y - y1 = (y2 - y1) / (x2 - x1) * (x - x1)
y - y1 = (y2 - y1) / (x2 - x1) * x - (y2 - y1) / (x2 - x1) * x1
(y1 - y2) / (x2 - x1) * x + y - y1 = (y1 - y2) / (x2 - x1) * x1
(y1 - y2) / (x2 - x1) * x + y = (y1 - y2) / (x2 - x1) * x1 + y1
(y1 - y2) * x + (x2 - x1) * y = (y1 - y2) * x1 + (x2 - x1) * y1
A = (y1 - y2)
B = (x2 - x1)
C = (y1 - y2) * x1 + (x2 - x1) * y1 = A * x1 + B * y1
для вашего примера:
x1 = 0, x2 = 6, y1 = 0, y2 = 6
A1 = (0 - 6) = -6
B1 = (6 - 0) = 6
C1 = A1 * 0 + B1 * 0 = 0
x1 = 0, x2 = 6, y1 = 6, y2 = 0
A2 = (6 - 0) = 6
B2 = (6 - 0) = 6
C2 = A2 * 0 + B2 * 6 = 6 * 6 = 36
затем Сформируйте матрицу, с AB и C в рядах:
[A1 B1 C1]
[A2 B2 C2]
[-6 6 0]
[ 6 6 36]
Теперь уменьшается к уменьшению эшелонной формы с использованием функции MATLAB RREF (MATRIX)
:
[ 1 0 3]
[ 0 1 3]
Как вы можете догадаться, последний столбец является вашим пересечением точка. Это расширяется до такой же размеры, по мере необходимости. Если ваша уменьшающаяся форма эшелона имеет что-то кроме матрицы личности для передней части его, ваши векторы либо не имеют уникальной точки пересечения, либо не имеют точки пересечения, в зависимости от формы матрицы.
dim = 2;
% Do other stuff, ending with rref(matrix)
if (matrix(:,1:dim) == eye(dim))
% Matrix has unique solution.
solution = (matrix(:,dim+1))'
else
% No unique solution.
end
В двух измерениях вариации являются:
x + by = C
: [ 1 B C]
[ 0 0 0]
[ 1 B C]
[ 0 0 0]
C2 <> 0
: [ 1 B C1]
[ 0 0 C2]