Geometry 7/16/2015

Inverse kinematics today.

So here’s another random geometrical situation that caught my attention while I had some downtime at work today.

Imagine we have two monitors that we would like to pivot so that they always stay in contact; however, we don’t want to install and ugly hinge along the front surfaces so we build an arm attachment in the back.  Of course, it can’t be one arm because that doesn’t physically work, but two arms hinged to each other and to the monitors will.  This raises interesting questions about how the arms need to move together to pivot the screens, especially if we would like the system to be automatically driven and move at an even and smooth speed.

2015-07-16-17.25.10

I haven’t yet figured out all the equations and differentials that govern the relative movements of the arms, but some quick thought on the ideal case can get us in the right direction.  Imagining a perfectly equilateral triangle setup, and also ignoring the thickness of the screens, we see that every 3° rotated by the screen requires a 1° rotation on each internal angle of the hinges.  Twisting each hinge at a fixed speed will result in the screen pivoting at 3 times that speed.

Of course, this becomes less true as the arm lengths vary: an armature with a √2 ratio with the short arm being the length of the distance between the two screen hinges (starts off in a 90°, 45°, 45° triangle) will not be able to rotate the screens to a full 90°.  But to get to a 45° angle, must rotate ~27.0°, ~4.4°, ~22.3° respectively.

Or, think of an armature that can just get to a 90° screen rotation by having a long arm that is the distance between the two screen hinges and a short arm that is 1/√2 times that.  It starts off in a ~69.3°, ~69.3°, ~41.4° triangle, rotating ~24.3°, ~24.3°, 41.4° respectively.

Of course, the correct way to do this is clearly just to build the darn setup, manually rotate the screens, have sensors record the movement, and then feed those movement curves back into the motors.

Reflection on Werewolf

I’ve played Mafia, a lot of Mafia, and some of my thoughts are probably anchored based on how those experiences went.  Nevertheless, I wanted to comment on something that stood out to me the most on my first game of Werewolf played on 1/30/2015:

We let every villager have a role. While letting every villager have a role was a nice way to give everyone something to do, I didn’t like it from a game design perspective. Having too many clear roles upset the fuzziness in identity that makes this type of game confusingly compelling.

For example, say there is one werewolf and two villagers left:

If those two villagers had specific roles, say bodyguard and seer, then in that case, the werewolf must claim to be one or the other. However, the person with that card would know that is a lie and it would simply come down to a shouting match between the two.

If on the other hand, those two villagers roles were just “villager,” then the werewolf could claim to be a villager. In that case, both real villagers only know that they themselves are one of two villagers, and could be played against each other by the werewolf claiming to be the second villager.

In the first case, the onus is entirely on the werewolf to process all the information, make an optimal choice, and then try to be the loudest.  In the second case, the werewolf has the choice to be more deceptive, and play both villagers against each other, creating flexibility.

When my group played with too many roles last night, then, it was simply a process of elimination and matching up individual roles with people, which made it easy to solve the game. I found it difficult as a werewolf to pretend to be “part of the crowd” as there was no generic “crowd” to be a part of. Instead the game was about knowing the ideal next steps.

My recommendation would be to play with more regular villager cards but give them artifacts if they want to have unique powers. Having duplicates makes it more difficult to determine who people are and creates more confusion, politics, and intrigue, which is what I believe is the essence of these types of games.

On the Wonders of IFERROR()

