Tag Archives: Geometry

Tutorial

Distance...

Mathematica is perfect for working with lists and matrices.  Essentially making it useful for defining and manipulating geometry through rotations and later on analysing the forces through stiffness methods.

A key task when working with series of co-ordinates is to check that the relative distances between points don't change so that the structural elements in between remain the same, even though the structure may have changed position and shape.  When you're working with Mathematica and there's a task that you need to do repeatedly it's often worth creating a custom function that can be called whenever needed.

A couple of the functions that I've written can determine the distance between each co-ordinate in a list for 2D and 3D co-ordinate lists.

First, create some co-ordinates to work with on the examples.

Now that we've got some points to work with we can create a function to determine the distance between the points in 2D.  On 2D points, Mathematica has an inbuilt function called  EuclideanDistance[] which is nice and fast when determining the distance between 2D points.

There are two key parts to the function, the first part maps a list of points across the   EuclideanDistance[] function, with the second section essentially iterating the co-ordinates to restructure the list so that the function can be mapped across the list by rearranging it in a  (First point, Second point)(Second point, Third point) format.... until the last element in the list.

This is nice and zippy for 2D co-ordinates, but won't work unfortunately for 3D and needs modifying to make use of the inbuilt function  Norm[] .

Running a comparison on speed for how 2D points are handled can be compared by zeroing out the Z ordinate.

As can be seen, EuclideanDistance[] is faster, but Norm[] is more flexible and can be used on 2D and 3D co-ordinates.

Tutorial

Lists...

One of the things that I spend a lot of time doing in Mathematica is creating lists of co-ordinates so that I can export them into structural analysis software, either before or after I've rotated and transformed them through space to mimic a deployable structure.

Most of these methods I've picked up along the way through trawling Stack Exchange which I find a great resource for learning Mathematica, I'm not able to link to all of them as I've hoovered them up into a notebook over a long period of time and not kept all of the original links...

Creating lists.

Frequently I'll create a list of x co-ordinates, then y co-ordinates, then the z co-ordinates.  There are a multitude of ways to do this, a few of the ways to create a list of co-ordinates are linked below:

Other ways of creating lists, could make use of functions.

{0, 2, 4, 6, 8, 10}

{1, 4, 9, 16, 25}

Creating points

And there are dozens of other methods that are available, but once you have your list of x, y, and z co-0rdinates then the next step is to combine them.  You could certainly type them in long hand as below, but the more nodes you have the longer it takes.

You could automate a simple list of co-ordinates like above in a couple of ways:

or

Both return the same list of co-ordinates:

