Пересечение прямой и сферы? - PullRequest
3 голосов
/ 26 мая 2009

У меня есть простой объект, который позволяет вам назначить три свойства (x, y, z) (давайте назовем этот объект «точкой», потому что это то, что он есть). Затем у меня есть второй объект с методом, который принимает два экземпляра первого объекта и возвращает расстояние между двумя «точками» в трехмерном пространстве. Мне также нужен метод, который будет принимать две "точки" и double, представляющий пройденное расстояние (от первого используемого параметра «точка»), который возвращает «точечный» объект с его координатами x, y, z.

Я в порядке со всем, кроме вычисления координат точек, которые находятся на исходной линии между двумя поставленными точками, то есть на определенном расстоянии от первой точки.

«точечный» объект:

public class POR
{
    private double PORX;
    private double PORY;
    private double PORZ;

    public double X
    {
        get { return PORX; }
        set { PORX = value; }
    }
    public double Y
    {
        get { return PORY; }
        set { PORY = value; }
    }
    public double Z
    {
        get { return PORZ; }
        set { PORZ = value; }
    }
    public POR(double X, double Y, double Z)
    {
        PORX = X;
        PORY = Y;
        PORZ = Z;
    }

Я тогда использую:

    public double PorDistance(POR por1, POR por2)
    {
        return Math.Round(Math.Sqrt( Math.Pow((por1.X - por2.X),2) + Math.Pow((por1.Y - por2.Y),2) + Math.Pow((por1.Z - por2.Z),2)),2);
    }

чтобы вернуть расстояние между этими двумя точками, мне нужно что-то вроде

public POR IntersectPOR (POR por1, POR por2, double distance)
{

}

где расстояние - расстояние, пройденное от por1 к por2.

Ответы [ 3 ]

5 голосов
/ 26 мая 2009

Это можно сделать с небольшой помощью векторов.

Допустим, ваша начальная точка называется P, а другая точка - Q, а расстояние - d. Вы хотите найти точку на линии PQ на расстоянии d от P к Q.

  1. Сначала вам нужно найти направление движения. Это делается путем нахождения Q - P

    v = Point(Q.x - P.x, Q.y - P.y, Q.z - P.z)
    
  2. Теперь вам нужно найти единичный вектор в этом направлении, поэтому

    scale = sqrt(v.x*v.x + v.y*v.y + v.z*v.z)
    unit = Point(v.x/scale, v.y/scale, v.z/scale)
    
  3. Теперь вам нужно найти вектор, представляющий пройденное расстояние:

    t = Point(unit.x*d, unit.y*d, unit.z*d)
    
  4. Чтобы найти конечную позицию, добавьте свой пройденный вектор к начальной точке:

    final = Point(P.x + t.x, P.y + t.y, P.z + t.z)
    
1 голос
/ 26 мая 2009

Нет реального кода, потому что я думаю, что это больше концептуальный вопрос. Это может быть не самым эффективным, но когда я делаю это, я просто применяю соотношение между общим расстоянием и сегментом к координатным дельтам. Например, если у меня есть точки в 0,0,0 и 1,2,3, общее трехмерное расстояние составляет 3,74, если я хочу разместить точку 1 на единицу от первой точки, отношение равно 1 / 3,74, поэтому новая координата будет .2673 от общего расстояния от первой точки до второй или .267, .534, .802

1 голос
/ 26 мая 2009

Похоже, вы хотите что-то похожее на:

public class Point
{
     public double x, y, z;

     // ctors, Add(), Subtract() omitted

     public Point Normalize()
     {
         double m = Magnitude;
         if (m != 0.0) return ScaleTo(1.0/m);
         return new Point();
     }

     public double Magnitude
     {
         get { return Math.Sqrt(x * x + y * y + z * z); }
     }

     public Point ScaleTo(double s)
     {
         return new Point(x * s, y * s, z * s);
     }
}

public Point PointOnLine(Point from, Point to, double dist)
{
    return from.Add(to.Subtract(from).Normalize().ScaleTo(dist));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...