Форум умных людей

Задачи и головоломки => Для программистов => Тема начата: fortpost от Октябрь 25, 2012, 15:19:11



Название: Пифагорово дерево
Отправлено: fortpost от Октябрь 25, 2012, 15:19:11
Дерево Пифагора представляет собой фрактал, сформированный следующим способом:

Начнем с единичного квадрата. Затем, считая одну из сторон основанием (в анимации это нижняя сторона):

Построим прямоугольный треугольник с гипотенузой на стороне, противоположной основанию, и с соотношением сторон 3:4:5. Построим квадраты на катетах треугольника.Повторим эту процедуру для обоих квадратов. В результате фигура, полученная после бесконечного числа итераций, является Пифагоровым деревом.
(http://i076.radikal.ru/1210/ab/6d0005f9020f.gif)
Можно показать, что существует по крайней мере один прямоугольник, стороны которого параллельны самому большому квадрату, охватывающий Пифагорово дерево полностью. Надо найти такой прямоугольник наименьшей площади, и дать ответ, округленный до 10 знаков после запятой.


Название: Re: Пифагорово дерево
Отправлено: moonlight от Октябрь 27, 2012, 15:30:06
Показать скрытый текст


Название: Re: Пифагорово дерево
Отправлено: fortpost от Октябрь 27, 2012, 20:53:11
Показать скрытый текст
Здорово! А как посчитали?


Название: Re: Пифагорово дерево
Отправлено: moonlight от Октябрь 28, 2012, 20:01:59
Дерево покрылось листьями...
(http://i44.fastpic.ru/big/2012/1028/37/bcef0cd1f782c35f55a4cdf3b494da37.png) (http://fastpic.ru/)

Сначала посчитал расстояние от центра первого квадрата до центра самого удалённого квадрата. Затем зная это расстояние обошёл дерево ещё 4 раза отбрасывая те ветви которые оказывались бесперспективными для достижения одной из 4-х границ.

Глубина обхода - 100.


Название: Re: Пифагорово дерево
Отправлено: or0ez от Январь 14, 2020, 08:54:11
программа на C
Код:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct{double x,y;}cplx;

typedef struct{double size;cplx center,orient;}square;

cplx newCplx(double x,double y){
    cplx z;
    z.x=x;
    z.y=y;
    return z;
}

square newSquare(double size,cplx center,cplx orient){
    square sq;
    sq.size=size;
    sq.center=center;
    sq.orient=orient;
    return sq;
}

cplx add(cplx z1,cplx z2){return newCplx(z1.x+z2.x,z1.y+z2.y);}

cplx subt(cplx z1,cplx z2){return newCplx(z1.x-z2.x,z1.y-z2.y);}

cplx mult(cplx z1,cplx z2){
    return newCplx(z1.x*z2.x-z1.y*z2.y,z1.x*z2.y+z1.y*z2.x);
}

cplx mult1(cplx z,double k){
    return newCplx(z.x*k,z.y*k);
}

cplx w1,w2,z1,z2;
double xMin,xMax,yMin,yMax,dX,dY;
double k;

square fSq1(square sq){
    double size=sq.size*0.8;
    cplx orient=mult(sq.orient,w1);
    cplx center=add(sq.center,mult(mult1(sq.orient,sq.size),z1));
    return newSquare(size,center,orient);
}

square fSq2(square sq){
    double size=sq.size*0.6;
    cplx orient=mult(sq.orient,w2);
    cplx center=add(sq.center,mult(mult1(sq.orient,sq.size),z2));
    return newSquare(size,center,orient);
}

double fXMin(square sq,int l,int l0){
    if(l==l0||sq.center.x-k*sq.size>xMin)return sq.center.x;
    double x1=fXMin(fSq1(sq),l+1,l0);
    double x2=fXMin(fSq2(sq),l+1,l0);
    double x=fmin(sq.center.x,fmin(x1,x2));
    if(x<xMin)xMin=x;
    return x;
}

double fXMax(square sq,int l,int l0){
    if(l==l0||sq.center.x+k*sq.size<xMax)return sq.center.x;
    double x1=fXMax(fSq1(sq),l+1,l0);
    double x2=fXMax(fSq2(sq),l+1,l0);
    double x=fmax(sq.center.x,fmax(x1,x2));
    if(x>xMax)xMax=x;
    return x;
}

double fYMin(square sq,int l,int l0){
    if(l==l0||sq.center.y-k*sq.size>yMin)return sq.center.y;
    double y1=fYMin(fSq1(sq),l+1,l0);
    double y2=fYMin(fSq2(sq),l+1,l0);
    double y=fmin(sq.center.y,fmin(y1,y2));
    if(y<yMin)yMin=y;
    return y;
}

double fYMax(square sq,int l,int l0){
    if(l==l0||sq.center.y+k*sq.size<yMax)return sq.center.y;
    double y1=fYMax(fSq1(sq),l+1,l0);
    double y2=fYMax(fSq2(sq),l+1,l0);
    double y=fmax(sq.center.y,fmax(y1,y2));
    if(y>yMax)yMax=y;
    return y;
}

int main()
{
    w1=newCplx(0.8,0.6);
    w2=newCplx(0.6,-0.8);
    z1=mult(subt(newCplx(-0.5,0.5),mult(newCplx(-0.4,-0.4),w1)),newCplx(0,-1));
    z2=mult(subt(newCplx(0.5,0.5),mult(newCplx(0.3,-0.3),w2)),newCplx(0,-1));
    xMin=xMax=yMin=yMax=0;
    k=4.5*sqrt(2);
    square sq=newSquare(1,newCplx(0,0),newCplx(0,1));
    int l=0;
    double dX=0,dY=0,dX0,dY0;
    double eps=1e-14;
    do{
        l+=10;
        dX0=dX,dY0=dY;
        fXMin(sq,1,l),fXMax(sq,1,l),fYMin(sq,1,l),fYMax(sq,1,l);
        dX=xMax-xMin,dY=yMax-yMin;
        printf("L = %d\n",l);
        printf("xMin = %18.15f\n",xMin);
        printf("xMax = %18.15f\n",xMax);
        printf("yMin = %18.15f\n",yMin);
        printf("yMax = %18.15f\n",yMax);
        printf("  dX = %18.15f\n",dX);
        printf("  dY = %18.15f\n\n",dY);
    }while(fabs(dX-dX0)>eps||fabs(dY-dY0)>eps);
    return 0;
}


Название: Re: Пифагорово дерево
Отправлено: RudikoV от Декабрь 23, 2021, 19:17:58
А это здоово!