![]() |
#1 | ||
![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Mar 2006
Location: ,
Posts: 4,613
|
![]() Most of the programs I make at work are not suitable or interesting to post here, but I have also made some reusable libraries, and some curious side projects.
I'll start with one of the latter, made in Maple. It calculates the equations of the position of the Sun, relative to any point on the Earth, as a function of the time of the year. Code:
# speed of Earth's orbit in rad/h oo_t:= evalf(2*Pi/(365.25*24)): # speed of Earth's rotation in rad/h oo_r:= evalf(2*Pi/24): # tilt of Earth's rotation axis tilt:= evalf(23.44*Pi/180): # latitude: 41º 38' N lat:= evalf(( 41 + 38 /60)*Pi/180): # longitude: 4º 43' W lon:= evalf(( -4 - 43 /60)*Pi/180): x:= evalf(Vector(3, [cos(oo_t*t), -sin(oo_t*t), 0])): # changes of basis B:= simplify(evalf(Matrix(3, 3, [ cos(tilt), 0, sin(tilt), 0, 1, 0, -sin(tilt), 0, cos(tilt) ]).Matrix(3, 3, [ cos(oo_r*t), -sin(oo_r*t), 0, sin(oo_r*t), cos(oo_r*t), 0, 0, 0, 1 ]).Matrix(3, 3, [ cos(lon), -sin(lon), 0, sin(lon), cos(lon), 0, 0, 0, 1 ]).Matrix(3, 3, [ sin(lat), 0, cos(lat), 0, 1, 0, -cos(lat), 0, sin(lat) ]))^%T): # finally, parametric equation of position r:= simplify(B.x): ![]() (click) The purpose is to know the position of the sun at any hour of any day of the year, but I think the most visual result is had by plotting the Sun's trajectory along a whole year. Code:
plots[spacecurve]( r, t=0..365.25*24, numpoints=87660, axes=normal, labels=["S-N", "E-W", "z-n"], tickmarks=[0, 0, 0], shading=zhue, thickness=2, orientation=[130, 60]); ![]() (click) One axis goes from South to North, another from East to West, and the other is the verticality. The colours colder than blueish green are below the horizon--it's night. Another example: the Equator, you can see why there's no Summer or Winter over there: ![]() (click) And Murmansk, Russia, above the Arctic Circle. Notice how the Sun doesn't set during some Summer days, and it doesn't dawn during some Winter ones. ![]() (click)
__________________
Life starts every day anew. Prospects not so good... Last edited by Japo; 24-09-2010 at 10:46 PM. |
||
![]() ![]() |
|
![]() |
#2 | ||
![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Mar 2006
Location: ,
Posts: 4,613
|
![]() Something more useful today. My preferred programming framework is .NET, and my preferred language C#. With .NET it's very easy to take do multi-threading, so you can perform tasks in parallel, taking advantage of modern CPUs; and most important, so your user interface doesn't stop responding whenever you have to perform a task that takes some time, instead you can perform it in the background while the UI thread goes on in parallel.
Even though the .NET class library does most of the work, I made a little library to take care of some common tasks when multi-threading and cross-threading, I called it "xThreading". First it has a simple extension method to make thread-safe calls to Controls (actually any ISynchronizeInvoke) as detailed here. The arguments it takes are a delegate to the method that you want to run in the Control's thread, and the parameters, if any. (I provided an overload for the frequent case when the method has no parameters nor return value--is a System.Action delegate--because just "Delegate" isn't strongly typed (System.Delegate is abstract) and you'd need an instantiated delegate every time you used this, but the compiler can't infer it because Delegate is abstract. You could make additional overloads for other recurrent situations.) Code:
using System; using System.ComponentModel; namespace SEADM.xThreading { public static class xExtensions { public static object xInvoke(this ISynchronizeInvoke thread, Delegate method, params object[] args) { if(args.Length == 0) args = null; // if the Delegate takes no arguments // we must pass null to ISynchronizeInvoke.Invoke() or Delegate.DynamicInvoke(), // not an empty array. if(thread.InvokeRequired) return thread.Invoke(method, args); else return method.DynamicInvoke(args); } // Handy overload: public static void xInvoke(this ISynchronizeInvoke thread, Action method) { xInvoke(thread, method, null); } } } Code:
frm.xInvoke( () => frm.Close() ); Code:
frm.xInvoke( () => { frm.lbl.Text = "Done! :)"; frm.btn.Enabled = true; // etc... } );
__________________
Life starts every day anew. Prospects not so good... Last edited by Japo; 05-01-2011 at 06:38 PM. Reason: added overload |
||
![]() ![]() |
|
![]() |
#3 | ||
![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Mar 2006
Location: ,
Posts: 4,613
|
![]() So what I wanted at this point, were classes that presented the same properties and methods as the different Controls. I want them to reference cross-thread Controls, and when anyone calls their members as if they were the Controls themselves, under the hood they'll be using xInvoke() to make the calls in a thread-safe way.
For example, having created one of these objects referencing our Form, Code:
xfrm = new xForm(frm); Quote:
Of course I haven't implemented all the functionality of Windows Forms in the corresponding xControls; actually I have defined very little classes with very little members, whatever I have needed myself so far. For example: Code:
using System.Windows.Forms; namespace SEADM.xThreading { public class xForm:xISynchronizeInvoke<Form> { public xForm(Form reference) :base(reference) { } public void Close() { methodCall("Close"); } } public class xLabel:xISynchronizeInvoke<Label> { public xLabel(Label reference) :base(reference) { } public string Text { get { return (string)propertyGet("Text"); } set { propertySet("Text", value); } } } } Here goes xISynchronizeInvoke<T>, be warned, lots of reflection going on: Code:
using System; using System.ComponentModel; namespace SEADM.xThreading { public abstract class xISynchronizeInvoke<T> where T :ISynchronizeInvoke { private ISynchronizeInvoke xThis; protected xISynchronizeInvoke(T reference) { xThis = reference; } protected object methodCall(string methodName, params object[] arguments) { return xThis.xInvoke(new Func<object>( () => { return xThis.GetType().GetMethod(methodName).Invoke(xThis, arguments); } )); } protected object propertyGet(string propertyName) { return xThis.xInvoke(new Func<object>( () => { return xThis.GetType().GetProperty(propertyName).GetValue(xThis, null); } )); } protected void propertySet(string propertyName, object value) { xThis.xInvoke( () => xThis.GetType().GetProperty(propertyName).SetValue(xThis, value, null) ); } } }
__________________
Life starts every day anew. Prospects not so good... Last edited by Japo; 05-01-2011 at 06:27 PM. |
||
![]() ![]() |
|
![]() |
#4 | ||
![]() ![]() ![]() ![]() ![]() ![]() ![]() Join Date: Mar 2006
Location: ,
Posts: 4,613
|
![]() And then I wanted another thing--actually this was the first one I wanted to make, and what got me into authoring the rest, that this is built onto. I wanted a splash window to show while a parallel task is carried out in the background, but I wanted the background task to be able to show its status in the splash screen.
Here it is. The constructor takes a delegate to the action you want to perform in parallel, and just creating the splash window starts the task immediately. You won't even need to keep a reference to the window most times, as it closes itself down when the task is done; so even this minimal statement works: Code:
new xSplash(method); The class doesn't provide for returning values from the Task (an System.Action<> returns void), passing parameters to it, or cancelling it from the main thread, simply because I haven't needed it; although it wouldn't be hard to add that. By the way, if a parallel thread throws an exception, it doesn't reach the main thread immediately. But with xSplash, every time you click on it, it will check the task for exceptions, and if there's any it will be thrown back into the main thread; if there's none, nothing will happen. (I guess if the user sees that the task is taking too long and the splash window remains there forever without reporting any change of status, he will instinctively click on it.) Here's the code: Code:
using System.Windows.Forms; using System.Threading.Tasks; namespace SEADM.xThreading { public class xSplash:Form { Task guest; Label lbl; public xSplash(Action<xLabel> method) { InitializeComponent(); var frmSplash = new xForm(this); var lblSplash = new xLabel(lbl); guest = Task.Factory.StartNew( () => { method(lblSplash); frmSplash.Close(); } ); MouseDown += frm_Click; lbl.MouseDown += frm_Click; Show(); } void frm_Click(object sender, MouseEventArgs e) { if(guest.IsFaulted) throw guest.Exception; // don't use Task.Wait() instead, in case // the splash is clicked before guest is through. } } } There's actually more code of course (InitializeComponent() etc.), what was written automatically with the Visual Studio designer, including non default values for some properties, to make the splash window look the way I wanted--even though it's really nothing fancy and has no graphics etc. I used dynamic layout (everyone should), so the label and the window resize automatically according to the text, depending of the system font size etc. Also you shouldn't let the user close the window, in principle, otherwise when the task is finished and it tries to close it again, you'll get an exception--and without the splash you won't have any way to retrieve it.
__________________
Life starts every day anew. Prospects not so good... Last edited by Japo; 05-01-2011 at 06:34 PM. |
||
![]() ![]() |
|
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Japo's status report | Japo | Introductions, Farewells and Returns | 30 | 05-10-2012 08:14 PM |
Code Share | Burger Meister | Programming | 5 | 10-02-2009 07:22 AM |
Somebody Who Knows Php Code? | andy_blah | Blah, blah, blah... | 14 | 11-06-2006 03:11 AM |
Need The Code.... | TalonStriker | Troubleshooting | 1 | 14-04-2006 07:21 PM |
|
|
||
  |