How do I apply a list of translations to the same object? - openscad

imagine I have a list of translations which I want to apply to the same object.
for instance, a list which defines rotation and translation
list = [[10,20],[30,45]]
how to I apply them in a for loop to one object?
I am looking for something like
for (i=list) {
translate([i[0],0,0])
rotate([i[1],0,0])
}
cube([10,1,1]);
obviously, that is the wrong approach...
any ideas?

This could be done by defining a module that steps through the list recursively.
list = [[10,20],[30,45]];
module transform(list, idx = 0) {
if (idx >= len(list)) {
children();
} else {
translate([list[idx][0],0,0])
rotate([list[idx][1],0,0])
transform(list, idx + 1)
children();
}
}
transform(list) cube([10,1,1]);

Related

Backtracking results in same repeating course

I am trying to solve a puzzle, and it has been suggested that I use backtracking - I did not know the term so did some investigation, and found the following in Wikipedia:
In order to apply backtracking to a specific class of problems, one must provide the data P for the particular instance of the problem that is to be solved, and six procedural parameters, root, reject, accept, first, next, and output. These procedures should take the instance data P as a parameter and should do the following:
root(P): return the partial candidate at the root of the search tree.
reject(P,c): return true only if the partial candidate c is not worth completing.
accept(P,c): return true if c is a solution of P, and false otherwise.
first(P,c): generate the first extension of candidate c.
next(P,s): generate the next alternative extension of a candidate, after the extension s.
output(P,c): use the solution c of P, as appropriate to the application.
The backtracking algorithm reduces the problem to the call backtrack(root(P)), where backtrack is the following recursive procedure:
procedure backtrack(c) is
if reject(P, c) then return
if accept(P, c) then output(P, c)
s ← first(P, c)
while s ≠ NULL do
backtrack(s)
s ← next(P, s)
I have attempted to use this method for my solution, but after the method finds a rejected candidate it just starts again and finds the same route, rather than the next possible one.
I now don't think I have used the next(P,s) correctly, because I don't really understand the wording 'after the extension s'.
I've tried 2 methods:
(a) in the first() function, generating all possible extensions, storing them in a list, then using the first. The next() function then uses the other extensions from the list in turn. But this maybe can't work because of the calls to backtrack() in between the calls to next().
(b) adding a counter to the data (i.e. the class that includes all the grid info) and incrementing this for each call of next(). But can't work out where to reset this counter to zero.
Here's the relevant bit of code for method (a):
private PotentialSolution tryFirstTrack(PotentialSolution ps)
{
possibleTracks = new List<PotentialSolution>();
for (Track trytrack = Track.Empty + 1; trytrack < Track.MaxVal; trytrack++)
{
if (validMove(ps.nextSide, trytrack))
{
ps.SetCell(trytrack);
possibleTracks.Add(ps);
}
}
return tryNextTrack(ps);
}
private PotentialSolution tryNextTrack(PotentialSolution ps)
{
if (possibleTracks.Count == 0)
{
ps.SetCell(Track.Empty);
return null;
}
ps = possibleTracks.First();
// don't use same one again
possibleTracks.Remove(ps);
return ps;
}
private bool backtrackTracks(PotentialSolution ps)
{
if (canExit)
{
return true;
}
if (checkOccupiedCells(ps))
{
ps = tryFirstTrack(ps);
while (ps != null)
{
// 'testCells' is a copy of the grid for use with graphics - no need to include graphics in the backtrack stack
testCells[ps.h, ps.w].DrawTrack(g, ps.GetCell());
if (ps.TestForExit(endColumn, ref canExit) != Track.MaxVal)
{
drawRowColTotals(ps);
return true;
}
ps.nextSide = findNextSide(ps.nextSide, ps.GetCell(), ref ps.h, ref ps.w);
if (ps.h >= 0 && ps.h < cellsPerSide && ps.w >= 0 && ps.w < cellsPerSide)
{
backtrackTracks(ps);
ps = tryNextTrack(ps);
}
else
return false;
}
return false;
}
return false;
}
and here's some code using random choices. This works fine, so I conclude that the methods checkOccupiedCells() and findNextSide() are working correctly.
private bool backtrackTracks(PotentialSolution ps)
{
if (canExit)
{
return true;
}
if (checkOccupiedCells(ps))
{
Track track = createRandomTrack(ps);
if (canExit)
return true;
if (track == Track.MaxVal)
return false;
ps.SetCell(track);
ps.nextSide = findNextSide(ps.nextSide, track, ref ps.h, ref ps.w);
if (ps.h >= 0 && ps.h < cellsPerSide && ps.w >= 0 && ps.w < cellsPerSide)
backtrackTracks(ps);
else
return false;
}
}
If it helps, there's more background info in the puzzle itself here

Constrains for Specman's list of lists

