Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 04.04.2020
Сообщений: 6

Нужно нарисовать точку на прямой

20.06.2021, 09:01. Показов 1593. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте дорогие форумчане, долгое время не могу решить такую вот задачку. Есть векторный редактор и список list со всеми точками, которые потом последовательно соединяются линией. Допустим у нас имеется отрезок и мы знаем две его крайние точки, нам нужно навести указатель мыши на этот отрезок и поставить точку между двумя точками отрезка, прямо на отрезок. Нарисовал примерную схему: нужно между A и B кликнуть и точку переместить относительно места клика C прямо на прямую в точку D. Пытался просто искать ближайшее расстояние до одной, нескольких прямых, сравнивать их, но это работает криво т.е. в любом случае если несколько прямых будут близко то такая система посыпется. Пытался сделать через уравнение прямой, но разобраться в его интеграции так и не вышло.
Может подскажите в какую сторону стоит посмотреть или возможно уже есть какие-то примеры?

https://sun9-21.userapi.com/im... type=album

Как получилось сделать через поиск одной ближайшей точки(просто ставит точку в место ближайшей в списке)
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
                    if (list.Count > 0)
                    {
                        if (!list.EqualPoints(mousePos, 10))//Проверка наличия точек в 10 пикселях от мыши
                        {
                            list.InstanceItem(list.GetNearPoint(mousePos), mousePos); //Ставим точку в место
                        }                                                             //ближайшей
                    }
                    else list.Add(mousePos); //Если в списке нет элементов мы создаем новый
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.06.2021, 09:01
Ответы с готовыми решениями:

Составить каноническое уравнение прямой, проходящей через точку М1 и точку М2 пересечения прямой L и плоскости
M1(1;-3;4) L: (x+1)/2=(y-2)/-1=(z+2)/2 - каноническое уравнение прямой П: x-2y-2z+1=0 - уравнение плоскости

В какую точку на прямой нужно поместить другой точечный заряд?
Два равных положительных точечных заряда находятся на расстоянии l = 10,0 см друг от друга. В какую точку на прямой перпендикулярной линии,...

Составить уравнение прямой линии, проходящей через точку и параллельной прямой
Составить уравнение прямой линии, проходящей через точку A(-4, 3, 3) и параллельной {l}:\begin{cases} & \text{x-2y+z-4}=0 \\ ...

2
 Аватар для samana
2639 / 1567 / 853
Регистрация: 23.02.2019
Сообщений: 3,876
20.06.2021, 13:55
Лучший ответ Сообщение было отмечено Hibiky как решение

Решение

Цитата Сообщение от Hibiky Посмотреть сообщение
Пытался просто искать ближайшее расстояние до одной, нескольких прямых, сравнивать их, но это работает криво т.е. в любом случае если несколько прямых будут близко то такая система посыпется.
Конечно, если прямые очень близко друг к другу и к обеим одинаковое расстояние до точки, то здесь уже нет выхода и придётся выбирать одно из них.

Код ниже просто как подсказка, возможно что-то пригодится. Он для консольного приложения, но это не важно в данный момент.

Здесь левой кнопкой мыши ставятся точки. Между точками автоматически рисуются линии (рёбра). А так же автоматически по рёбрам "бегает" красная точка, которая является самой ближней к курсору точкой на любом из рёбер.
А правой кнопкой мыши - создаётся промежуточная точка на ребре в ближайшем месте к курсору (там где красная точка).

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Numerics;
using System.Windows.Forms;
 
namespace CyberForum
{
    class Program
    {
        [STAThread]
        static void Main()
        {
            Application.Run(new Form2());
        }
 
    }
 
 
    internal class Form2 : Form
    {
        // список всех вершин
        private List<Vector2> _vertices;
 
        // временное хранение ближайшей точки на ребре
        private Vector2 _tempMiddlePoint;
        // временный индекс той вершины, после которой можно вставить промежуточную ближайшую точку
        private int _index;
 
 
        // просто данные для размеров при отрисовке вершин и линий
        private int _vertSize = 6;
        private int _vertSizeHalf = 3;
 
