Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Задача. Рисуем стрелку. =)) 
V
    Опции темы
Elfet
Дата 24.11.2006, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Есть прямая. Нужно к ней нарисовать стрелку. Я убил целый час ( о ужас! главное что бы наш профессор по алгебре не узнал ) , но вышло се совсем то чего я ожидал)))
Вот что я умудрил:
Код

            int radius = 5;
            int arrowWidth = 7;
            int arrowHeight = 2;

                    int x1 = i.p1.x;
                    int y1 = i.p1.y;
                    int x2 = i.p2.x;
                    int y2 = i.p2.y;
                    g.DrawLine(ribPen, x1, y1, x2, y2);
                    // Стрелка
                    {
                        double r = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
                        double lambdaC = radius / (r - radius);
                        double Cx = (x1 + lambdaC * x2) / (1 + lambdaC);
                        double Cy = (y1 + lambdaC * y2) / (1 + lambdaC);
                        double lambdaB = (radius + arrowWidth) / (r - (radius + arrowWidth));
                        double Bx = (x1 + lambdaB * x2) / (1 + lambdaB);
                        double By = (y1 + lambdaB * y2) / (1 + lambdaB);
                        double nath = (y2 - y1) / (x2 - x1);
                        double cph = Math.Atan(nath);
                        double betta = Math.Atan(arrowWidth / arrowHeight);
                        double tgAlpha1 = Math.Tan(cph - betta);
                        double tgAlpha2 = Math.Tan(cph + betta);
                        double F1y = (Cy / tgAlpha1 - Cx + Bx + nath * By) / (1 / tgAlpha1 + nath);
                        double F1x = (F1y - Cy) / tgAlpha1 + Cx;
                        double F2y = (Cy / tgAlpha2 - Cx + Bx + nath * By) / (1 / tgAlpha2 + nath);
                        double F2x = (F2y - Cy) / tgAlpha2 + Cx;
                        g.DrawLine(ribPen, (int)Cx, (int)Cy, (int)F1x, (int)F1y);
                        g.DrawLine(ribPen, (int)Cx, (int)Cy, (int)F2x, (int)F2y);
                    }

 smile

Добавлено @ 17:43 
user posted image
user posted image
user posted image

Добавлено @ 17:43 
Полная шызуха.


--------------------
PM MAIL WWW Skype   Вверх
Void
Дата 24.11.2006, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 25
Всего: 173



Код
using System.Drawing;
using System.Drawing.Drawing2D;

Pen pen = new Pen(Color.Black, 2.0F);
pen.CustomEndCap = new AdjustableArrowCap(4.0F, 8.0F);
Graphics g = ...;
g.DrawLine(pen, 10, 50, 100, 50);

Вот как-то так smile


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
mr.DUDA
Дата 24.11.2006, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Задачка интересная, и решается двумя путями:

1. Предложенный тобой способ (не проверял)
2. Если знать о существовании матриц и трансформаций, то всё получается на порядок проще: мы смещаем и поворачиваем систему координат к началу стрелки, рисуем стрелку горизонтально из точки (0;0), поворачиваем координаты обратно. Накатал простой пример с формой, где стрелка рисуется из центра формы к курсору мыши:

Код
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace WindowsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        ///<summary>
        /// Рисует стрелку на графиксе
        ///</summary>
        void DrawArrow(Graphics gr, Point start, Point end)
        {
            float x1 = start.X, y1 = start.Y, x2 = end.X, y2 = end.Y;

            // вычисляем угол, под которым стрелка повёрнута против часовой
            // вычисляем длину стрелки
            float angle = (float)Math.Atan2(y2 - y1, x2 - x1);
            angle = angle * 180f / (float)Math.PI; // переводим в градусы
            float len = (float)Math.Sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));

            // сохраняем старое состояние Graphics, чтобы потом его восстановить
            GraphicsState state = gr.Save();

            // трансформация: сдвиг к точке start и поворот на угол
            gr.TranslateTransform(x1, y1);
            gr.RotateTransform(angle);

            using (Pen pen = new Pen(Color.Red, 2f))
            {
                int arrowLength = 10; // длина окончания стрелки
                int arrowWidth = 5; // ширина окончания стрелки
               
                // рисуем стрелку в горизонтальном положении
                gr.DrawLine(pen, 0, 0, len, 0);
                gr.DrawLine(pen, len, 0, len - arrowLength, arrowWidth);
                gr.DrawLine(pen, len, 0, len - arrowLength, -arrowWidth);
            }

            // восстанавливаем старое состояние Graphics (убираем наши трансформации)\
            gr.Restore(state);
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            DrawArrow(e.Graphics, 
                new Point(this.Width / 2, this.Height / 2), // начало - центр формы
                this.PointToClient(Cursor.Position)); // конец - курсор мыши в координатах формы
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            this.Refresh();
        }
    }
}


З.Ы. чтоб не мерцало, у формы ставим DoubleBuffered = true.

Добавлено @ 18:03 
Цитата(Void @  24.11.2006,  16:44 Найти цитируемый пост)
Вот как-то так

3. Способ Void-а. Совсем для ленивых smile

Добавлено @ 18:09 
Видать, ваш препод хочет знания тригонометрии проверить... значит только руками, и учить матчасть...  smile 


--------------------
user posted image
PM MAIL WWW   Вверх
Elfet
Дата 24.11.2006, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



smile Ок! Спасибо! smile нее. эт я для себя в программе сделать хотел smile просто подобные задачки препод двавал нам в огромных количествах. Теперь забылось всё немного smile

Добавлено @ 18:29 
Использовал AdjustableArrowCap так как красиво и я думаю быстрее?  smile 


--------------------
PM MAIL WWW Skype   Вверх
mr.DUDA
Дата 24.11.2006, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



AdjustableArrowCap хорош, если не нужно делать таких вещей как например стрелка нестандартной формы  smile 


--------------------
user posted image
PM MAIL WWW   Вверх
mr.DUDA
Дата 5.12.2006, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Хы, ещё красивее можно сделать если добавить сглаживание:

Код
            // сохраняем старое состояние Graphics, чтобы потом его восстановить
            GraphicsState state = gr.Save();
            gr.SmoothingMode = SmoothingMode.HighQuality;

// ...



--------------------
user posted image
PM MAIL WWW   Вверх
Elfet
Дата 16.12.2006, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Вот что получилось: Graph Simple smile


--------------------
PM MAIL WWW Skype   Вверх
scalosale
Дата 8.2.2023, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 8.2.2023

Репутация: нет
Всего: нет




Модератор: Сообщение скрыто.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1452 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.