Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
sergiy
6 лет назад

40 FreeBASIC - Фракталы. Снежинка Коха.

Как построить снежинку Коха...

0 - строим простой правильный треугольник АВС

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

2 - каждый из новых сегментов заминим такой же ломаной линией

и так далее...

Вычислим координаты неизвестных точек при построении вместо линии AB ломаной линии ACEDB.

У нас есть A(x1,y1) B(x2,y2)

image.png
x3 = x1 + (x2 - x1)/3
y3 = y1 + (y2 - y1)/3

x4 = x1 + 2⋅(x2 - x1)/3
y4 = y1 + 2⋅(y2 - y1)/3

А вот как получить коорднаты точки E?

Можно как и в прошлый раз воспользоваться формулами поворота. Но я нагуглил немного другие формулы (сам пока не понял, расмотрю их в одном из следующих постов)

l = sqr((x1-x2)^2^ + (y1-y2)^2^)
h = l / (2⋅sqr(3))
sina = (y2-y1)/l
cosa = (x2-x1)/l

x5=(x2+x1)/2 + h⋅sina
y5=(y2+y<sub1)/2 - h⋅cosa

        
dim as double x1,x2,x3,x4,x5, y1,y2,y3,y4,y5, l, h, sina, cosa

x1=100:y1=100
x2=600:y2=450

x3 = x1 + (x2 - x1)/3
y3 = y1 + (y2 - y1)/3

x4 = x1 + 2 * (x2 - x1)/3
y4 = y1 + 2 * (y2 - y1)/3

screenres 800,600

line(x1,y1)-(x3,y3),11

line(x4,y4)-(x2,y2),11

l = sqr((x1-x2)^2+(y1-y2)^2)
h = l / (2*sqr(3))
sina = (y2-y1)/l
cosa = (x2-x1)/l

x5=(x2+x1)/2 + h*sina
y5=(y2+y1)/2 - h*cosa

line(x3,y3)-(x5,y5),11
line(x4,y4)-(x5,y5),11

sleep

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

n=5 картинка мне кажется более красивой

n=10 невысокое разрешение экрана немного портит картинку

Осталось оформить рекурсивную подпрограмму, и вызвать её для равностороннего треугольника.

screenres 1024,768
const CL as integer=15

sub otr(byval x1 as double, byval y1 as double, byval x2 as double, byval y2 as double, byval n as integer) 
    dim as double x3,x4,x5, y3,y4,y5, l, h, sina, cosa

    x3 = x1 + (x2 - x1)/3
    y3 = y1 + (y2 - y1)/3

    x4 = x1 + 2 * (x2 - x1)/3
    y4 = y1 + 2 * (y2 - y1)/3
    
    l = sqr((x1-x2)^2+(y1-y2)^2)
    h = l / (2*sqr(3))
    sina = (y2-y1)/l
    cosa = (x2-x1)/l

    x5=(x2+x1)/2 + h*sina
    y5=(y2+y1)/2 - h*cosa

    if n>1 then 
        otr(x3,y3,x5,y5,n-1)
        otr(x5,y5,x4,y4,n-1)
        otr(x1,y1,x3,y3,n-1)
        otr(x4,y4,x2,y2,n-1)
        
    else
        line(x3,y3)-(x5,y5),CL
        line(x5,y5)-(x4,y4),CL
        line(x1,y1)-(x3,y3),CL
        line(x4,y4)-(x2,y2),CL
    end if
end sub

otr(0,760,1000,760,7)

sleep

Составим цикл от 1 до 5, это бедет уровень рекурсии.
Используем две новые команды FreeBASICа screenlock и screenunlock.

При их использовании изображение строится быстрее(чуточку) и нет мерцания. Первая команда блокирует вывод на экран, весь вывод в этот момент строится в буфере, а вторая команда выводит построенное озображение(содержимое буфера) на экран.
Можете запустить программу с ними, а потом убрать их и посмотреть результат.

screenres 1024,768
const CL as integer=15
dim i as integer

sub otr(byval x1 as double, byval y1 as double, byval x2 as double, byval y2 as double, byval n as integer) 
    dim as double x3,x4,x5, y3,y4,y5, l, h, sina, cosa

    x3 = x1 + (x2 - x1)/3
    y3 = y1 + (y2 - y1)/3

    x4 = x1 + 2 * (x2 - x1)/3
    y4 = y1 + 2 * (y2 - y1)/3
    
    l = sqr((x1-x2)^2+(y1-y2)^2)
    h = l / (2*sqr(3))
    sina = (y2-y1)/l
    cosa = (x2-x1)/l

    x5=(x2+x1)/2 + h*sina
    y5=(y2+y1)/2 - h*cosa

    if n>1 then 
        otr(x3,y3,x5,y5,n-1)
        otr(x5,y5,x4,y4,n-1)
        otr(x1,y1,x3,y3,n-1)
        otr(x4,y4,x2,y2,n-1)
        
    else
        line(x3,y3)-(x5,y5),CL
        line(x5,y5)-(x4,y4),CL
        line(x1,y1)-(x3,y3),CL
        line(x4,y4)-(x2,y2),CL
    end if
end sub

for i=1 to 5
    screenlock
    cls
    otr(780,538,243,539,i)
    otr(243,539,511,74,i)
    otr(511,74,780,538,i)
    screenunlock
    sleep 1500
next i
sleep


Вторая снежинка получается если строить ломаную не за треугольником, а внутрь треугольника. Для этого нужно изменить знак в формулах, перед h:
x5=(x2+x1)/2 - h*sina
y5=(y2+y1)/2 + h*cosa

5
429.829 GOLOS
На Golos с October 2016
Комментарии (8)
Сортировать по:
Сначала старые