Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.03.2016, 10:44   #1
Longplay
Новичок
Джуниор
 
Регистрация: 31.03.2016
Сообщений: 2
По умолчанию Графика. Вывод шестигранников на экран

Помогите написать программу на (С++, С#) вывода графического изображения в виде сот с заданными параметрами N, X и Y,

Где N = количество сот, произвольно, задается при запуске программы
X = сторона соты в пикселях, произвольно, задается при запуске программы
Y = color стороны соты

Вывод изображения: циклично до на нажатия клавиши "Esc"
Важно: Запрос параметров Х, Y для каждой выводимой стороны шестигранника. (по умолчанию X, Y = заданным в начале цикла)

Картинка должна выглядеть так:




Подскажите с чего начать? С графикой не умею работать вообще.

Последний раз редактировалось Longplay; 31.03.2016 в 10:47.
Longplay вне форума Ответить с цитированием
Старый 01.04.2016, 23:05   #2
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Цитата:
Помогите написать программу на (С++, С#)
Цитата:
Подскажите с чего начать? С графикой не умею работать вообще.
Начать нужно с того, что нужно посмотреть, как рисуется одна линия. Один из самых простых вариантов - это рисовать линии на C# WPF:

Код:
using System.Windows;
using System.Windows.Shapes;

namespace Hexagons
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // First Line
            Line line1 = new Line();
            line1.Stroke = System.Windows.Media.Brushes.Black;
            line1.Fill = System.Windows.Media.Brushes.Black;
            line1.X1 = 10.0;
            line1.Y1 = 10.0;
            line1.X2 = 50.0;
            line1.Y2 = 50.0;
            MainGrid.Children.Add(line1);
        }
    }
}
8Observer8 вне форума Ответить с цитированием
Старый 02.04.2016, 02:49   #3
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Вот здесь: http://www.redblobgames.com/grids/hexagons/
есть всё что нужно и даже больше.
Даже реализация всего этого на нескольких языках.
Croessmah вне форума Ответить с цитированием
Старый 02.04.2016, 13:59   #4
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

В приведённой выше статье в самом начале есть функция, которая возвращает координаты вершины шестиугольника:

Код:
function hex_corner(center, size, i):
    var angle_deg = 60 * i   + 30
    var angle_rad = PI / 180 * angle_deg
    return Point(center.x + size * cos(angle_rad),
                 center.y + size * sin(angle_rad))
Я её перевёл в C#:

Код:
        Point HexCorner(Point center, int size, int i)
        {
            var angleDeg = 60 * i + 30;
            var angleRad = Math.PI / 180 * angleDeg;
            return new Point(center.X + size * Math.Cos(angleRad),
                center.Y + size * Math.Sin(angleRad));
        }
Написал программу, которая рисует один шестиугольник:



Код:
using System;
using System.Windows;
using System.Windows.Shapes;

namespace Hexagons
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Point center = new Point(250, 150);
            int size = 100;

            DrawHexagon(center, size);
        }

        void DrawHexagon(Point center, int size)
        {
            Point startPoint = HexCorner(center, size, 0);

            Point p1 = startPoint;
            for (int i = 1; i <= 5; i++)
            {
                Point p2 = HexCorner(center, size, i);
                DrawLine(p1, p2);
                p1 = p2;
            }
            DrawLine(p1, startPoint);
        }

        Point HexCorner(Point center, int size, int i)
        {
            var angleDeg = 60 * i + 30;
            var angleRad = Math.PI / 180 * angleDeg;
            return new Point(center.X + size * Math.Cos(angleRad),
                center.Y + size * Math.Sin(angleRad));
        }

        void DrawLine(Point p1, Point p2)
        {
            Line line = new Line();
            line.Stroke = System.Windows.Media.Brushes.Black;
            line.Fill = System.Windows.Media.Brushes.Black;
            line.X1 = p1.X;
            line.Y1 = p1.Y;
            line.X2 = p2.X;
            line.Y2 = p2.Y;
            MainGrid.Children.Add(line);
        }
    }
}
8Observer8 вне форума Ответить с цитированием
Старый 02.04.2016, 14:09   #5
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
В приведённой выше статье в самом начале есть функция, которая возвращает координаты вершины шестиугольника
А я сделал таблицу косинусов и синусов с шагом в 30 градусов, чтобы не считать каждый раз.
Получается
Код:
return Point
   (
      center.X + size * cos_30_table[index],
      center.Y + size * sin_30_table[index]
   );
Если size будет параметром шаблона, то вообще можно на этапе компиляции вычислить все координаты сразу и брать их из таблицы.
Но это я так, рассуждения вслух.
Как раз потихоньку занимаюсь проектом где нужны гексагоны.

Последний раз редактировалось Croessmah; 02.04.2016 в 14:18. Причина: чутка напутал
Croessmah вне форума Ответить с цитированием
Старый 02.04.2016, 23:56   #6
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Да, действительно лучше таблицу делать

Такие значения будут:

Цитата:
Cos(30) = 0.866025403784439, Sin(30) = 0.5

Cos(90) = 0, Sin(90) = 1

