-
Postów
434 -
Dołączył
-
Ostatnia wizyta
-
Wygrane w rankingu
36
Treść opublikowana przez perlon
-
Chciałbym zaproponować pewne rozwiązanie w zakresie tworzenia bazy danych rozdzielające odpowiedzialność klas. Mianowicie tworzeniem i operacjami na bazie danych nie powinna sie zajmować klasa służąca do tworzenia interfejsu użytkownika. Wkładanie logiki obsługi bazy do UI spowoduje mocne rozbudowanie metod obsługi zdarzeń i w rezultacie uzyskamy jedną superklasę wszystko robiącą w swoich metodach. Poniższa propozycja jest jedynie namiastką koncepcji, ale jeżeli zostanie zaakceptowania przez Parikona i umieszczona w kodzie, mogę tą część BackEnd'u dalej uszczegółowić. Oczywiście wszelkie uwagi, propozycje i krytyka mile widziane. Komentarze do fragmentów kodu poniżej każdej sekcji. Na początek proponuję wydzielenie struktury tabel do osobnej klasy: using System.Collections.Generic; namespace ProjektForum { public class DatabaseStructure { public static Dictionary<string,string> GetProjectsTableStructure() { Dictionary<string, string> result = new Dictionary<string, string>(); result.Add("Numer_projektu", "INT"); result.Add("Nazwa_projektu", "TEXT"); result.Add("Data_dodania", "TEXT"); result.Add("Data_zakonczenia", "TEXT"); result.Add("Sciezka", "TEXT"); return result; } } } Mamy tu metodę statyczna zwracającą słownik gdzie kluczem jest nazwa kolumny a wartością jest typ tej kolumny. Rozwiązanie nieidealne ale na początek wystarczy. Potrzebna nam będzie klasa która sprawdzi czy baza istnieje i czy zawiera odpowiednie kolumny. Umówmy się że na tym etapie używamy na sztywno bazy SQLite jak było w zamyśle Parikona aby maksymalnie uprościć obsługę. Nie budujemy przecież systemu uniwersalnego i super elastycznego. Klasa coś na taki kształt : using System; using System.Collections.Generic; using System.Data; using System.Data.SQLite; namespace ProjektForum { public class DatabaseChecker : IDisposable { private bool isDisposed = false; private SQLiteConnection connection; public DatabaseChecker(string _dbName) { connection = new SQLiteConnection($"Data Source = {_dbName}; Version = 3"); } // poniewaz w SQLite brakuje ALTER TABLE ALTER COLUMN poki co metoda jest w stanie jedynie dodac brakujaca kolumne // w przyszlosci nalezy uzupelnic funkcjonalnosc o modyfikacje typu kolumn porzez tymczasowa kopie tabeli // stworzenie nowej i skopiowanie danych ze starej na nowa tabele public void CheckTable( string tableName, Dictionary<string, string> structure) { string parseText; SQLiteCommand command; command = connection.CreateCommand(); command.CommandType = CommandType.Text; connection.Open(); // zagwarantowanie, ze tabela w bazie istnieje parseText = ParseCreateTableCommand(structure); command.CommandText = $"CREATE TABLE IF NOT EXISTS {tableName} ({parseText})"; command.ExecuteNonQuery(); // zagwarantowanie, ze tabela zawiera co najmniej kolumny z listy "structure" command.CommandText = $"PRAGMA table_info({tableName})"; var queryResult = command.ExecuteReader(); while (queryResult.Read()) { if ( !structure.ContainsKey( queryResult.GetString(1) )) { // dodaj kolumne jezeli brakuje command.CommandText = $"ALTER TABLE {tableName} ADD COLUMN {queryResult.GetString(1)} {structure[queryResult.GetString(1)]}"; command.ExecuteNonQuery(); } } connection.Close(); } string ParseCreateTableCommand(Dictionary<string, string> structure) { string result = ""; foreach( var item in structure) { if (result != "") { result += ","; } result += $"[{item.Key}] {item.Value}"; } return result; } public void Dispose() { connection.Dispose(); GC.SuppressFinalize(this); } } } Przyjmuje ona w konstruktorze ścieżkę do bazy danych SQLite. Zawiera jedną publiczną metodę CheckTable której argumentami jest nazwa tabeli oraz słownik z oczekiwaną strukturą tabeli. Metoda prywatna ParseCreateTableCommand zamienia słownik na stringa w formacie wymaganym przez komendę CREATE TABLE. Klasa posiada implementację interfejsu IDisposable do zarządzania swoim istnieniem o czym już za chwilę. Jak tego użyć? Ano prosto. Klasa ma w zasadzie jeden cel. Sprawić aby w podanej bazie danych istniała tabela o podanej nazwie i określonej strukturze. Robimy to tak: using (var dc = new DatabaseChecker(databasePath + "\\" + databaseFileName)) { dc.CheckTable("projekt_lista", DatabaseStructure.GetProjectsTableStructure()); } Wywołanie klasy zamykamy w bloku using żeby nie pozostawiać śmieci w pamięci. Po to był nam potrzebny interfejs IDisposable. Metoda Dispose w klasie DatabaseChecker załatwia zniszczenie obiektu klasy SQLiteConnection. Powyższy kod należy umieścić w metodzie startowej całej aplikacji. Wg mnie zanim jeszcze zaczniemy myśleć o wyświetleniu jakiegokolwiek okna. Dobrym kandydatem na to byłaby metoda Initialize() w klasie implementującej interfejs IExtensionApplication o której była już w tym wątku i nie tylko mowa. Załatwia nam to jako taką integralność bazy danych z aplikacją i kontrolę w momencie ładowania modułu .dll poleceniem NETLOAD. Jeżeli wystąpi potrzeba dołożenia jakiegoś pola do tabeli wystarczy zmienić metodę zwracającą odpowiedni słownik, albo dołożenie nowej tabeli wymaga dołożenia kolejnej metody w klasie DatabaseStructure. Mamy jedno miejsce gdzie siedzi definicja bazy a nie gdzieś rozsiane po kodzie i trudne do znalezienia. Na koniec. Powyższe rozwiązanie jest dalece niedoskonałe i nie załatwia wielu problemów na które natrafimy w bardziej zaawansowanym korzystaniu z bazy SQL. Ponadto można je zrobić bardziej elastycznym wykorzystując wzorce projektowe w tym np. metodę wytwórczą fabryki czy uzyskiwanie instancji obiektów za pomocą wstrzykiwania zależności, ale to jest już zupełnie inna historia, a ja nie chciałbym się wymądrzać bo za mało o tym jeszcze wiem. Niemniej mam chęć się tego poduczyć i mogę pewne rozwiązania wdrożyć jeżeli tylko Parikon zechce je wprowadzić do kodu, który tu tworzymy.
-
Drobna uwaga. Plik z bazą danych nie powinien mieć rozszerzenia .sql Zwyczajowo .sql jest to typ pliku zawierającego skrypt w języku SQL. Warto zmienić nazwę bazy na np. "projekty.sqlite". DB Browser for SQLite który sobie zainstalowałem przy otwieraniu bazy poszukuje plików z jednym z rozszerzeń : .db .sqlite .sqlite3 lub db3 I jeszcze jedna uwaga. Wydaje mi się że w nazwach kolumn należałoby unikać spacji. Może to w przyszłości powodować komplikacje przy migracjach na inne platformy lub wprowadzać niejednoznaczności przy np. parsowaniu nazw kolumn jeżeli kiedyś taka potrzeba zajdzie. Wpisanie podkreślenia zamiast spacji nic nie kosztuje a daje jednoznaczność nazwy.
-
Mam w biurze takie "dzieci ikonek". Dla nich do kompletu jeszcze by się przydała operacja odwrotna przywracająca skojarzenie napisu z faktycznym wymiarem (TextOverride = <>)
-
W 2019 SP1 w dalszym ciągu jest sprzężona ze sobą zmiana Annotation scale z Standard scale. Nie wiem czy to jest zamierzone ale wg mnie obie skale powinno się ustawiać niezależnie. Tak na marginesie. Jest gdzieś porządny opis jak to działa, żeby nie używać metody "na macanta"?
-
Jeszcze tylko drobna uwaga. W powyższym polecenie (netload "appdebug") można wołać bezpośrednio z pliku netload.scr. Używanie pośrednika autostart.lsp w zasadzie jest nadmiarowe, ale jakoś tak z przyzwyczajenia kod lispowy trzymam w .lsp. Przy innych okazjach w tym pliku wykonuję inne operacje dla meritum sprawy w naszym przypadku nieistotne.
-
Można nieco przyspieszyć pracę z kodem i umożliwić debugowanie kodu. Szczegóły na filmiku. Z góry przepraszam za słaby warsztat w nagrywaniu bo to mój pierwszy raz 😉
-
A może by wyłączyć właściwość path do innej klasy np. klasy służącej do zapisu i odczytu konfiguracji całej aplikacji i pobierać tą wartość w dowolnym miejscu i czasie. Ponadto można uzupełnić konfigurację o możliwość wskazania innej lokalizacji pliku bazy danych jeżeli tylko zajdzie taka potrzeba. Można to ustawiać np. w osobnym formularzu Ustawienia. Poniżej klasa typu Singleton która może trzymać różne ustawienia aplikacji. Umieściłem w niej funkcje zapisujące i odczytujące parametry dowolnego okna dialogowego w rejestrze windows. Dla każdego wywołanego okna można w zdarzeniu Loaded umieścić wywołanie var config = new ProjektForumSettings(); config.RestoreSettingsWindow(config.AppName, this); w zdarzeniu Closed var config = new ProjektForumSettings(); config.SaveSettingsWindow(config.AppName, this); Klasa ta przyjmuje domyślne pewne wartości (appName i appPath) ale można te wartości ustawiać np. przy starcie aplikacji. Będą one dostępne w całej aplikacji zawsze takie same. Zakłada również że ona sama znajduje się w tym samym assmebly co reszta aplikacji dla prawidłowego ustawienia appName i appPath. A klasa może wyglądać np. tak: using Microsoft.Win32; using System.Windows; namespace ProjektForum { public sealed class ProjektForumSettings { private static ProjektForumSettings instance = null; private int counter = 0; private string appPath; private string appName; public static ProjektForumSettings Instance { get { if (instance == null) { instance = new ProjektForumSettings(); } return instance; } } private ProjektForumSettings() { counter = 1; appPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.GetType().Assembly.Location)); appName = this.GetType().Assembly.GetName().Name; } public string AppPath { get { return appPath; } } public string AppName { get { return appName; } } public void SetAppPath(string path) { appPath = path; } public void SetAppName(string name) { appName = name; } public void SetKeyToRegister(string appName, string name, object value) { RegistryKey regKey = Registry.CurrentUser.OpenSubKey("Software", true); RegistryKey subKey = regKey.CreateSubKey(appName); subKey.SetValue(name, value); } public object GetKeyFromRegister(string appName, string name, object defaultValue) { RegistryKey regKey = Registry.CurrentUser.OpenSubKey("Software", true); RegistryKey subKey = regKey.CreateSubKey(appName); return subKey.GetValue(name, defaultValue); } public void SaveSettingsWindow(string appName, Window appWindow) { SetKeyToRegister(appName, "WindowState", (int)appWindow.WindowState); SetKeyToRegister(appName, "WindowLeft", appWindow.RestoreBounds.Left); SetKeyToRegister(appName, "WindowTop", appWindow.RestoreBounds.Top); SetKeyToRegister(appName, "WindowWidth", appWindow.RestoreBounds.Width); SetKeyToRegister(appName, "WindowHeight", appWindow.RestoreBounds.Height); } public void RestoreSettingsWindow(string appName, Window appWindow) { appWindow.Left = (int)GetKeyFromRegister(appName, "FormLeft", appWindow.Left); appWindow.Top = (int)GetKeyFromRegister(appName, "FormTop", appWindow.Top); appWindow.Width = (int)GetKeyFromRegister(appName, "FormWidth", appWindow.Width); appWindow.Height = (int)GetKeyFromRegister(appName, "FormHeight", appWindow.Height); appWindow.WindowState = (WindowState)GetKeyFromRegister(appName, "WindowState", appWindow.WindowState); } } }
-
Tego nawet nie sugerowałem. To był tylko mój przykład na podział strukturalny. UI może być w czymkolwiek. WPF jak najbardziej. Zresztą można to robić równolegle z innymi systemami UI bez szkody dla projektu. Ważne tylko, aby aplikacja była tak napisana, żeby dało się interfejs użytkownika np podmienić na inny bez utraty funkcjonalności samej aplikacji. To oczywiście śpiew przyszłości ale warto pomyśleć o modularności i zastosowaniu wzorca MVC. Dla aplikacji typu desktop to byłby wzorzec MVP (ModelViewPresenter). Część View w tym wzorcu to może być np. Windows Presentation Foundation.
-
A coś free bez watermark'a
-
Chciałbym dorzucić swoje uwagi w temacie architektury. Proponowałbym na początek rozdzielenie projektu co najmniej na dwa moduły dll. 1. Core Aplikacji : obsługa domeny czyli co aplikacja ma robić. Może być w tym cała obsługa okien dialogowych, dostęp do bazy danych i co tam jeszcze się uda napisać 2. Moduł startowy : w zasadzie jedna klasa odpowiedzialna za uruchomienie Core Struktura na obrazku na końcu posta. Uzasadnienie : Jądro aplikacji może wykonywać wszystkie swoje zadania nie mając świadomości istnienia platformy na jakiej jest wykonywane. W zasadzie otworzenie okna czy dostęp do bazy jest realizowany bez potrzeby angażowania ZwCAD'a. Łączenie jądra aplikacji z konkretną platformą ogranicza jego zastosowanie np. można przecież chcieć odpalić tą nakładkę na Auto... Brick... czy jakimś tam innym CAD w którym jest obsługa .NET albo bez użycia jakiejkolwiek platformy CAD. Autostart w module ładowanym przez NETLOAD w środowiski ZwCAD: using ProjektForum; using ZwSoft.ZwCAD.Runtime; namespace ProjectForumZwCAD { public class Autostart : IExtensionApplication { public void Initialize() { var projektForum = new Start(); } public void Terminate() { } } } Aplikacja zasadnicza (Core) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; namespace ProjektForum { public class Start { public Form mainForm; public Start() { mainForm = new MainForm(); mainForm.Show(); } } } Starter aplikacji WinForm. using ProjektForum; using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace ProjektForumWinApp { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } } } Należy zwrócić uwagę, że jedyne miejsce gdzie odwołuję się do biblioteki ZwCAD to jest autostart z namespace ProjectForumZwCAD. Pytanie na marginesie. Jakiś w miarę funkcjonalny i darmowy program do nagrywania pulpitu komputera żeby wstawić to później na forum? Coś polecicie?
-
[DCL] Walidacja wartości edit-box'a
perlon odpowiedział(a) na perlon temat w Wsparcie programistyczne LISP i VisualLISP
Zaadoptowałem do własnych potrzeb. Nie działa to ostatecznie tak jak chciałem i są sytuacje że validator nie zadziała prawidłowo, ale chyba nic więcej się nie da z tego wycisnąć. Lsp2Zel.lsp -
[DCL] Walidacja wartości edit-box'a
perlon opublikował(a) temat w Wsparcie programistyczne LISP i VisualLISP
Witam. Jakoś do tej pory nie było mi potrzebne ale przy pisaniu tego DCL'ka by mi się przydało. Czy jest możliwość w oknie DCL w elemencie edit_box validować wartość takiego pola tekstowego w trakcie zmiany jego wartości? Chodzi mi o taką funkcjonalność, która na bieżąco w trakcie pisania sprawdzałaby wartość pola i podejmowała akcję po każdej zmianie wartości. Coś w stylu zdarzenia OnChange dla C# i WinForms. Chciałbym sterować cechą enable przycisku w zależności od tego czy wartość w polu tekstowym jest prawidłowa lub nie. -
Naskrobałem dcl'a dla ułatwienia wyboru plików do szyfrowania. Może komuś się przyda. Lsp2Zel.lsp
-
Hmmm... Gdzie się zaszportała w 2019 możliwość szyfrowania LISP'ów? Przesiadłem się na 2019 z 2015+ a tam to było.
-
Szablony i skrypty startowe ZWPack
perlon odpowiedział(a) na dmatusz3 temat w ZWCAD Standard i Professional
Moja propozycja implementacji powyższej funkcjonalności bez obracania gridem. (defun RTD (/ANG) (/ (* ANG 180.0) pi)) (defun C:DWS2 (/ P1 P2 ANG) (if (setq P2 (getpoint "\--- Wskaż lewy punkt: " ) ; _ end of GETPOINT ) ;_ end of SETQ (progn (initget 1) (setq P1 (getpoint "\n--- Wskaż prawy punkt: " P2) ANG (angle P2 P1) ) ;_ end of SETQ (command "_UCS" "Z" P2 P1) ; zwykly obróy względem osiZ (command "_plan" "C") ; widok na aktualny UCS ) ;_ end of PROGN ) ;_ end of IF (princ) ) ;_ end of DEFUN (defun C:00 () (command "_-view" "top") ; jest na to ikonka na pasku View więc komenda mało potrzebna ale niech tam... ) ;_ end of DEFUN -
[C#] Detekcja środowiska
perlon odpowiedział(a) na perlon temat w Wsparcie programistyczne LISP i VisualLISP
Niestety poniższe podejście nie daje efektu. Initialize() w ogóle nie startuje. Uruchomi się tylko gdy usunę interfejs z klasy AcAutoStart (ciekawe dlaczego tak jest). Wymuszenie za pomocą [assembly: ...] również nic nie daje. Żeby mieć wspólną dll'kę dla ZwCAD i AutoCAD musiałbym chyba przejść na typy dynamic i stosować jakieś fabryki obiektów. Na 4programers ktoś zaproponował opakować klasy CAD'a klasą proxy. Ale to trzeba by zrobić 1:1 całe API .NET'a. W czort roboty i trzeba jeszcze to umieć 😞 using System; // [assembly: ZwSoft.ZwCAD.Runtime.ExtensionApplication(typeof(CADKit.ZwAutoStart))] // [assembly: Autodesk.AutoCAD.Runtime.ExtensionApplication(typeof(CADKit.AcAutoStart))] namespace CADKit { public class ZwAutoStart : ZwSoft.ZwCAD.Runtime.IExtensionApplication { public void Initialize() { string env = AppDomain.CurrentDomain.SetupInformation.ApplicationName; System.Windows.Forms.MessageBox.Show("ZwCAD -> " + env.ToUpper()); } public void Terminate() { } } public class AcAutoStart : Autodesk.AutoCAD.Runtime.IExtensionApplication { public void Initialize() { string env = AppDomain.CurrentDomain.SetupInformation.ApplicationName; System.Windows.Forms.MessageBox.Show("AutoCAD ->" + env.ToUpper()); } public void Terminate() { } } } -
[C#] Detekcja środowiska
perlon odpowiedział(a) na perlon temat w Wsparcie programistyczne LISP i VisualLISP
Ładowanie innych dll z głównego dll może rozwiązać problem platformy xxxCAD i zwiększyć uniwersalność aplikacji Tak jeszcze w uzupełnieniu do terminate(). U mnie komunikat z terminate() wyskakuje po zamknięciu okna ZwCAD'a. (w trybie debug) wtedy już nie ma okna konsoli. Żeby to sprawdzić wystarczy zamienić Console.WriteLine("Cleaning up..."); na MessageBox.Show("Cleaning up..."); Można w metodzie Initialize() zapisać referencję do obiektu IExtensionApplication np w jakimś singleton globalnym dla całej aplikacji i wołać jego metody w tym również terminate w dowolnym momencie ale i tak metoda terminate() będzie wywołana przy zamknięciu całego CAD'a. Tu pojawia się chyba kwestia niemożności odładowania dll'ki (brak NETUNLOAD) w trakcie trwania sesji CAD'a. Może są jakieś inne sposoby na usunięcie z pamięci wskazanej dll przez mechanizmy ogólne systemu a nie to co oferuje ZwCAD. -
[C#] Detekcja środowiska
perlon odpowiedział(a) na perlon temat w Wsparcie programistyczne LISP i VisualLISP
No jest z czego Próbowałem coś przez konstruktora ale jest wołany przy pierwszym użyciu dowolnej metody. O Initialize nie doczytałem. Wygląda na to, że metoda Initialize jest wywoływana tylko z jednej klasy pomimo zdefiniowania interfejsu IExtensionApplication w kilku. Wniosek : trzeba stworzyć klasę np. Autostart z interfejsem IExtensionApplication niekoniecznie zawierającą CommandMethod. Dzięki za rozwiązanie Z testów mi wyszło że Terminate() jest wołana przy niszczeniu obiektu a to następuje przy zamykaniu ZwCAD'a. Chyba może być wykorzystana do ręcznego wywołania Garbage Collector ewentualnie zapisu stanu aplikacji przed zamknięciem zwcad'a. Ale żeby tak w trakcie działania wywołać terminate() to chyba się nie da bo trzeba by mieć do tego obiektu referencję. A zdaje się że obiekt jest powoływany na zapleczu bez globalnie wystawionej referencji. -
[C#] Detekcja środowiska
perlon odpowiedział(a) na perlon temat w Wsparcie programistyczne LISP i VisualLISP
Tak sobie trochę sam odpowiem 😉 Co do generowania różnych dll to myślę że rozwiązaniem połowicznym może być globalny #define i w poszczególnych deklaracjach using zamykać je w #ifdef #endif. Jeszcze tylko muszę poszukać czy da się zautomatyzować generowanie nazwy dll w zależności od takiego #define Będę to sprawdzał. Na razie AppDomain.CurrentDomain.SetupInformation.ApplicationName; zwraca mi ZwCAD.exe więc już jest jakieś zaczepienie. -
Witam. Czy jest możliwość skonstruowania .dll'ki wczytywanej przez NETLOAD tak aby po jej załadowaniu automatycznie wykonał się jakiś kod z jej wnętrza? Coś w rodzaju autostartu wewnątrz dll bez wydawania komendy z commandline. I pytanie główne raczej dotyczy ogólnie C# czy w takim kodzie jest możliwe sprawdzenie jaka aplikacja załadowała do swoich assemblies taką właśnie dll'kę. Chodzi mi o możliwość używania jednej skompilowanej dll w różnych środowiskach CAD (AutoCAD, ZwCAD, BricsCad etc.) gdzie wewnętrzna metoda sprawdzałaby środowisko i za pomocą fabryki tworzyła instancję klasy Document zgodną z tym środowiskiem. Tak na marginesie, czy w ogóle jest możliwe stworzenie takiej dll która raz skompilowana będzie pracowała na różnych platformach CAD obsługujących .NET'a
-
Wygląda, że w 2019 to poprawili i jest jak powinno być.
-
Przechowywanie informacji w bazie danych
perlon odpowiedział(a) na kaminki temat w Wsparcie programistyczne LISP i VisualLISP
Wyważaniem otwartych drzwi, byłoby gdyby Przybornik był open-source. Dopóki tak nie jest to trzeba te drzwi wyważać jeżeli jest potrzeba funkcjonalności której w przyborniku brakuje. Co do trzymania danych poza rysunkiem każdy rasowy programista powie oczywiście "to zależy". Zależy od mnóstwa rzeczy i problemów jakie trzeba rozwiązać. Podstawowym jest przenośność. Jeżeli tworzy się aplikację na własne potrzeby albo zamkniętego kręgu odbiorców (np. w ramach jednego biura) a powstała dokumentacja jest wydawana na zewnątrz np w pdf'ach, to nie ma problemu. Co się jednak stanie z rysunkami dwg które zostaną pozbawione zewnętrznego źródła danych z chwilą ich przekazania odbiorcy? Chętnie zapoznałbym się z w miarę wygodnym i działającym rozwiązaniem problemu przenośności/zmian nazw plików/backap'u danych/pracy grupowej etc. przy zewnętrznej bazie do dwg'a. -
Problem z wyświetlaniem bloku po rozbiciu [SP2 beta]
perlon odpowiedział(a) na Bartek1977 temat w ZWCAD Standard i Professional
U mnie bywa tak w różnych sytuacjach nawet na wersji 2015+. Wg mnie _draworder -> Front załatwia temat. -
Witam. Tytuł strasznie enigmatyczny ale nie potrafiłem krótko zdefiniować problemu. A mianowicie: Mam wektor w którym umieszczam wartości sił. Mam wzór na zastępcze obciążenie równomiernie rozłożone. Wartości m, e_0, delta_d zdefiniowane jako stałe mam również wektor delta Obecnie same wartości 0 ale pojawią się tam jakieś inne wartości Chciałbym uzyskać taki wektor q_d w którym wartości będą obliczone wg powyższego wzoru ale zamiast delta_d były wzięte odpowiednie wartości wektora delta. Czyli q_d[1] wg wzoru dla d_d równej delta[1], q_d[2] wg wzoru dla d_d[2] itd. Czy jest to możliwe do uzyskania w SMath metodami nie nazbyt skomplikowanymi?
-
Żadne rozporządzenie jakiegokolwiek ministra nie może zmieniać bezpośrednio jak również pośrednio przepisów prawa zawartych w ustawie. Akty niższego rzędu nie mogą zmieniać aktów wyższego rzędu. To a'propos rozporządzenia, które na marginesie NIE DOTYCZY projektów wykonawczych. Jeżeli coś jest narysowane niezgodnie z normą nie znaczy, ze jest niejasne, nieczytelne. Dlatego w wielu miejscach co do stosowania norm z MARTIN_S się nie zgadzam. Natomiast uważam, że stosowanie na rysunku różnych jednostek używanych w tym samym kontekście (mówię tu np. o wymiarach liniowych) jest bardo prawdopodobnym źródłem błędów. Przywołuję w pamięci sytuację gdy na budowę przyjechało 10x więcej zbrojenia bo kosztorysant zliczył beton i zbrojenie w cm, ale niestety zbrojenie było wymiarowane w mm. I to są koszty dużo wyższe niż nakład na dopisanie jednego dodatkowego zera. Zresztą tak naprawdę to zero generuje nakładka. Nie pamiętam już od kiedy nie wpisuję ręcznie wymiarów. No może gdy stosuję przerwania i wymiary skażone. Ale i tak wtedy najpierw rysuję prawdziwy wymiar a po zerwaniu dynamicznego połączenia go streczuję. Tak więc zdecydowanie jedna jednostka na rysunku. U mnie to są wyłącznie mm do wszystkiego. Jeżeli chodzi o oznaczenie koty, czy kropeczka lub strzałka zamiast kreseczki to nie ma znaczenia. Wg mnie nawet rozróżnienie kot konstrukcyjnych od architektonicznych poprzez odmienny znak jest czytelniejsze. Zgadzam się również z Parikonem w kwestii miejsca stosowania norm. Jak wspomniałem rozporządzenie nic nie mówi o zasadach sporządzania rysunków wykonawczych, więc argument niezgodności z normą rysunkową jest zupełnie chybiony. O normie PN-EN ISO 3766 rozporządzenie również milczy.