If you’re spreadsheet is meant to be looked at by other people, you should just about nest everything in an IFERROR([formula],).  The nothing after the comma means that in the case that your formula throws an error (#VALUE, #N/A, #REF!, et cetera), nothing shows up in the cell.  No distracting error text.

Now, this doesn’t mean you shouldn’t debug your formulas first, but if there are normal cases where they might throw some of these errors, IFERROR() is invaluable.  (e.g. I have a dynamically updating query list and I know that sometimes the query will return nothing).

On the Quirks of INDEX()

I’ve been working on a self-updating bi-weekly deliverables calendar / dashboard in Google Spreadsheets for my office the past few days.  Our Traffic Manager can simply add projects and their various deliverables to other sheets which serve as databases. Then another sheet, which one of our animator a painstakingly organized for aesthetics, will search those databases to pull deliveries to their correct dates and color-coding based on other information associated with those projects.  This sheet updates itself based on the current day and week.

Recently, a switch I made from INDEX(FILTER(SORT(…))) to INDEX(QUERY(…)) for minimization purposes resulted in some peculiar behavior.

But first a preface as to why I am using INDEX for array formulas that are perfectly capable of expanding themselves down multiple rows.  Our animator has used the spreadsheet as a grid to help align elements, merging some cells and leaving some as borders.  This means that the cells no longer behave like a sequential spreadsheet.  For example, merged cells behave as only their top left cell.  Net result is that I need to write a specific formula for each identified locus of data.  Somewhat more time-consuming but not un-doable.

Anyway, so I was using INDEX() to return whole rows from my QUERY() via INDEX(QUERY([array], “select Col[#],Col[#] where …”),1).  This worked fine when the QUERY() pulled more than one row; however, when the QUERY() only pulled a single row, INDEX() only pulled the first entry where I wanted the whole first row, and where it would have pulled the non-existent second r0w, it pulled the single entry from the second column.

I cannot confirm my suspicion, but I surmise that QUERY(), as written by the programmer returns a one dimensional array when there is only one row of results and a two dimensional array when there are more.  This inconsistency means that INDEX(), when passed only a single number, pulls that index from an array, resulting in a single element from a one-dimensional array, and a whole row (or sub-array) in a two-dimensional array.

Unfortunately, to a naive user on the front-end who expects that number of their INDEX() function to always refer to a row, this is confusing and un-beneficial. I have not figured out how to solve this problem yet, and instead have broken up my QUERY() to multiple ones that only query single columns, thus guaranteeing that the dimensions of returned arrays are always 1xN.  It has maximized rather than minimized my formulas, but is more robust for the time being.

Chinese Practice 1/14/2014

I’m pretty good at English, and I know enough about Chinese to put together the meanings even if I have to look up every character, so translation and localization can be fun.

Songs are also fun, so below is a random song I’ve translated. I’ve tried to stay literal where possible, but where a Chinese turn-of-phrase just doesn’t match up to an English expression/cultural image, I’ve taken some liberties to capture the meaning. I’ve also tried to match syllables where possible to make it sing-able in English.

凡人
李宗盛

你我皆凡人,生在人世間
終日奔波苦,一刻不得閑
既然不是仙,難免有雜念
道義放兩旁,利字擺中間

多少男子漢,一怒為紅顏
多少同林鳥,已成分飛燕
人生何其短,何必苦苦戀
愛人不見了,向誰去和喊冤

問你何時曾看見 / 這世界為了人們改變
有了夢寐以求的容顏 / 是否就算是擁有春天

 

We are ordinary people, born in this earthly world
Rushing about all day, without a moment’s rest
We are not immortals, can’t avoid impure thoughts
Cast your morals aside, for your selfish ways

How many bright young men, chase pretty women
How many young love birds, have now flown separate ways
Life is far too short, for the pain of love
When my lover walks away, to whom can I cry?

Have you ever once seen / the world change for anyone?
If you yearn day and night for your dreams / will you really ever find happiness?

Geometry 1/13/2014

Something that I’ve been trying to figure out what to do with is my affinity for random geometric problems (e.g. staring at a half-covered design on a random pizza box and realizing that the lines of the “pizza slices” do not intersect at the center of the arc in which they lie).

Today, I was pondering over the toroidal map type in Civilization. The game still plays on a planar rectangular projection of the map, but how much distortion should there really be?

I’m going to assume that the width of the map is the maximum latitudinal circumference around the outside, and therefore I am interested in how much narrower the “poles” should really be to meet each other on the inside of the torus.

My initial condition therefore is that [map width] = 2 * pi * ([major radius] + [minor radius]) and that [map height] = 2 * pi * [minor radius].

I am interested in the minimum latitudinal circumference, described by 2 * pi * ([major radius] – [minor radius]).

After some very basic algebra, the conclusion is that the poles should be only as wide as [map width] – 2 * [map height], a significant result! The distortion is quite severe for maps of appreciable height!

If a toroidal Civ map was twice as wide as it was tall, the poles would all still come to a single point, which is not much actual space for units and cities placed up there. Though, if we had to play on Civ maps where distance was physically accurate given the 3D shape of the world, it’d probably be even more confusing to keep track of.

scan_01142014

A not actually very informative scan from my scribbles