Сообщество программистов Autodesk в СНГ

ADN Club => Revit API => Тема начата: shss от 02-10-2015, 12:39:33

Название: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 12:39:33
Добрый день!
Пытаюсь подвинуть точку(midpoint) относительно прямой, заданной двумя точками(p1/p2), на определенное расстояние, делаю вот так:
Код - C# [Выбрать]
  1. Line columnFaceLine = Line.CreateUnbound(p1, p2); //создание прямой
  2. double projP3 = (columnFaceLine.Project(p3).XYZPoint - p3).GetLength(); //расстояние от точки до проекции точки на прямую - минимальное расстояние
  3. midpoint = (p1 + p2) / 2;
  4. XYZ lineDirection = columnFaceLine.Direction; //направление прямой
  5. XYZ normal = midpoint.CrossProduct(lineDirection).Normalize(); // определение нормального вектора к прямой относительно точки
  6. XYZ transform = normal.Multiply(projP3  / 2);
  7. midpoint = transform;
  8.  

Но проекция точки p3 - какая-то не правильная и точка midpoint перемещается черт знает куда.
 
Название: Re: Перемещение точки относительно прямой
Отправлено: Александр Игнатович от 02-10-2015, 12:59:20
На вскидку:
Код - C# [Выбрать]
  1. midpoint = p1 + (p2 - p1) / 2

а дальше, наверное,
Код - C# [Выбрать]
  1. midpoint + projP3 * lineDirection.Normalize()
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 13:14:20
midpoint = p1 + (p2 - p1) / 2
это же тоже самое, что и (p1 + p2) / 2, ну если скобки раскрыть:)
midpoint + projP3 * lineDirection
а вот этого чтото я не совесем понял.
Может я не свосем ясно выразился мне надо переместить точку перпендикулярно прямой на расстояние
Название: Re: Перемещение точки относительно прямой
Отправлено: Александр Игнатович от 02-10-2015, 13:18:52
Ну если раскрыть скобки будет
Код - C# [Выбрать]
  1. (p2 - p1) / 2

Да, не lineDirection, ошибся.

Код - C# [Выбрать]
  1. midpoint = (p2 - p1) / 2 + projP3 * normal

projP3 - это же как раз будет расстояние, на которое сместить нужно?
Название: Re: Перемещение точки относительно прямой
Отправлено: Александр Игнатович от 02-10-2015, 13:24:21
А, вру, действительно
Код - C# [Выбрать]
  1. (p1 + p2) / 2
. Ну тогда к этому нужно прибавить вектор normal-и умноженный на заданную длину
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 13:45:41
Пытаюсь подвинуть точку(midpoint) относительно прямой, заданной двумя точками(p1/p2), на определенное расстояние
Но проекция точки p3
Пародон, а причем здесь точка p3? в коде эта точка используется только для получения минимального расстояния projP3, которое в свою очередь нигде потом не используется
.
double projP3 = (columnFaceLine.Project(p3).XYZPoint - p3).GetLength(); //расстояние от точки до проекции точки на прямую - минимальное расстояние
можно чуть проще кстати:
Код - C# [Выбрать]
  1. double projP3 = columnFaceLine.Project(p3).Distance
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 13:52:53
А вообще вроде так точка перемещается:
Код - C# [Выбрать]
  1. Line line = ...;
  2. // направление = вектор
  3. var direction = line.Direction;
  4.  
  5. // нормализованный вектор
  6. var n = direction.Normalize();
  7.  
  8. // точка которую надо переместить
  9. var p = ...;
  10.  
  11. // расстояние, на которое надо переместить
  12. var d = 0.2; // в футах
  13.  
  14. // конечные координаты точки
  15. var res = p.Add(n.Multiply(d));
  16.  
Название: Re: Перемещение точки относительно прямой
Отправлено: Александр Игнатович от 02-10-2015, 14:02:27
Виктор Чекалин,  так точка переместится в направлении line.Direction, я так понимаю, задача в том, чтобы сместиться относительно данной линии.

А если я все-таки ошибаюсь, можно же еще проще

