/
dinruspro
/
examples
Обзор
Документация
Войти
/
dinruspro
/
examples
Код
Запросы
0
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
GeoFun/GeoFun.cpp
830 строк
17 KB
EnergonV
Примеры перекочевали в гит-репо (наконец-то!)
09 янв 2024, 19:13
09 янв 2024, 19:13
757fe92
Код
Авторство
О чём код?
#include "GeoFun.h" #define IMAGECLASS GFImg #define IMAGEFILE <GeoFun/GeoFun.iml> #include <Draw/iml_source.h> //When idraw = 1 it will create image at actual size based on radius values //Else image created to screen window diaplay size template <class T> void DrawCanvas::DoPaint0 ( T& sw, int idraw ) { double x1, y1; int cnt1, cnt2; int RunTo ; Sizef sz; if ( idraw == 1 ) { sz = Sizef ( 2 * Radius1 + 20, 2 * Radius1 + 20 ); } else { sz = GetSize(); } sw.Clear ( White() ); x1 = sz.cx / 2 ; y1 = sz.cy / 2 ; // Show color fill. Draw bacground circle with color if ( ColorFill ) { if ( ShowGradient ) { sw.Ellipse ( x1, y1, Radius1, Radius1 ).Fill ( x1, y1, fcolorB1, Radius1, fcolorB2 ); } else { sw.Ellipse ( x1, y1, Radius1, Radius1 ).Fill ( fcolorB1 ); } } cnt1 = data.GetCount(); for ( int i = 0; i < data.GetCount(); i++ ) { Vector<Pointf>& p = data[i].point; sw.Move ( x1 + p[0].x, y1 + p[0].y ); cnt2 = p.GetCount(); // If animation flag set do incremental display of curve // elase show all curve points. RunTo = ShowAnimation ? ShowTo : cnt2 ; if ( RunTo > cnt2 ) RunTo = cnt2 ; for ( int j = 1; j < RunTo; j++ ) sw.Line ( x1 + p[j].x, y1 + p[j].y ); sw.Stroke ( data[i].penwidth, data[i].lcolor ); sw.EvenOdd ( true ); if ( ColorFill ) { if ( ShowGradient ) { sw.Fill ( x1, y1, data[i].fcolorM1, Radius1, data[i].fcolorM2, GRADIENT_REFLECT ); } else { sw.Fill ( data[i].fcolorM1 ); } } // Show if option animation set if ( ShowAnimation ) { sw.BeginOnPath ( 1.0 ); sw.DrawImage ( 0, -GFImg::Bee().GetHeight() / 2, GFImg::Bee() ); sw.End(); sw.Ellipse ( x1, y1, BaseR, BaseR ).Stroke ( 3, Blue() ); sw.Ellipse ( x1 + data[i].CenR[RunTo-2].x, y1 + data[i].CenR[RunTo-2].y, RollR, RollR ).Stroke ( 3, LtBlue() ); sw.Move ( x1, y1 ); sw.Line ( x1 + data[i].CenR[RunTo-2].x, y1 + data[i].CenR[RunTo-2].y ); sw.Line ( x1 + data[i].point[RunTo-2].x, y1 + data[i].point[RunTo-2].y ); sw.Stroke ( 3, Red() ); ColorFill = false ; // this is required to stop colorfill if other options are changed during animation } } } DrawCanvas::DrawCanvas() { } // at present this function is redundant but kept here to improve printing in future void DrawCanvas::DoPaint ( Painter& sw ) { bool painting = false ; if ( painting ) { PaintingPainter h ( 4000, 4000 ); DoPaint0 ( h, 0 ); sw.Paint ( h ); } else DoPaint0 ( sw, 0 ); } void DrawCanvas::Paint ( Draw& drw ) { Size sz = GetSize(); ImageBuffer ib ( sz ); BufferPainter sw ( ib ); bool transparent = false ; DoPaint ( sw ); drw.DrawImage ( 0, 0, ib ); } Image GeoFun::GetImage() { Size sz = Size ( int ( dc1.Radius1 * 2 + 20 ), int ( dc1.Radius1 * 2 + 20 ) ); ImageBuffer ib ( sz ); BufferPainter bp ( ib, MODE_ANTIALIASED ); dc1.DoPaint0 ( bp, 1 ); return static_cast<Image>(ib); } void GeoFun::SaveToImageFile ( String fileName ) { GuiLock __; if ( IsNull ( fileName ) ) { FileSel fs; fs.Type ( "Файл PNG", "*.png" ); fs.Type ( "Файл JPEG", "*.jpg" ); if ( !fs.ExecuteSaveAs ( t_ ( "Сохранение чертежа в файле PNG или JPEG" ) ) ) { Exclamation ( t_ ( "Чертёж не сохранён" ) ); return; } fileName = fs; } if ( GetFileExt ( fileName ) == ".png" ) { PNGEncoder encoder; encoder.SaveFile ( fileName, GetImage() ); } else if ( GetFileExt ( fileName ) == ".jpg" ) { JPGEncoder encoder ( 90 ); encoder.SaveFile ( fileName, GetImage() ); } else Exclamation ( Format ( t_ ( "Формат файла \"%s\" не найден" ), GetFileExt ( fileName ) ) ); } void GeoFun::SaveToAutoCadScript ( String fileName ) { if ( IsNull ( fileName ) ) { FileSel fs; fs.Type ( "SCR file", "*.scr" ); if ( !fs.ExecuteSaveAs ( t_ ( "Сохранеие чертежа в Polyline -- AutoCAD Script " ) ) ) { Exclamation ( t_ ( "Чертёж не сохранён" ) ); return; } fileName = fs; } if ( GetFileExt ( fileName ) == ".scr" ) { String sScr ; for ( int i = 0; i < dc1.data.GetCount(); i++ ) { sScr << "PLINE\n" ; Vector<Pointf>& p = dc1.data[i].point; for ( int j = 0; j < p.GetCount(); j++ ) sScr << p[j].x << "," << p[j].y << "\n"; sScr << "\nZ\nE\n"; } FileOut fo ; fo.Open ( fileName ); fo.Put ( sScr ); fo.Close(); } } void GeoFun::SaveToSVG ( String fileName ) { if ( IsNull ( fileName ) ) { FileSel fs; fs.Type ( "SVG file", "*.svg" ); if ( !fs.ExecuteSaveAs ( t_ ( "Сохранение файла SVG " ) ) ) { Exclamation ( t_ ( "SVG не сохранён" ) ); return; } fileName = fs; } if ( GetFileExt ( fileName ) == ".svg" ) { String sXML ; sXML.Clear(); sXML << "<?xml version=\"1.0\" standalone=\"no\"?>" ; sXML << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" " ; sXML << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" ; sXML << "<svg width=\"100%\" height=\"100%\" version=\"1.1\" " ; sXML << "xmlns=\"http://www.w3.org/2000/svg\"> \n \n" ; for ( int i = 0; i < dc1.data.GetCount(); i++ ) { sXML << "\n<polygon points=\" "; Vector<Pointf>& p = dc1.data[i].point; for ( int j = 0; j < p.GetCount(); j++ ) sXML << Format ( "%0.4f", p[j].x ) << "," << Format ( "%0.4f", p[j].y ) << " "; sXML << "\" style=\"fill:none;stroke:#00C000;stroke-width:0.4\" />\n" ; } sXML << "</svg>\n"; FileOut fo ; fo.Open ( fileName ); fo.Put ( sXML ); fo.Close(); } } void GeoFun::Print() { Report r; String sQtf; r.SetPageSize ( 4400, 4400 ); Size sz = Size ( 4200, 4200 ); Image im = GetImage(); qtfim = CreatePNGObject ( im, Size ( 600, 600 ), sz ); sQtf << "[s0;= " ; sQtf << qtfim << " ]"; r << sQtf ; Perform ( r ); } // This function calculates curve data points for display void GeoFun::PrepareData() { int p, q, pw; double a, b, h ; double x, y; double Period, step, t ; step = 1.0 ; // value in deg int q1 = InputPane.edValP ; if ( q1 > 0 ) { p = InputPane.edValP ; } else { p = 1 ; InputPane.edValP.SetData ( p ) ; } q1 = InputPane.edValQ ; if ( q1 > 0 ) { q = InputPane.edValQ ; } else { q = 1 ; InputPane.edValQ.SetData ( q ) ; } q1 = InputPane.edPenWidth ; if ( q1 > 0 ) { pw = InputPane.edPenWidth ; } else { pw = 1 ; InputPane.edPenWidth.SetData ( pw ) ; } Period = 2 * M_PI * p ; int iCrv = ~InputPane.CurveType; if ( ( iCrv == 1 ) || ( iCrv == 3 ) ) { p = -p ; } double tmp = InputPane.edBaseCircleRad; if ( tmp < 10 ) { a = 10 ; InputPane.edBaseCircleRad.SetData ( a ); } else { a = InputPane.edBaseCircleRad; } b = ( double ) p * a / ( double ) q; dc1.BaseR = a ; dc1.RollR = fabs ( b ); if ( iCrv < 2 ) { h = fabs ( b ); } else { tmp = InputPane.edArmLength ; if ( tmp < 0 ) { h = 0 ; InputPane.edArmLength.SetData ( h ) ; } else { h = InputPane.edArmLength ; } } dc1.Radius1 = fabs ( a + b ) + h ; InputPane.RollingRad = "Радиус Вращения : " + Format ( "%0.2f", b ) ; dc1.Zoomed = InputPane.optZoom.GetData(); if ( dc1.Zoomed ) { Size sz = dc1.GetSize(); double dmax = sz.cx ; if ( sz.cy < dmax ) dmax = sz.cy; dmax -= 10 ; double zScale = fabs ( dmax / ( 2 * dc1.Radius1 ) ); a = a * zScale; h = h * zScale; b = b * zScale; dc1.BaseR = a ; dc1.RollR = fabs ( b ); dc1.Radius1 = fabs ( a + b ) + h ; } dc1.data.Clear(); dc1.data.Add(); dc1.data[0].point.Clear(); dc1.data[0].CenR.Clear(); dc1.data[0].lcolor = ~InputPane.LineColor; dc1.data[0].fcolorM1 = ~InputPane.FillColorM1; dc1.data[0].fcolorM2 = ~InputPane.FillColorM2; dc1.data[0].penwidth = pw; dc1.fcolorB1 = ~InputPane.FillColorB1; dc1.fcolorB2 = ~InputPane.FillColorB2; dc1.ShowGradient = ~InputPane.optGradient; dc1.ColorFill = ~InputPane.optColorFill; int NumSteps = abs ( ( int ) ( 2.0 * ( double ) p * 180.0 / step ) ) + 1 ; for ( int i = 0; i < NumSteps; i++ ) { t = ( double ) i / ( double ) NumSteps * Period ; x = ( a + b ) * cos ( t ) + h * cos ( ( ( a + b ) / b ) * t ) ; y = ( a + b ) * sin ( t ) + h * sin ( ( ( a + b ) / b ) * t ); Pointf p1; p1.Clear(); p1.x = x ; p1.y = y ; dc1.data[0].point.Add ( p1 ); p1.Clear(); x = ( a + b ) * cos ( t ); y = ( a + b ) * sin ( t ); p1.x = x ; p1.y = y ; dc1.data[0].CenR.Add ( p1 ); } Pointf p1; p1.x = dc1.data[0].point[0].x ; p1.y = dc1.data[0].point[0].y ; dc1.data[0].point.Add ( p1 ); dc1.Refresh(); } void GeoFun::ShowAnimated() { int MaxCnt = dc1.data[0].point.GetCount(); if ( dc1.ShowAnimation ) { if ( dc1.ShowTo < MaxCnt ) { dc1.Refresh(); dc1.ShowTo += dc1.AnimSpeed ; } else { dc1.ShowAnimation = false ; } } else { Animate.Kill(); PrepareData(); dc1.ShowAnimation = false ; } } void GeoFun::SetAnimation() { dc1.AnimSpeed = InputPane.edAnimSpeed.GetData(); dc1.ShowTo = 5 ; dc1.ShowAnimation = dc1.ShowAnimation ? false : true ; dc1.ColorFill = false ; if ( dc1.ShowAnimation ) { InputPane.btnShowAnimation.SetLabel ( "Остановить Анимацию" ); } else { InputPane.btnShowAnimation.SetLabel ( "Начать Анимацию" ); } Animate.KillSet ( -50, [=, this]{ ShowAnimated();} ); } void GeoFun::FirstDraw() { First = false ; PrepareData(); DUMP ( "First Draw" ); } void GeoFun::Serialize ( Stream& s ) { s % InputPane.edArmLength % InputPane.edBaseCircleRad % InputPane.edPenWidth % InputPane.edValP % InputPane.edValQ % InputPane.LineColor % InputPane.FillColorM1 % InputPane.FillColorM2 % InputPane.FillColorB1 % InputPane.FillColorB2 % InputPane.optGradient % InputPane.optColorFill % InputPane.CurveType % InputPane.optZoom % InputPane.edAnimSpeed ; SerializePlacement ( s ); } // Using layout to redraw on windows resize void GeoFun::Layout() { if ( !First ) { PrepareData(); } TopWindow::Layout(); } void GeoFun::About() { WithAboutLayout<TopWindow> dlg; dlg.AboutText = GetTopic ( "topic://GeoFun/app/About$ru-ru" ).text; CtrlLayoutOK ( dlg, "О Программе" ); dlg.CenterScreen(); dlg.Run(); } void GeoFun::Help() { HelpWindow helpme; helpme.GoTo ( "topic://GeoFun/app/Help$ru-ru" ); helpme.Execute(); } void GeoFun::Exit() { Close(); } void GeoFun::SetAnimationSpeed() { dc1.AnimSpeed = InputPane.edAnimSpeed.GetData(); if ( dc1.AnimSpeed < 1 ) dc1.AnimSpeed = 1; if ( dc1.AnimSpeed > 20 ) dc1.AnimSpeed = 20; InputPane.edAnimSpeed.SetData ( dc1.AnimSpeed ); } void GeoFun::OptionColorFill() { int i = InputPane.optColorFill.Get(); i = i ? 0 : 1; InputPane.optColorFill.Set ( i ) ; PrepareData(); } void GeoFun::OptionGradient() { int i = InputPane.optGradient.Get(); i = i ? 0 : 1; InputPane.optGradient.Set ( i ) ; PrepareData(); } void GeoFun::OptionZoom() { int i = InputPane.optZoom.Get(); i = i ? 0 : 1; InputPane.optZoom.Set ( i ) ; PrepareData(); } void GeoFun::SetCurveType ( int CrvType ) { InputPane.CurveType.SetData ( CrvType ); SetCurveTypeMenu ( CrvType ); } void GeoFun::SetCurveTypeMenu ( int CrvType ) { EpiCyclo = HypoCyclo = EpiTroch = HypoTroch = false ; switch ( CrvType ) { case 1 : HypoCyclo = true ; break ; case 2 : EpiTroch = true ; break ; case 3 : HypoTroch = true ; break ; default : EpiCyclo = true ; } PrepareData(); } // Menu Functions void GeoFun::SettingsMenu ( Bar& bar ) { bar.Add ( t_ ( "Цветная Заливка" ), [=, this] { OptionColorFill();} ).Check ( dc1.ColorFill ) .Help ( t_ ( "Изменить настройки" ) ); bar.Add ( t_ ( "Градиентная Заливка" ), [=, this] { OptionGradient();} ).Check ( dc1.ShowGradient ) .Help ( t_ ( "Изменить настройки" ) ); bar.Add ( t_ ( "Растянуть" ), [=, this] { OptionZoom();} ).Check ( dc1.Zoomed ) .Help ( t_ ( "Растянуть по размеру окна" ) ); } void GeoFun::FileMenu ( Bar& bar ) { bar.Add ( t_ ( "Сохранить рисунок" ), CtrlImg::save_as(), [=, this] {SaveToImageFile("");} ) .Help ( t_ ( "Сохранить как PNG или JPG" ) ); bar.Add ( t_ ( "Save AutoCAD Script" ), CtrlImg::save(), [=, this] { SaveToAutoCadScript("");} ) .Help ( t_ ( "Сохранить как файл AutoCAD Script (.scr)" ) ); bar.Add ( t_ ( "Сохранить как SVG" ), CtrlImg::save(), [=, this]{ SaveToSVG("");} ) .Help ( t_ ( "Сохранить как файл Scalable vector graphics (.svg)" ) ); bar.Separator(); bar.Add ( t_ ( "Печать" ), CtrlImg::print() , [=, this] { Print();} ) .Help ( t_ ( "Печать рисунка, страница A4" ) ); bar.Separator(); bar.Add ( t_ ( "Выход" ), [=, this] { Exit(); }) .Help ( t_ ( "Покинуть приложение" ) ); } void GeoFun::CurvesMenu ( Bar& bar ) { bar.Add ( t_ ( "Эпициклоид" ), [=, this] { SetCurveType(0);} ) .Help ( t_ ( "Начертить кривую Эпициклоид" ) ).Check ( EpiCyclo ); bar.Add ( t_ ( "Гипоциклоид" ), [=, this] { SetCurveType( 1 );} ) .Help ( t_ ( "Начертить кривую Гипоциклоид" ) ).Check ( HypoCyclo ); bar.Add ( t_ ( "Эпитрохоид" ), [=, this] { SetCurveType( 2 );} ) .Help ( t_ ( "Начертить кривую Эпитрохоид" ) ).Check ( EpiTroch ); bar.Add ( t_ ( "Гипотрохоид" ), [=, this] { SetCurveType( 3 );} ) .Help ( t_ ( "Начертить кривую Гипотрохоид" ) ).Check ( HypoTroch ); bar.Separator(); bar.Add ( t_ ( "Анимированный Чертёж" ), [=, this] { SetAnimation( );} ) .Help ( t_ ( "Показать анимацию черчения кривой" ) ).Check ( AnimMn ); } void GeoFun::MainMenu ( Bar& bar ) { bar.Sub ( t_ ( "Файл" ), [=, this] (Bar& bar) { FileMenu(bar);} ); bar.Sub ( t_ ( "Кривые" ), [=, this] (Bar& bar) { CurvesMenu(bar);} ); bar.Sub ( t_ ( "Опции" ), [=, this] (Bar& bar) { SettingsMenu(bar);} ); bar.Sub ( t_("Ассистент"), [=, this] (Bar& bar) {HelpMenu(bar);} ); } void GeoFun::HelpMenu ( Bar& bar ) { bar.Add ( t_ ( "О Программе" ), CtrlImg::information(), [=, this] { About();} ) .Help ( t_ ( "О GeoFun" ) ); bar.Separator(); bar.Add ( t_ ( "Справка" ), CtrlImg::help(), [=, this] { Help();} ) .Help ( t_ ( "Справка по GeoFun" ) ); } GeoFun::GeoFun() { CtrlLayout ( *this, "GeoFun : Наслаждайтесь Геометрическими Кривыми" ); Icon ( GFImg::gficon() ); CtrlLayout ( InputPane ); Sizeable().Zoomable(); InputPane.btnImg << [=, this] { SaveToImageFile( "" );}; InputPane.btnPrint << [=, this] { Print();}; InputPane.btnShowAnimation << [=, this] { SetAnimation();}; Add ( dc1.HSizePosZ ( 5, 160 ).VSizePosZ ( 25, 5 ) ); Add ( InputPane.RightPosZ ( 5, 150 ).VSizePosZ ( 2, 5 ) ); BackPaint(); dc1.data.Clear(); // Check config file available else set default data if ( !cfgAvailable ) { InputPane.edArmLength.SetData ( 112 ) ; InputPane.edBaseCircleRad.SetData ( 145 ); InputPane.edPenWidth.SetData ( 3 ); InputPane.edValP.SetData ( 5 ); InputPane.edValQ.SetData ( 12 ); InputPane.edAnimSpeed.SetData ( 5 ); InputPane.LineColor.SetData ( Blue() ) ; InputPane.FillColorM1.SetData ( LtGreen() ) ; InputPane.FillColorM2.SetData ( Yellow() ) ; InputPane.FillColorB1.SetData ( Blue() ) ; InputPane.FillColorB2.SetData ( LtCyan() ) ; InputPane.optGradient.Set ( 1 ); InputPane.optColorFill.Set ( 1 ); InputPane.CurveType.SetData ( 2 ); } InputPane.CurveType.WhenAction << [=, this] {SetCurveTypeMenu(( int ) InputPane.CurveType.GetData() );}; InputPane.optGradient.WhenAction << [=, this] {PrepareData();}; InputPane.optColorFill.WhenAction << [=, this] {PrepareData();}; InputPane.FillColorB1.WhenAction << [=, this] {PrepareData();}; InputPane.FillColorB2.WhenAction << [=, this] {PrepareData();}; InputPane.FillColorM1.WhenAction << [=, this] {PrepareData();}; InputPane.FillColorM2.WhenAction << [=, this] {PrepareData();}; InputPane.LineColor.WhenAction << [=, this] {PrepareData();}; InputPane.edPenWidth.WhenAction << [=, this] {PrepareData();}; InputPane.edValP.WhenAction << [=, this] {PrepareData();}; InputPane.edValQ.WhenAction << [=, this] {PrepareData();}; InputPane.edArmLength.WhenAction << [=, this] {PrepareData();}; InputPane.edBaseCircleRad.WhenAction << [=, this] {PrepareData();}; InputPane.edAnimSpeed.WhenAction << [=, this] {SetAnimationSpeed();}; InputPane.optZoom.WhenAction << [=, this] {PrepareData();}; // Set timercallback to do first painting with calculations // You can not call this directly from constructor SetTimeCallback ( 200, [=, this] {FirstDraw();} ); dc1.ShowTo = 5 ; // start point of animation. menu.Set ([=, this] (Bar& bar) { MainMenu( bar );} ); dc1.ShowAnimation = false; } GUI_APP_MAIN { GeoFun gf ; gf.First = true ; String cfgfile = ConfigFile(); if ( FileExists ( cfgfile ) ) { cfgAvailable = true ; if ( !LoadFromFile ( gf, cfgfile ) ) { cfgAvailable = false ; Exclamation ( "Ошибка при загрузке файла конфигурации!" ); } } else { cfgAvailable = false ; } gf.Run(); StoreToFile ( gf ); }