Cos(150) = -0.866025403784439, Sin(150) = 0.5

Cos(210) = -0.866025403784439, Sin(210) = -0.5

Cos(270) = 0, Sin(270) = -1

Cos(330) = 0.866025403784438, Sin(330) = -0.5,
В C# задал таблицы через коллекции Dictionary:

Код:
    public partial class MainWindow : Window
    {
        Dictionary<int, double> cosTable = new Dictionary<int, double> {
            { 30, 0.866025403784439 },
            { 90, 0.0 },
            {150, -0.866025403784439},
            {210, -0.866025403784439},
            {270, 0.0},
            {330, 0.866025403784438}};

        Dictionary<int, double> sinTable = new Dictionary<int, double> {
            { 30, 0.5 },
            { 90, 1.0 },
            {150, 0.5},
            {210, -0.5},
            {270, -1.0},
            {330, -0.5}};

        // ...

    }
Метод, который расчитывает координату вершины, выглядит теперь так:

Код:
        Point HexCorner(Point center, int size, int i)
        {
            var angleDeg = 60 * i + 30;

            return new Point(center.X + size * cosTable[angleDeg],
                center.Y + size * sinTable[angleDeg]);
        }

Последний раз редактировалось 8Observer8; 03.04.2016 в 00:01.
8Observer8 вне форума Ответить с цитированием
Старый 06.04.2016, 11:27   #7
Longplay
Новичок
Джуниор
 
Регистрация: 31.03.2016
Сообщений: 2
По умолчанию

Спасибо огромное!

Буду разбираться.
Longplay вне форума Ответить с цитированием
Старый 06.04.2016, 12:37   #8
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Я добавил метод, который рисует заданное количество гексагонов в ширину и высоту, вызывая метод, который рисует один гексагон

Вывод программы:


Весь код:

Код:
using System;
using System.Windows;
using System.Windows.Shapes;
using System.Collections;
using System.Collections.Generic;

// http://www.programmersforum.ru/showthread.php?t=291279

namespace Hexagons
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Dictionary<int, double> cosTable =
            new Dictionary<int, double> {
            { 30, 0.866025403784439 },
            { 90, 0.0 },
            {150, -0.866025403784439},
            {210, -0.866025403784439},
            {270, 0.0},
            {330, 0.866025403784438}};

        Dictionary<int, double> sinTable =
            new Dictionary<int, double> {
            { 30, 0.5 },
            { 90, 1.0 },
            {150, 0.5},
            {210, -0.5},
            {270, -1.0},
            {330, -0.5}};

        public MainWindow()
        {
            InitializeComponent();

            Point center = new Point(50, 50);
            int size = 30;

            DrawHexagonPlane(center, size, 5, 7);
        }

        void DrawHexagonPlane(Point center, int size, int amountInWidth, int amountInHeight)
        {
            Point c = center;
            double distToRight = size * cosTable[30];
            double distToBottom = size * sinTable[30] + size;
            for (int row = 0; row < amountInHeight; row++)
            {
                for (int col = 0; col < amountInWidth; col++)
                {
                    if (row % 2 == 0)
                    {
                        DrawHexagon(new Point(c.X + col * 2 * distToRight, c.Y + row * distToBottom), size);
                    }
                    else
                    {
                        DrawHexagon(new Point(c.X + col * 2 * distToRight + distToRight, c.Y + row * distToBottom), size);
                    }
                }
            }
        }

        void DrawHexagon(Point center, int size)
        {
            Point startPoint = HexCorner(center, size, 0);

            Point p1 = startPoint;
            for (int i = 1; i <= 5; i++)
            {
                Point p2 = HexCorner(center, size, i);
                DrawLine(p1, p2);
                p1 = p2;
            }
            DrawLine(p1, startPoint);
        }

        Point HexCorner(Point center, int size, int i)
        {
            var angleDeg = 60 * i + 30;
            //var angleRad = Math.PI / 180 * angleDeg;

            return new Point(center.X + size * cosTable[angleDeg],
                center.Y + size * sinTable[angleDeg]);
        }

        void DrawLine(Point p1, Point p2)
        {
            Line line = new Line();
            line.Stroke = System.Windows.Media.Brushes.Black;
            line.Fill = System.Windows.Media.Brushes.Black;
            line.X1 = p1.X;
            line.Y1 = p1.Y;
            line.X2 = p2.X;
            line.Y2 = p2.Y;
            MainGrid.Children.Add(line);
        }
    }
}
Код:
<Window x:Class="Hexagons.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Hexagons" Height="400" Width="350">
    <Grid Name="MainGrid"/>
</Window>
8Observer8 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C++ графика. Вывод на экран форматированного текста из файла. Freedo Помощь студентам 0 17.02.2013 15:51
Выведение графика на экран (Си) 77Jan77 Помощь студентам 3 01.10.2012 15:30
вывод на экран Nikolai_90 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 11 02.05.2012 09:25
не выводится графика на экран Petruha-nsk Общие вопросы C/C++ 3 09.09.2009 17:58
Вывод на экран Rifler Паскаль, Turbo Pascal, PascalABC.NET 10 18.07.2008 18:30