{{0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, {4, 0, 0}, {5, 0, 0}}

Combining lists.

Or you might have created a list of points, the same as the lists x,y, and z at the top of this post and now want to combine them...

Thread[ ] is available and is one of the quicker methods for knitting together lists.

{{0, 10, 0}, {1, 11, 1}, {2, 12, 2}, {3, 13, 3}, {4, 14, 4}, {5, 15, 5}, {6, 16, 6}}

or

both return.

{{0, 10, 0}, {1, 11, 1}, {2, 12, 2}, {3, 13, 3}, {4, 14, 4}, {5, 15, 5}, {6, 16, 6}}

Transpose.

Transpose[ ]   can be used for nice tidy syntax

Inner.

If there is a simple 2D set of co-ordinates, then these can be combined using  Inner[ ]

Riffle.

Again for simple 2D lists, the function  Riffle[ ] can be used, but needs to be used in combination with  Partition[ ]

If you're working with multiple lists, then a function called multiRiffle can be written, taken from here.

Gives

{{0, 10, 0}, {1, 11, 1}, {2, 12, 2}, {3, 13, 3}, {4, 14, 4}, {5, 15, 5}, {6, 16, 6}}

Custom functions.

If you only have 2D data points then a function could be written to knit them together, these functions can check to see if the lists are of the same length too which can be beneficial.

{{0, 10}, {1, 11}, {2, 12}, {3, 13}, {4, 14}, {5, 15}, {6, 16}}

Which can be adapted for 3D data points easily enough.

{{0, 10, 0}, {1, 11, 1}, {2, 12, 2}, {3, 13, 3}, {4, 14, 4}, {5, 15, 5}, {6, 16, 6}}

Hopefully this will help someone who's learning Mathematica who's going to be working with data points and co-ordinates a lot.  It seems to be a topic that gets asked a lot on Mathematica Stack Exchange so I thought it would be helpful to try and summarise up in one post.

Dynamic Arches...

Tinkering about with SystemModeler a little further, I've managed to finally build a sprung arch, complete with dampers on the revolute joints.  I'm intending on using this principle in my research to create folded structures, so it's interesting to see what effect the spring stiffness will have on the behaviour of the arch during the unpacking process - specifically looking at the accelerations on the masses at key points.

The thing that I was struggling with was creating a structure that had a set of equations that could be solved, the key concept I was initially missing was the closing of the structure with the special type of revolute joint to complete the chain.  Without this special revolute chain the equations are essentially unsolvable, so it's important that one of these joints sits in the system somewhere.

Another concept is that the structure in the video has 3 straight segments, each 1m long; but the supports are only 2m apart.... forcing the arch to pop into a stable shape that balances the weights at each of the joints.  This is essentially what makes the arch wobble when solving the initial set of equations.  Next step is applying external forces and measurement points along the structure for displacement etc...

Tutorial

Rotations...

In a previous post I showed how complex numbers are useful when rotating co-ordinates and since then I've hard coded several geometrical translation and rotation routines that have been crude, but functional in Mathematica.  Nothing too complex, but a nice little achievement, working with matrices and manipulations.

But the scary thing about a big program like Mathematica, is that it has lots of built in functions that whilst incredibly well documented, you have to be aware that they exist before you can start to search for them.

The transformation matrices scripted above, can be automated using some of the inbuilt functions in Mathematica 9.  So for example if I wanted to rotate some co-ordinates about the z-axis the syntax is quite straightforward and can be taken from the documentation.  Rotating 4 co-ordinates (a) around the z axis (b) to give the newly updated co-ordinates (c).

There are quite a few neat and compact examples over on the documentation website if you're interested.

I personally struggle with Mathematica at times, not because the documentation is poor, but because the scope is so vast.  But with helpful sites such as Stack Exchange or the Wolfram Community Page I'm sure I'll start to work my way through some of the more hardcore functions given time.

Tutorial

Rotating points...

Part of the Mathematica scripts that I've been writing require the generation of curved geometries and I've been spending a bit of time to work through different ways of achieving this.  My initial solutions were quite straightforward and made use of polar co-ordinates to create an array of points, which were then converted to cartesian co-ordinates at the end to make their inclusion in the analysis scripts a little easier.

Another way to do it makes use of complex numbers, but I haven't studied complex numbers for over 20 years and if I'm brutally honest I always struggled to work out what on earth they were really used for in the real world.  I've been through a few texts but the practical applications have always been glossed over.  One line of texts that I've found helpful for rediscovering lost maths skills, specifically for generating geometry, are mathematics books aimed at computer scientists rather than engineers (Vince, 2010).

So what's a complex number?  Essentially a complex number has a real part and an imaginary part and this was the part I used to struggle with as a maths student because I could never understand what use in the real world an imaginary thing could be.  If we could make an imaginary part useful then we could harness the power of unicorns and dragons surely?  This is where Vince (2010) has helped me decipher how complex numbers can be useful as the principles are used in geometry to rotate a point around another point.

And to convert from a simple cartesian co-0rdinate into an equivalent complex number representation is quite straightforward too, you just use the relationship below.

The key concept to understand is that a cartesian co-ordinate can easily be converted to an equivalent complex number and to rotate this new co-ordinate by 90 degrees anti-clockwise you multiply this new complex number by i.  If you want to rotate by a further 90 degrees, then multiply this again by i.  One important thing to remember when going through this series of operations though is that i² can be simplified.

Example.

So for example if we wanted to take the co-ordinate at point A and rotate it through 90 degrees, we simply multiply the point by i, then simplify and we'll get the new co-ordinate for point B.  Here's the worked example for anyone that wants to follow along at home.

Rotate by 90 degrees, therefore multipy by i.

i² can be simplified to - 1 though

Becoming

Once you've followed the working above, why not have a go at rotating B through 90 degrees to get to point C, then again to get point D and then again to get back to point A?  Essentially multiplying the co-ordinates by i rotates the point 90 degrees in an anti-clockwise direction.

If you wanted to boil this down to a single expression to allow a programme to be coded this can be done quite easily and the expression is as set out below with the angle expressed in terms of degrees.  This expression, takes an existing point (x,y) and rotates it by an angle θ to get the new co-ordinate (x',y')

Mathematica sample code.

Now we have this simplified expression, let's see how hard it is write a little bit of code to calculate the angle for us using complex numbers.  I don't pretend for a second this code is either elegant or efficient, but for new programmers I think it should be fairly easy to follow.  First we define a variable called coords to input a cartesian co-ordinate, this has to be in between curly brackets.

{-19.94, 392.11}

Next the angle that you wish to rotate between has to be defined, I've assigned this to a variable called angleRot for this example.  This angle has been entered in degrees.

{-49.45}

The next stage applies the equation above for imaginary numbers on the first line of code, with the second line extracting the Real component using the Re[ ] function for the X co-ordinate, and the imaginary component using the Im[ ] function for the Y co-ordinate.

{284.977, 270.066}

This gives the new position based on the co-ordinate being rotated by an angle around the origin (0,0).

Rotate a point around another specified point.

It's just as straightforward to rotate a point around an arbitrary point rather than the origin it just requires an additional step that moves the co-ordinate back to the origin, then after the rotation has been completed the point is shifted back again by the same amount.

Enter co-ordinates as cartesian.

{3, 2}

Confirm the angle by which you want to rotate the co-ordinate by degrees. All angles are measured positive from 3 o'clock in the anticlockwise direction as per complex numbers standard.

{90}

Now you need to declare the point which you intend to rotate around.

{2, 1}

Before the rotate can begin you need to determine the distance between the origin and the rotate point, this will be the distance you have to translate the point being moved around before the rotation starts.

{-2, -1}

{1, 1}

The final step is to rotate the point around the origin and then move it back by the same amount that it was translated by before rotating.

{1, 2}

References.

Vince, J. (2010). Mathematics for Computer Graphics (Third ed.). London: Springer.

Cable-Chains...

Part of the work that I've been undertaking on Mathematica is to create a series of sheets that will calculate the geometry of a cable-chain arch with a set of given parameters.  In part I’m interested in how the cable-chain arch can behave as a deployable structure and looking to build on the work of (Li, Vu, & Richard, 2011) to see how practical a cable-chain structure can be made with regards economy, efficiency, and robustness.  Essentially a cable-chain structure is a curved arch that is sub-divided into straight sections, with cables spanning across the base of two struts as can be seen in the figure below.  Simple versions of these types of structures are widely used for the likes of temporary and deployable aircraft hangers to create large open spans.

Now that I’ve got the makings of a simple Mathematica sheet up and running and I’ve taught myself some rudimentary programming and graphics manipulation skills I’ve managed to start to knock together what I feel are some high quality illustrations for my thesis.

I’ve done this with a mixture of Mathematica to create the base diagram, which I save as a PDF.  I then import the PDF into OmniGraffle to annotate the diagram and then export to a PNG file to maintain the transparent background, this figure I can then host for linking into blogs etc.  Below is a sample figure which shows how the number of segments (nSeg) affects the internal area available for habitation within a typical parabolic arch.

Given that both of my brothers are colour blind and I’ve never done the test, I’m not convinced on my choice of colour schemes, but the good news is that it won’t take long to change if it turns out I’ve made my figures look like something off the set of Austin Powers.

So far I’m finding OmniGraffle quite limited compared to Visio that I’ve been using for my diagrams for perhaps 20 years or so.  I decided to use OmniGraffle though as most of my writing work is done on a Mac, although I also have a PC so I can always create the more complex diagrams on Visio if need be, especially as I’ve managed to get a legitimate copy from work for £12.

I'd love to hear how other engineers and academics approach creating technical figures and sketches on their Macs though, I've a feeling that I'm really missing out on something and there's got to be a much slicker workflow out there.

References:

Li, Y., Vu, K. K., & Richard, J. Y. (2011). Deployable Cable-Chain Structures: Morphology, Structural Response And Robustness Study. Journal for the International Association for Shell and Spatial Structures, 52(168), 83-96.

Kriss Kross...

I've been really busy with various things associated with my new house lately and not really had much time to tinker and meddle with Mathematica or my PhD.  One of the key elements that I need to investigate is to calculate the internal area of a polygon where cables cross...  This will vary, depending on how many internal cables that I have and so I need a quick way of finding out the internal area for lots of different permutations.

This is a simple polygon problem which can be easily calculated once you know the cartesian co-ordinates for each of the key points using the following equation which is presented for the general condition.  It's not a hard calculation, as really it's just triangles, but it is a tedious calculation, which means it's perfect for Mathematica or Excel.

However, the tricky part comes from determining where the cables actually cross over as that is where the cartesian co-ordinates will come from that are needed to determine the areas.  The calculation of the co-ordinates can be done a few different ways, but I've decided to solve the problem through using some vector based geometry, consider the simple condition below which is just for two lines that cross, how do we find the point where the lines intersect?

You could describe the two lines in the general term of y=mx+c, but this isn't what I want to do within Mathematica as I want to automate this for a wide range of values and lines and so iterative geometry using vectors is likely to be far more beneficial.  Representing these two lines in vector format using cartesian co-ordinates gives:

Now we know the equations in vector format it becomes possible to solve both of these equations to determine λ and μ which when back substituted into either equation will give us the co-ordinate for the intersection point p5 in (x,y) format.

This isn't that difficult to do by hand, but requires a bit of vector manipulation to expand the brackets and given my low attention span I would inevitably get it wrong after a few run throughs, but in Mathematica the problem gets much more simple, so for the example below we'll assume that the four co-ordinates are at 4m away from the origin (0,0) that is point p1.

{p1, p2, p3, p4} := {{0, 0}, {4, 4}, {0, 4}, {4, 0}};

Solve[{(1 - λ) p1 + λ*p2 == (1 - μ) p3 + μ*p4}, {λ, μ}, Reals];

p5 = Flatten[(1 - λ) p1 + λ*p2 /. %]

Executing this codes gives the intersection as being at point (2,2) in a fraction of a second, which is where you would expect it to be.  Now to explain the three lines of code and what they do, I'm sure a more experienced user could make this code much neater but doing it this way makes sense to my tiny brain.

The first line simply sets the variables p1-p4 with their corresponding cartesian co-ordinate position, giving the point two in the top right corner 4m up and 4m across, p3 is along the bottom 4m away, p4 is straight up in the top left corner 4m above point p1, as shown in the figure below.

The second line then solves the two vector equations of the lines for λ and μ and makes sure that they are real numbers, rather than imaginary.  The real part probably isn't necessary, but it's just a force of habit that I put this in when using the solver as a just incase.

The final line substitutes the λ value back into the equation and then stores this as variable p5 so that I can use this in up and coming calculations, this was the fiddly part for me and makes use of the strange /. % input that allows the equation to effectively go back and substitute the solutions from the Solve command into the equation specified and recalculate and because my equation has the λ within it Mathematica knows this is what I want substituting in even without me being explicit.   I spent ages trying to work out this final stage, but now I've cracked it as a principle I can start to roll it out on the other sheets that I've been working on and this was the reason for writing this post incase it too helps someone else.  Now I can directly write the solution outputs from Solve, FindRoot, and NSolve and then carry on using these within my calculations rather than having to manually type them in.

This process lets me know that the intersection point is at (2,2) and now I know that the process works I can start to extrapolate this algebraically for the general conditions and start to calculate the areas of my polygons.

All of the figures in this post have been written using OmniGraffle, which I'm slowly getting to grips with, I can't make it dance as well as I can Visio, but I think it will help create some nice looking diagrams for my thesis once I get more proficient with it.

Arc...

Following on from my last post where I was investigating how to determine the parabolic equation when only provided with three co-ordinates, I wanted to extend that knowledge and create a Mathematica sheet to allow me to do this without having to rely on Wolfram Alpha.  This is for two reasons, firstly if I don't have an internet connection, then I'm screwed as Wolfram Alpha isn't going to work for me... secondly I need to encourage a deeper understanding of the procedure and process if I'm going to get the most from Mathematica.

The first part is trying to determine the parabolic equation when I know three points on the curve, typically these are going to be the start, midpoint, and the end support point.  To give an appreciation of the geometry, it's important to firstly understand that parabolic curves are defined by the common equation:

Determining the length of a parabola with cartesian co-ordinates is done through applying the equation below over the limits being considered.

As three co-ordinates are known along the curve, the equations can be expressed as follows, with (x1,y1) (x2,y2) (x3,y3) being taken as the co-ordinate points... this gives a nest of simultaneous equations that can be solved using traditional matrix methods or in this case elimination could be used given that one of the input variables is 0.

Taking the co-ordinates above as (0,500) (2050,0) (4100,500) for the input variables, this gives the simultaneous equations below to solve:-

However, Mathematica is well equipped for solving simultaneous equations and simply requires that the expressions are stacked up neatly and logically.... there can be a few problems with mixing bracket types, but this is just down to practice.  To solve the simultaneous equations above, the following code will solve them, the double equals signs are used just to push up the accuracy of the expressions and Reals is used as an additional parameter just incase any of the solutions are imaginary numbers.

Solve[{a x1^2 + b x1 + c == y1, a x2^2 + b x2 + c == y2, a x3^2 + b x3 + c == y3}, {a, b, c}, Reals]

Which will return the following solution:-

Substituting this back into the general expression determines the parabolic equation for this particular curve to be...

The last thing to do is to work out the length of the curve between the two support points, this is a simple process determined by:-

For those of us with too little time on our hands, this calculation can easily be automated and defined within Mathematica using the following code, where f'[x] is used to differentiate the term within the brackets.

f[x_]:=500 - (20 x)/41 + x^2/8405;

NIntegrate[Sqrt[1 + (f'[x])^2], {x, 0, 4100}]

Which gives the length of the cable to be  4,257.24m  which matches Wolfram Alpha's answer perfectly... the next step is defining equal length links to segment this curve to start creating the geometry for parabolic cable-chain structures... that's definitely a post for another day.

The intention with this post is to help anyone who is trying to define parabolas and arc lengths using Mathematica... or traditional methods, if they've got time on their hands...

General

Geometry...

I've posted a few times that I feel my mathematics skills have slowly atrophied having been out in industry and that this I feel will be my achilles heel when it comes through to my research.  One of the areas that I've been investigating is the relationship between cable-chain structures and their behaviour.

Depending on how many segments you divide the arc into will determine the geometry and efficiency of the cable-chain arch, now if it's a semi-circle that's not too hard to calculate the geometry using simple triangles.  In degrees the internal angle of each triangle will be given by the following formula, where nseg is the number of segments you're dividing the arc by:-

This then can allow you to calculate the length of the segment along the arc as set out below using the Cosine rule which I haven't used for probably about 20 years, this though is only half the problem as you still have to determine the length of the cables.

Next to determine the length of the cable, you will need to combine two of the triangles previously calculated and which gives double the internal angle and repeat the process for the cable that is shown highlighted in red below.

This all seems fine and well for simple circles, but how would you know that a semi-circle gives the most efficient arrangement for a cable-chain?  What about if it's a parabola?  Well fortunately for the mathematically out of practice determining the equation for a parabolic curve is pretty easy for us Mathematica users...  Let's say I know I have a draped cable that spans 4100m horizontally between supports and has a 500m drape at the middle.  We can define three points on this cable easy enough as can be seen below:

This is where Mathematica starts to flex its muscles for me and why I feel I get good value from the student version that I've purchased.  I don't know what the Mathematica code for determining a line through the points is, but if I press the = key twice I get access to the Wolfram Alpha Servers and try and describe using every day English what it is that I'm trying to do...  Following a blog post from Mathematica on determining arc lengths using calculus I tried the following term which doesn't use any mathematical code at all, simply describes what it is that I'm trying to do:-

Parabola through the points (0,500), (2050,0), (4100,500)

Which gives the me the following output, which is pretty helpful to the maths novice who is trying to explore and understand the relationship between the data, the expression, and the graph...

Which makes my life a lot easier as I can start to tinker with geometry very quickly now using this approach.  One of the cool things about working this way is that you can then start to dissect the code and determine what the correct format should be when creating Mathematica sheets and it makes learning Mathematica much much easier than say MatLab or Maple.

Whilst creating code like this would not be difficult for someone with a little rudimentary programming experience, it isn't that intuitive for a newb like myself, but now I can start to adapt this syntax to suit what I need...  The next step is to try and work out how to subdivide this into nseg number of equal length links... but that's a job for another day.  Maybe I'll need to start using polar geometry to make my life easier? Who knows... but at least I'm not being held to ransom by my elderly fuzzled brain anymore and I can explore and play with the maths rather than being pummelled by them.

I'd love to hear from other Mathematica users, especially to hear what their experiences are and particularly to hear if I'm missing a trick as I'm going through and learning the syntax...