Код - C# [Выбрать]
  1. var d = 0.2;
  2.  
  3. var res = line.GetEndPoint(0) + (line.Length / 2 + d) * line.Direction.Normalize() // можно и без Normalize(), line.Direction будет и так единичным вектором
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 14:09:51
Саш, а в твоем понимании что значит относительно прямой? Это вдоль или перпендикулярно? Или еще как?

А если я все-таки ошибаюсь, можно же еще проще
Дык я можно сказать тож самое и написал, только подробно по шагам:)

В общем формула есть. Осталось только определиться, что и вдоль чего передвигать.
 
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 14:15:54
Вообще ТС либо привел не полный код как минимум.
1) неизвестно что за p3
2) зачем нужно projP3
3) откуда взялась переменная t (строка 6)
4) строка 7 - midpoint = transform; что за transform и зачем это значение присваивать midpoint, если это середина линии?
shss, уточните пожалуйста все же какую точку и в каком направлении нужно переместить.
Название: Re: Перемещение точки относительно прямой
Отправлено: Александр Игнатович от 02-10-2015, 14:20:48
Да, нужны комментарии от shss

Про движение точки меня, возможно, сбил с толку вызов CrossProduct в исходном сообщение

https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Cross_product_parallelogram.svg/2000px-Cross_product_parallelogram.svg.png
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 15:03:27
Да извиняюсь, за некорректную формулировку.
p3 - это точка вне прямой, с помощью, которой я определяю расстояние до прямой, на половину которого и надо подвинуть midpoint
Код - C# [Выбрать]
  1. double projP3 = (columnFaceLine.Project(p3).XYZPoint - p3).GetLength();
- но работает очень странно.
t - это  proj3, просто ошибся
Переместить надо перпендикулярно существующей линии
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 15:10:28
Если я не ошибаюсь, то как раз:
Код - C# [Выбрать]
  1. XYZ normal = midpoint.CrossProduct(lineDirection).Normalize();
это и есть перпендикулярное направление относительно линии
а вот уже в какую сторону двигать определяет точка которая лежит или выше или ниже прямой
Код - C# [Выбрать]
  1. XYZ transform = normal.Multiply(projP3  / 2);
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 15:20:25
shss, вот так:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fcontent.screencast.com%2Fusers%2FVictorChekalin%2Ffolders%2FJing%2Fmedia%2Fe652f452-d11d-484f-a0b2-7308d635e06e%2F2015-10-02_1719.png&hash=3ac1ff5e4bba381fc52d71464d9e7ebb)
Я верно понял?
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 15:21:24
Да, Виктор, все верно
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 15:36:51
Код - C# [Выбрать]
  1. var p3 = ...; // точка вне прямой columnFaceLine
  2.  
  3. var midpoint = (p1 + p2) / 2; //точка в середине прямой columnFaceLine
  4.  
  5. var intersectionPoint = columnFaceLine.Project(p3).XYZPoint; // точка пересечения перпендикуляра от прямой columnFaceLine к точке p3
  6.  
  7. var line1 = Line.CreateBound (intersectionPoint, p3); // кратчайшее расстояние от columnFaceLine до p3;
  8.  
  9. var distance = line1.Length/2; // расстояние, на которое нужно передвинуть midpoint
  10.  
  11. var direction = line1.Direction.Normalize(); // направление, в котором нужно передвинуть midpoint. Возможно Normalize() лишнее, надо проверить.
  12.  
  13. // двигаем точку на нужное расстояние
  14. var res = midpoint.Add(direction.Multiply(d));
  15.  