        private int _lineWidth = 3;
        public Form2()
        {
            DoubleBuffered = true;
 
            _vertices = new List<Vector2>();
 
            MouseDown += Form2_MouseDown;
            MouseMove += Form2_MouseMove;
            Paint += Form2_Paint;
        }
 
 
        // при нажатии мыши
        private void Form2_MouseDown(object sender, MouseEventArgs e)
        {
            // если левая кнопка мыши, то добавляем новую точку в цепочку
            if (e.Button == MouseButtons.Left)
                _vertices.Add(new Vector2(e.Location.X, e.Location.Y));
 
 
            // если правая кнопка, то добавляем вершину на ближайшее ребро (красная точка)
            if (e.Button == MouseButtons.Right)
            {
                if (_vertices.Count > 1)
                {
                    _vertices.Insert(_index, _tempMiddlePoint);
                }
            }
        }
 
 
        // при движении мыши рисуем черновую точку красным цветом на ближайшем ребре
        private void Form2_MouseMove(object sender, MouseEventArgs e)
        {
            if (_vertices.Count > 1)
            {
                // получили позицию курсора в виде вектора
                Point mousePoint = PointToClient(Cursor.Position);
                Vector2 mouseVec = new Vector2(mousePoint.X, mousePoint.Y);
 
                // перебираем все рёбра и ищем ближайшую к курсору точку на ребре
                float minDist = float.MaxValue;
 
                for (int i = 0; i < _vertices.Count - 1; i++)
                {
                    var v2 = _vertices[i];
                    var v1 = _vertices[i + 1];
 
                    Vector2 closest = FindNearestPointOnLine(v1, v2, mouseVec);
 
                    float dist = Vector2.DistanceSquared(mouseVec, closest);
                    if (dist < minDist)
                    {
                        minDist = dist;
                        _tempMiddlePoint = closest;
                        _index = i + 1;
                    }
                }
            }
 
            // обновляем форму, чтобы она перерисовалась
            Refresh();
        }
 
 
        // Перерисовка графики на форме
        private void Form2_Paint(object sender, PaintEventArgs e)
        {
            // всегда рисуем текущие вершины
            foreach (Vector2 v in _vertices)
            {
                e.Graphics.FillRectangle(Brushes.Black, v.X - _vertSizeHalf, v.Y - _vertSizeHalf, _vertSize, _vertSize);
            }
 
 
            // если вершин больше чем 1, то рисуем..
            if (_vertices.Count > 1)
            {
                // рёбра, соединяющие вершины..
                for (int i = 0; i < _vertices.Count - 1; i++)
                {
                    e.Graphics.DrawLine(Pens.Blue, _vertices[i].ToPointF(), _vertices[i + 1].ToPointF());
                }
 
                // и черновую точку на ребре, которая ближе всего к курсору
                e.Graphics.FillRectangle(Brushes.Red,
                                        _tempMiddlePoint.X - _vertSizeHalf,
                                        _tempMiddlePoint.Y - _vertSizeHalf,
                                        _vertSize,
                                        _vertSize);
            }
        }
 
        // Метод возвращает ближайшую точку на линии
        private Vector2 FindNearestPointOnLine(Vector2 origin, Vector2 end, Vector2 point)
        {
            Vector2 heading = Vector2.Normalize(end - origin);
            float magnitude = Vector2.Distance(end, origin);
 
            Vector2 lhs = point - origin;
 
            float dotP = Vector2.Dot(lhs, heading);
            if (dotP < 0) dotP = 0;
            else if (dotP > magnitude) dotP = magnitude;
 
            return origin + heading * dotP;
        }
 
    }
 
    // это вспомогательный класс-расширения, чтобы по быстрому перевести тип Point в Vector
    static class Vector2Extentions
    {
        public static PointF ToPointF(this Vector2 v)
        {
            return new PointF(v.X, v.Y);
        }
    }
}
1
0 / 0 / 0
Регистрация: 04.04.2020
Сообщений: 6
20.06.2021, 16:53  [ТС]
Это как раз то, что мне было необходимо, спасибо огромное!)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
20.06.2021, 16:53
Помогаю со студенческими работами здесь

Составить уравнение прямой, проходящей через точку и перпендикулярной данной прямой
Необходимо составить уравнение прямой, проходящей через точку М(2,3,1) и перпендикулярную прямой (х+1)/2 = у/(-1) = (z-2)/3 ...

Найти общее уравнение прямой, проходящей через точку параллельно прямой
Пожалуйста помогите решить данные задачи. Не могу понять как их решить. 2.Найти общее уравнение прямой, проходящей через точку B...

Составить канонические уравнения прямой,проходящей через точку параллельно прямой
Составить канонические уравнения прямой, проходящей через точку (0;-1;-3) параллельно прямой х+1 = ( у + 2 ) / 2 = - z - 1 ...

Найти точку пересечения прямой и плоскости и угол между прямой и плоскостью
Дана прямая в пространстве и плоскость. Найти: а) точку пересечения прямой и плоскости; б) угол между прямой и плоскостью. ...

Составить уравнение прямой проходящей через одну точку и перпендикулярной к прямой:
Составить уравнение прямой проходящей через точку M(2,4) и перпендикулярной к прямой: 9x+5y-12=0


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru