Как нарисовать треугольник в с
Перейти к содержимому

Как нарисовать треугольник в с

  • автор:

Нарисовать треугольник

Author24 — интернет-сервис помощи студентам

Нарисовать треугольник
День добрый! Учу по книге. Not student! Тема не раз уже поднималась, но моего варианта не.

Нарисовать треугольник
Помогите нарисовать треугольник. Я нарисовал, но надо сделать его наоборот. Он должен смотреть в.

Нарисовать треугольник
Добрый день. Помогите с кодом для отрисовки треугольника по введенным координатам (х и у) его.

Эксперт JavaЭксперт С++

8384 / 3616 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
Nikolas999, вам надо переписать так

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
int main() { int j = 0; int i = 0; int n = 0; int m = 0; int k = 0; std::cout  "Vvedite razmer vysoty treugolnika:"; std::cin >> n; std::cout  "Vvedite razmer osnovy treugolnika:"; std::cin >> m; for (i = 0; i  n, k  m; i++) { for (j = 0; j  k; j++) cout  "*"; k++; cout  "\n"; } return 0; }

но у вас проблема с алгоритмом, потому как для высоты = 5 и основы 3 нарисуется треугольник с высотой 3

Регистрация: 09.02.2011
Сообщений: 189

Добрый вечер) Не подскажите как насчет не прямоугольного треугольника?
Вот мой код на прямоугольный, может кому то и интересно будет(язык Си):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include #include void main() { int i,j,l; for(i=1;i6;i++) { for(j=1;ji;j++) { putchar('*'); } putchar('\n'); } getch(); }

Результат:
*
**
***
****
*****
Хотелось бы узнать как сделать треугольник типа ёлки)

Эксперт С++

5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448

[nameless@desktop c]$ cat main.c #include #include #define SIZE 6 int main() < size_t i, j; for(i = 1; i i; --j) putchar(' '); for(j = 1; j < 2 * i; ++j) putchar('*'); putchar('\n'); >exit(0); > [nameless@desktop c]$ ./sample * *** ***** ******* ********* *********** [nameless@desktop c]$

Регистрация: 09.02.2011
Сообщений: 189
Всё понял, огромное спасибо)
Регистрация: 05.10.2022
Сообщений: 1

P.S. Для тех, кто учится в БГТУ, первый курс, ОАиП, вариант 5. Попробуйте постирать пару строчек и чекнуть, как это работает, чтоб сделать похожие задания ;р

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#include #include void main() { setlocale(LC_CTYPE, "Russian"); using namespace std; char c, probel; probel = ' '; cout  "Введите символ: "; cin >> c; cout  setw(62)  setfill(probel)  probel; cout  setw(1)  setfill(c)  c  endl; cout  setw(60)  setfill(probel)  probel; cout  setw(5)  setfill(c)  c  endl; cout  setw(58)  setfill(probel)  probel; cout  setw(9)  setfill(c)  c  endl; cout  setw(56)  setfill(probel)  probel; cout  setw(13)  setfill(c)  c  endl; cout  setw(54)  setfill(probel)  probel; cout  setw(17)  setfill(c)  c  endl; cout  setw(52)  setfill(probel)  probel; cout  setw(21)  setfill(c)  c  endl; cout  setw(50)  setfill(probel)  probel; cout  setw(25)  setfill(c)  c  endl; }

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

нарисовать треугольник из * без if else
Доброго времени суток, в книге задание нарисовать треугольник из *, причем пользователь вводит.

Нужно Нарисовать Треугольник на C++
Дали задание по C++. Нарисовать треугольник.Дайте материалы(ссылки,книги,tutorial) с не сложными.

Нарисовать треугольник звездочками
1) Write a program that prints the screen below. Conditions: Only use one printf("*") or.

Нарисовать треугольник в консоли
#include <iostream> using namespace std; int main() < setlocale(LC_ALL, "rus"); char.

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

Нарисовать равнобедренный треугольник из символов
Нужно разобрать код Нарисовать равнобедренный треугольник из символов . Высоту выбирает.

Или воспользуйтесь поиском по форуму:

Как нарисовать треугольник в консоли?

Здравствуйте, надавно начал осваивать СИ. Вопрос такой — как «нарисовать» в консоли правильный треугольник из символов звездочки *? Я что-то пытался до этого сделать, но ничего внятного не вышло.

  • Вопрос задан более трёх лет назад
  • 4334 просмотра

8 комментариев

Простой 8 комментариев

TosterModerator

Модератор @TosterModerator

Пожалуйста, исправьте вопрос так, чтобы он описывал конкретную проблему с достаточной детализацией для определения адекватного ответа.

LevG0r @LevG0r Автор вопроса
Сергей Горностаев @sergey-gornostaev Куратор тега C

Покажите код ваших попыток и объясните, что именно значит «ничего внятного не вышло». А то сейчас вопрос выглядит как «напишите код за меня», модераторы такое удаляют.

LevG0r @LevG0r Автор вопроса

#include #include int main() < int tr_number; scanf("%d", &tr_number); for (int y = 1; yprintf("\n"); > return 0; >

Просто вывод звёздочек. Я пробовал через modf, пробовал рисовать ‘ ‘ от начала и конца строки, но ничего не вышло.

Сергей Горностаев @sergey-gornostaev Куратор тега C

LevG0r, что значит «ничего не вышло»? Вообще не скомпилировалось? Скомпилировалось, но при запуске упало с ошибкой? Отработало, но нарисовало не то, что нужно?

Раскрашиваем треугольник программным способом

Мне интересно воссоздавать работу GPU программно, поэтому я решил поделиться моим пониманием того, как можно выполнить раскраску треугольников методами простой линейной алгебры.

Я напишу обобщённый 2D-массив элементов типа uint32_t под названием colorBuffer, который может быть резервным хранилищем чего-то простого, например, выводимого в файл изображения, или буфером цвета окна SDL.

Задаём треугольник

Треугольник можно задать тремя точками, или вершинами. Каждая вершина имеет различные атрибуты; пока мы добавим каждой вершине только положение на экране.

То есть если бы мы захотели нарисовать треугольник с вершиной в нижнем левом углу, нижнем правом углу и вверху по центру, то мы бы могли задать его так:

struct Point < float x; float y; >; struct Vertex < Point position; >; // Top middle Vertex v0 = ; // Bottom right Vertex v1 = ; // Bottom left Vertex v2 = ;

Нужно добавить, что вершины задаются в порядке по часовой стрелке. Сначала верхняя в центре, потом нижняя правая и нижняя левая. В дальнейшем это будет очень важно.

Каждая вершина имеет позицию, состоящую из двух значений с плавающей запятой. Их два, потому что при работе с экраном у нас есть всего два измерения: ширина (x) и высота (y).

Точкой начала координат экрана считается верхний левый угол: значения y становятся больше при смещении вниз, а значения x — при сдвиге вправо. Поэтому нижний правый угол треугольника имеет наибольшие значения.

Функция ребёр

Итак, каждая вершина треугольника имеет положение на экране, но нам нужно знать, какие из экранных пикселей находятся внутри этого треугольника, чтобы их можно было раскрасить соответствующим образом. Мы хотим, чтобы пиксели в треугольнике были не чёрными, а пиксели за пределами треугольника — чёрными. Этим займётся за нас линейная алгебра.

Сначала мы создадим вектор из каждой вершины до следующей соседней вершины, двигаясь по часовой стрелке, вычитанием позиции одной вершины из другой. Вспомним, что Точка A — Точка B создаёт вектор, указывающий из Точки B в Точку A.

Это красные векторы, названные e10 (v1 — v0), e21 (v2 — v1) и e02 (v0 — v2).

Если мы хотим узнать, находится ли точка P внутри треугольника, то можно использовать свойство векторного произведения 2D-векторов. Для каждого ребра (e10, e21, e02) мы можем найти векторное произведение вектора этого ребра с вектором из начальной точки ребра к точке P.

Новый вектор является результатом вычитания p — v0, что создаёт вектор из v0 в p. Если мы возьмём двухмерное векторное произведение двух зелёных векторов (p-v0 и e10), то получим значение, являющееся отрицательным, положительным или нулевым.

  • Положительное: точка P находится справа от e10 (внутри треугольника)
  • Отрицательное: точка P находится слева от e10 (снаружи треугольника)
  • Нулевое: точка P находится на e10 (ни внутри, ни снаружи)

Зелёный вектор является результатом вычитания p — v1, что создаёт вектор из v1 в p.

Зелёный вектор является результатом вычитания p — v2, что создаёт вектор из v2 в p.

Двухмерное векторное произведение получается довольно просто:

A x B = A.x * B.y — A.y * B.x

Vector e10 = v1 - v0; Vector e21 = v2 - v1; Vector e02 = v0 - v2; Vector p0 = p - v0; Vector p1 = p - v1; Vector p2 = p - v2;

Тогда если мы хотим протестировать точку P относительно e10:

float result = Edge(e10, p);

Всё это означает, что если мы хотим узнать, находится ли точка внутри треугольника, можно взять векторные произведения вектора каждой точки с вектором каждого ребра. Если все они больше нуля (или равны ему), то точка находится внутри треугольника и мы можем раскрасить этот пиксель.

Мы можем задать ещё одну структуру для представления Vector и перегрузить оператор вычитания, чтобы создавать Vector из вычитания двух точек. Структуры Point и Vector имеют одинаковое содержимое (два float), но благодаря их разделению код становится более понятным.

struct Vector < float x; float y; >; Vector operator-(Point lhs, Point rhs)

Затем мы создаём функцию, сообщающую нам по позициям двух векторов (точек рёбер) и тестируемой точки векторное произведение векторов из этих точек.

float Edge(Point v0, Point v1, Point p) < // Vector from edge origin to test point Vector a = p - v0; // Vector from edge origin to edge end Vector b = v1 - v0; // 2D cross product // Zero: Point is on edge // Positive: Point is right of edge // Negative: Point is left of edge return a.x * b.y - a.y * b.x; >

Рисование треугольника

Чтобы отрендерить треугольник, мы итеративно обходим все пиксели экрана и проверяем, содержится ли их позиция внутри треугольника. Если да, то раскрашиваем пиксель белым. Если нет, то ничего не делаем.

// Top middle Vertex v0 = ; // Bottom right Vertex v1 = ; // Bottom left Vertex v2 = ; for (unsigned int y = 0; y < WINDOW_HEIGHT; ++y) < for (unsigned int x = 0; x < WINDOW_WIDTH; ++x) < Point p = ; // Clockwise float e10 = Edge(v1.position, v0.position, p); float e21 = Edge(v2.position, v1.position, p); float e02 = Edge(v0.position, v2.position, p); // Point is inside triangle if (e10 >= 0.0f && e21 >= 0.0f && e02 >= 0.0f) < colorBuffer[y][x] = 0xffffffff; >> >

Так мы получаем следующее изображение:

Затенение треугольника

Замечательно. Мы можем задавать треугольник тремя точками и заливать его сплошным цветом. Разумеется, наша конечная цель — не сплошной цвет. Было бы здорово, если бы могли связать с вершиной и другие атрибуты, кроме позиции, а затем интерполировать эти атрибуты для всего множества пикселей, составляющих треугольник.

Это можно реализовать при помощи барицентрических координат. Векторное произведение двух 2D-векторов на самом деле является площадью параллелограмма, образованного этими двумя векторами. Половина площади этого параллелограмма — это площадь меньшего треугольника, образованного двумя точками треугольника и проверяемой точкой.

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

Каждая из этих раскрашенных площадей обозначает меньший треугольник.

Если указать на каждом меньшем треугольнике его площадь, то мы увидим нечто интересное.

  • Когда точка P приближается к v0, площадь красного треугольника становится больше.
  • Когда точка P приближается к v1, больше становится площадь зелёного треугольника.
  • Когда точка P приближается к v2, больше становится площадь синего треугольника.

Если мы разделим каждый из результатов, возвращённых из функции рёбер и разделим их на общую площадь основного треугольника, то получим нормализованное значение (от 0.0 до 1.0) для каждой вершины. Это значение является весом этой вершины в проверяемой точке. Можно умножить вес каждой вершины на атрибут вершины и сложить все три взвешенных значения, чтобы получить окончательное значение.

Это можно продемонстрировать, назначив каждой вершине цвет.

Мы создадим struct для задания цвета, которая будет всего лишь четырьмя float, и добавим переменную цвета в структуру Vertex.

struct Color < float r, g, b, a; >; struct Vertex < Point position; Color color; >;

Затем мы переопределим треугольник и назначим красный цвет вершине v0, зелёный — v1, а синий — v2.

// Top middle - red Vertex v0 = < , >; // Bottom right - green Vertex v1 = < , >; // Bottom left - blue Vertex v2 = < , >;

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

float area = Edge(v2.position, v1.position, v0.position); for (unsigned int y = 0; y < WINDOW_HEIGHT; ++y) < for (unsigned int x = 0; x < WINDOW_WIDTH; ++x) < Point p = ; // Clockwise float e0 = Edge(v2.position, v1.position, p); float e1 = Edge(v0.position, v2.position, p); float e2 = Edge(v1.position, v0.position, p); // Point is inside triangle if (e0 >= 0.0f && e1 >= 0.0f && e2 >= 0.0f) < // Barycentric weights float w0 = e0 / area; float w1 = e1 / area; float w2 = e2 / area; float r = w0 * v0.color.r + w1 * v1.color.r + w2 * v2.color.r; float g = w0 * v0.color.g + w1 * v1.color.g + w2 * v2.color.g; float b = w0 * v0.color.b + w1 * v1.color.b + w2 * v2.color.b; uint8_t red = r * 255; uint8_t green = g * 255; uint8_t blue = b * 255; uint8_t alpha = 255; colorBuffer[y][x] = (red > >

Значение, возвращаемое функцией Edge, является площадью параллелограмма, образованного векторами, но нас интересует площадь треугольника, равная её половине. Однако, поскольку мы делим результаты функции Edge (e1, e2, e3) на ещё один результат функции Edge (площадь), то 1/2 сокращается, поэтому нам не нужно об этом заботиться.

Когда треугольник меньше размера всего окна/изображения, то будет неэффективно обходить весь размер окна/изображения. Логичнее будет создать ограничивающий прямоугольник этого треугольника, вычислив его минимальные и максимальные значения X и Y, а затем обойдя только эту область.

Результаты

После выполнения программы получается следующий затенённый треугольник:

Пиксели, более близкие к верхней вершине, становятся более красными, к правой вершине — более зелёными, к левой — более синими. Площади между ними являются сочетанием цветов.

Заключение

Все, кто работал с графическими API наподобие OpenGL должны увидеть сходства между написанным мной и тем, как используется OpenGL.

В OpenGL мы передаём в GPU буфер данных вершин, содержащий атрибуты каждой вершины (например, позицию, цвет, нормаль), а он затем интерполирует эти атрибуты между пикселями (фрагментами), составляющими треугольник на экране.

В статье мы выполнили похожие действия.

  • Работа с векторной графикой
  • Работа с 3D-графикой
  • Разработка игр

Нарисовать треугольник

Aspose.Diagram for .NET API позволяет разработчикам рисовать треугольник на странице. В приведенном ниже примере кода показано, как нарисовать треугольник на чертеже Visio.

Нарисуйте треугольник в SVG

Aspose.Diagram for .NET API позволяет разработчикам рисовать треугольник на странице и сохранять в формате SVG. В приведенном ниже примере кода показано, как нарисовать треугольник на чертеже Visio и сохранить его в формате SVG.

Нарисуйте треугольник в PDF

Aspose.Diagram for .NET API позволяет разработчикам рисовать треугольник на странице и сохранять в формате PDF. В приведенном ниже примере кода показано, как нарисовать треугольник на чертеже Visio и сохранить его в формате PDF.

Нарисуйте треугольник в PNG

Aspose.Diagram for .NET API позволяет разработчикам рисовать треугольник на странице и сохранять в формате PNG. В приведенном ниже примере кода показано, как нарисовать треугольник на чертеже Visio и сохранить его в формате PNG.

Нарисуйте треугольник в HTML

Aspose.Diagram for .NET API позволяет разработчикам рисовать треугольник на странице и сохранять в формате HTML. В приведенном ниже примере кода показано, как нарисовать треугольник на чертеже Visio и сохранить его в формате HTML.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *