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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> WPF векторное поле 
:(
    Опции темы
Greenberet
Дата 30.3.2011, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Добрый день.

Делаю небольшой проект по моделированию. Необходимо отобразить в canvas векторное поле.
Какой лучший способ это сделать? Может уже есть готовые реализации?

Заранее благодарен за помощь.

Best regards,
GreenBeret.
PM MAIL   Вверх
-Mikle-
Дата 31.3.2011, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

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



Добрый день.

В каком виде отобразить?


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Greenberet
Дата 31.3.2011, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



http://en.wikipedia.org/wiki/Vector_field, справа есть рисунок, что то похожее на это.
PM MAIL   Вверх
SergeyLoginov
Дата 1.4.2011, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 28.9.2009
Где: Иваново

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



Ну... Canvas вроде как идеально для этого подходит. Первое, что напрашивается, это унаследоваться от Canvas, добавить наследнику свойство-список векторов и синхронизировать с этим списком свойство Children, содержащее соответствующие векторам визуальные элементы.
Вариантов как это реализовать можно придумать массу, но смысл примерно такой (набросок):
Код

public VectorField()
        {
            Vectors.CollectionChanged += new NotifyCollectionChangedEventHandler(Vectors_CollectionChanged);
        }

        void Vectors_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Reset)
            {
                Children.Clear();
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {                
                foreach (Arrow v in e.OldItems)
                {
                    Children.Remove(v.Visual);
                }
            }
            else if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (Arrow v in e.NewItems)
                {
                    Children.Add(v.Visual);
                }
            }            
        }
        ObservableCollection<Arrow> vectors = new ObservableCollection<Arrow>();
        /// <summary>
        /// Векторы для отрисовки
        /// </summary>
        public ObservableCollection<Arrow> Vectors
        {
            get { return vectors; }
        }
    }

    public class Arrow
    {
        public Arrow(Point start, Vector vector)
        {
            Start = start;
            Vector = vector;
        }
        
        public Point Start {get; private set; }
        public Vector Vector { get; private set; }

        private UIElement visual = null;
        public UIElement Visual
        {
            get
            {
                if (visual == null)
                {
                    Path path = new Path();
                    path.Stroke = Brushes.Blue;
                    path.StrokeThickness = 1;
                    PathGeometry g = new PathGeometry();
                    Point endPoint = new Point(Vector.X, Vector.Y);
                    g.AddGeometry(new LineGeometry(new Point(), endPoint));
                    Point p = new Point(Vector.X * 0.7, Vector.Y * 0.7);
                    LineGeometry l1 = new LineGeometry(endPoint, p);
                    l1.Transform = new RotateTransform(30, endPoint.X, endPoint.Y);
                    LineGeometry l2 = new LineGeometry(endPoint, p);
                    l2.Transform = new RotateTransform(-30, endPoint.X, endPoint.Y);
                    g.AddGeometry(l1);
                    g.AddGeometry(l2);
                    path.Data = g;
                    visual = path;
                    Canvas.SetLeft(visual, Start.X);
                    Canvas.SetTop(visual, Start.Y);
                }
                return visual;
            }
        }
    }


Визуальное представление вектора задано в коде не потому что так надо, а просто, чтобы не заморачиваться. Если бы я реализовывал это дело для дальнейшего использования, то задал бы свойству Visual тип Control и определял бы шаблон этого контрола в xaml.
А если поле векторов может быть довольно большим (требующим скролирования) и содержащим большое количество векторов, то имеет смысл воспользоваться виртуализацией (см VirtualCanvas).

Это сообщение отредактировал(а) SergeyLoginov - 1.4.2011, 10:18
PM MAIL   Вверх
Greenberet
Дата 2.4.2011, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо, очень хорошее решение. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




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


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

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