Должно быть так.
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 16:02:13
да этот код работает. В случае если точка вне прямой лежит в пределах отрезка
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fstorage5.static.itmages.ru%2Fi%2F15%2F1002%2Fs_1443790897_5882010_590544b498.png&hash=6cdb016732419ab5becdc66fe574cd04) (http://itmages.ru/image/view/3054967/590544b4)
А вот в случае если точка, лежащая не на прямой (заданной координатами р1 и р2), находится не в пределах отрезка, то функция
Код - C# [Выбрать]
  1. var intersectionPoint = columnFaceLine.Project(p3).XYZPoint;
работает неверно
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fstorage6.static.itmages.ru%2Fi%2F15%2F1002%2Fs_1443790907_6092983_58cc195195.png&hash=7211867749684836cfba484d3871bab8) (http://itmages.ru/image/view/3054968/58cc1951)

Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 16:02:51
да этот код работает. В случае если точка вне прямой лежит в пределах отрезка
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fstorage5.static.itmages.ru%2Fi%2F15%2F1002%2Fs_1443790897_5882010_590544b498.png&hash=6cdb016732419ab5becdc66fe574cd04) (http://itmages.ru/image/view/3054967/590544b4)
А вот в случае если точка (р3), лежащая не на прямой (заданной координатами р1 и р2), находится не в пределах отрезка, то функция
Код - C# [Выбрать]
  1. var intersectionPoint = columnFaceLine.Project(p3).XYZPoint;
работает неверно
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fstorage6.static.itmages.ru%2Fi%2F15%2F1002%2Fs_1443790907_6092983_58cc195195.png&hash=7211867749684836cfba484d3871bab8) (http://itmages.ru/image/view/3054968/58cc1951)

Меня это и насторожило это поведение проекции
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 17:06:37
Меня это и насторожило это поведение проекции
Не, метод правильно сработал. метод ищет минимальное расстояние от точки до кривой. А если точка находится в границах кривой, то минимальное расстояние - это перпендикуляр от точки к прямой, либо от точки к касательной кривой.

Но в этом случае мой способ действительно не сработает для этой задачи. Надо покопаться, есть ли готовые методы или надо свой написать
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 17:10:39
А если точка находится не в границах отрезка, то что тогда метод возвращает?
Я предполагал, что нужно делать прямую Unbound и будет тоже самое проекция на бесконечную прямую:
Код - C# [Выбрать]
  1. Line columnFaceLine = Line.CreateUnbound(p1, p2);
  2. var intersectionPoint = columnFaceLine.Project(p3).XYZPoint;
  3.  
а получается
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fstorage5.static.itmages.ru%2Fi%2F15%2F1002%2Fs_1443794696_1346390_20fc1ed69e.png&hash=247e9d0631687fccb905933a3a303f1b) (http://itmages.ru/image/view/3055222/20fc1ed6)
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 17:13:49
Видимо, придется через синус все считать.
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 17:15:59
А если точка находится не в границах отрезка, то что тогда метод возвращает?
Кратчайшее расстояние от точки до прямой, в этом случае будет отрезком от точки до одного из концов прямой
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fcontent.screencast.com%2Fusers%2FVictorChekalin%2Ffolders%2FJing%2Fmedia%2F6f027dbf-01c9-442e-92e0-9e188a266ed4%2F2015-10-02_1914.png&hash=c7be4a86aba9e9466f9b0d2d08677882)
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 17:18:53
Кратчайшее расстояние от точки до прямой, в этом случае будет отрезком от точки до одного из концов прямой
это в случае если прямая создана при помощи CreateBound
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 17:23:28
Вообще в случае с Unbound должен тоже тоже перпендикуляр построить.
Код - C# [Выбрать]
  1. Line columnFaceLine = Line.CreateUnbound(p1, p2);
думаю вот здесь построена не та линия, которую вы ожидали, поэтому и конечный результат неверный.
Это не значит что линия будет начинаться в точке p1 и проходить через p2. p2 это направление.
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 17:31:04
то есть получается Line.CreateBound(p1, p2) и Line.CreateUnbound(p1, p2) это две разных линии?
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 17:33:06
Хм кажется я нашел ответ:
Returns the unbounded line that passes through the specified point in the direction of the specified vector
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 17:35:22
Да, вот он ответ:
Line columnFaceLine = Line.CreateUnbound(p1, Line.CreateBound(p1, p2).Direction);
Название: Re: Перемещение точки относительно прямой
Отправлено: Виктор Чекалин от 02-10-2015, 17:38:31
Line columnFaceLine = Line.CreateUnbound(p1, Line.CreateBound(p1, p2).Direction);
Угу, только зачем создавать лишний объект.
Направление можно найти просто: p2-p1
Т.е.
Код - C# [Выбрать]
  1. Line columnFaceLine = Line.CreateUnbound(p1, p2-p1);
Название: Re: Перемещение точки относительно прямой
Отправлено: shss от 02-10-2015, 17:43:26
Всем огромное Спасибо за подсказки!