How can I apply constrains to list of list, similarly to what I can do to simple list:
list_size: uint;
my_list: list of uint;
keep my_list.size() == list_size;
keep for each (item) using index (item_index) in my_list { item == item_index;};
My intention is to create something like:
list_size:uint;
grosslist_size:uint;
my_grosslist: list of list of uint;
keep my_grosslist.size() == grosslist_size;
keep for each (grossitem) using index (grossindex)in my_grosslist {
grossitem.size() == list_size;
// keep for each (item) using index (item_index) in grossitem {
// item == item_index + grossindex * 100;
// };
};
How can I write 3 lines commented above using Specman syntax?
Please note that constrains are for instance only, in reality I'll need to apply much more sophisticated ones rather than indexing list items...
Thanks in advance.
The code you wrote is indeed the correct usage of list-of-list. Note that there was a missing space and the additional 'keep' is not needed for the internal for each. other than that, it works.
<'
extend sys {
list_size:uint;
grosslist_size:uint;
my_grosslist: list of list of uint;
keep my_grosslist.size() == grosslist_size;
keep for each (grossitem) using index (grossindex) in my_grosslist {
grossitem.size() == list_size;
for each (item) using index (item_index) in grossitem {
item == item_index + grossindex * 100;
};
};
};
'>

Filter getElementsByTagName list by option values

I'm using getElementsByTagName to return all the select lists on a page - is it possible to then filter these based upon an option value, ie of the first or second item in the list?
The reason is that for reasons I won't go into here there are a block of select lists with number values (1,2,3,4,5 etc) and others which have text values (Blue and Black, Red and Black etc) and I only want the scripting I have to run on the ones with numerical values. I can't add a class to them which would more easily let me do this however I can be certain that the first option value in the list will be "1".
Therefore is there a way to filter the returned list of selects on the page by only those whose first option value is "1"?
I am pretty sure that there is a better solution, but for the moment you can try something like:
var allSelect = document.getElementsByTagName("select");
var result = filterBy(allSelect, 0/*0 == The first option*/, "1"/* 1 == the value of the first option*/);
function filterBy(allSelect, index, theValue) {
var result = [];
for (var i = 0; i < allSelect.length; i++) {
if(allSelect[i].options[index].value == theValue ) {
result.push(allSelect[i]);
}
}
return result;
}
I managed to get this working by wrapping a simple IF statement around the action to be performed (in this case, disabling options) as follows:
inputs = document.getElementsByTagName('select');
for (i = 0; i < inputs.length; i++) {
if (inputs[i].options[1].text == 1) {
// perform action required
}
}
No doubt there is a slicker or more economic way to do this but the main thing is it works for me.

is there any way to use .indexOf to search a javascript array in mirth?

I am trying to find a string in a javascript array in the transformer of a mirth channel. Mirth throws an error when I try to use indexOf function. My understanding is that indexOf is something that browsers add in, rather than a native part of the javascript language itself. ( How do I check if an array includes an object in JavaScript? )
So is array.indexOf just not supported in Mirth? Is there any way to use .indexOf in Mirth? Maybe an alternate syntax? Or do I need to just loop thru the array to search?
This is how I search arrays in a Mirth js transformer:
var Yak = [];
Yak.push('test');
if(Yak.indexOf('test') != -1)
{
// do something
}
Does this give you error?
Mirth uses the Rhino engine for Javascript, and on some earlier versions of the JVM, indexOf appeared to not be supported on arrays. Since upgrading our JVM to 1.6.23 (or higher), indexOf has started working. However, we still have legacy code that, when searching arrays of strings, I just use a loop each time:
var compareString = "blah";
var index = -1;
for (var i = 0; i < myArray.length; ++i)
{
if (myArray[i] == compareString)
{
index = i;
break;
}
}
If you need to do this frequently, you should be able to use a code template to manually add the indexOf function to Array.
Set the code template to global access, and try out something like this (untested code):
Array.prototype.indexOf = function(var compareObject)
{
for (var i = 0; i < myArray.length; ++i)
{
// I don't think this is actually the right way to compare
if (myArray[i] == compareObject)
{
return i;
}
}
return -1;
}
var arr = ['john',1,'Peter'];
if(arr.indexOf('john') > -1)
{
//match. what to do?
console.log("found");
}
else
{
console.log("not found");//not found .. do something
}
var i = ['a', 'b', 'c']
if(i.indexOf('a') > -1)
{
///do this, if it finds something in the array that matches what inside the indexOf()
}
else
{
//do something else if it theres no match in array
}

Any Way to Streamline this Logic?

I've written some code that translates an Entity Framework collection to some fixed fields. I ended up with the following snippet but isn't there a slicker way to accomplish this?
var numbers = c.ContactPhoneNumbers.OrderByDescending(n => n.IsPrimary);
int count = 0;
foreach (var number in numbers)
{
if (count == 0)
{
hc.PrimaryPhone = number.PhoneNumber;
hc.PrimaryPhoneType = number.PhoneNumberType;
}
else if (count == 1)
{
hc.SecondaryPhone = number.PhoneNumber;
hc.SecondaryPhoneType = number.PhoneNumberType;
}
else break;
count++;
}
c is an Entity Framework entity and c.ContactPhoneNumbers represents entries in a related table. Seems like this code could be made a little more straight forward and less awkward.
Since you are iterating the phone enumeration right away, might be better to use ToList() so you can use the indexer:
var numbers = c.ContactPhoneNumbers.OrderByDescending(n => n.IsPrimary).ToList();
if(numbers.Count > 0)
{
hc.PrimaryPhone = numbers[0].PhoneNumber;
hc.PrimaryPhoneType = number[0].PhoneNumberType;
}
if(numbers.Count > 1)
{
hc.SecondaryPhone = numbers[1].PhoneNumber;
hc.SecondaryPhoneType = numbers[1].PhoneNumberType;
}