I did some triangulation tasks with the library PolyK. Just for comparison purposes for my simple polygons.
I have a Polygon with 7 vertices. But I get with this library only 9 indexes == 3 triangles that is to less I guess.
In the following code you see my implemention of PolyK.js in THREE.js
var pts3 = [];
var ids2 = PolyK.Triangulate(pts3);
for (var k = 0; k < ids2.length; k+=3)
{
geometry.faces.push(new THREE.Face3(ids2[k], ids2[k + 1], ids2[k + 2]));
}
My points array:
(7 points with x and y value)
var points = [
158.56000000005588, 336.73000000044703,
158.60000000009313, 335.21999999973923,
161.589999999851, 335.3099999995902,
161.7799999997951, 329.820000000298,
155.52000000001863, 329.62000000011176,
155.29999999981374, 336.62999999988824,
158.56000000005588, 336.73000000044703
];
This is the current result:
This is the expected result:
Is there something wrong regarding the usage of PolyK in the source code?
These are the points:
4 _______________ 3
| |
| |
| |
| |
| |
| _______|
| |1 2
|_______|
5 0/6
I tested in a fiddle here and it seems to work like you said.
I get result:
[5, 6, 0, 0, 1, 2, 0, 2, 3]
It is the same incorrect result as you showed in your drawing.
At first I thought removing the duplicated point ( 0 is same as 6 ) would solve the issue, but that also gives a incorrect result.
I would suggest using a different library like earcut or poly2tri.
Check also this triangulation adapter/library on GitHub that I made for three.js. It might be useful for you.
Related
Input data
Pipes or somethins like on stock (length = quantity on stock):
pipe3m = 4 pc
pipe4m = 1 pc
pipe5m = 1 pc
Needed cust (length = quantity)
cut2m = 4pc
cut2.5m = 1pc
Result: optimal pipes for minimum remains, considering quantity that left on stock
pipe4m 1pc => cut2m + cut2m => remains 0m (4-2-2)
pipe5m 1pc => cut2m + cut2.5m => remains 0.5m (5 - 2 - 2.5)
pipe3m 1pc => cut2m => remains 1m (3-2)
So we need:
pipe4m => 1pc *(if we have 2 pc of pipe4m on stock we can cut it into 2m+2m, but there is only 1)*
pipe5m => 1pc
pipe3m => 1pc
How can I implement some optimal algorithm for this?
There will be 5-10 pipe lengths and 10-20 cuts, so I think that it can't be solved with brute force, but I'm not algorithm guru.
Thanks :)
Smaller instances can be solved with mixed-integer linear programming. Here is an implementation in MiniZinc using the data from the question. The available pipes have been rearranged into a flat array pipeLength. In the model x denotes the cuts from each pipe and z denotes whether a pipe is used or not.
int: nPipes = 6;
int: nCuts = 2;
set of int: PIPE = 1..nPipes;
set of int: CUT = 1..nCuts;
array[PIPE] of float: pipeLength = [3, 3, 3, 3, 4, 5];
array[CUT] of int: cutQuantity = [4, 1];
array[CUT] of float: cutLength = [2, 2.5];
array[PIPE, CUT] of var 0..10: x;
array[PIPE] of var 0..1: z;
% required cuts constraint
constraint forall(k in CUT)
(sum(i in PIPE)(x[i,k]) = cutQuantity[k]);
% available pipes constraint
constraint forall(i in PIPE)
(sum(k in CUT)(cutLength[k]*x[i,k]) <= pipeLength[i]);
% pipe used constraint
constraint forall(i in PIPE)
(max(cutQuantity)*z[i] >= sum(k in CUT)(x[i,k]));
var float: loss = sum(i in PIPE)(pipeLength[i]*z[i] - sum(k in CUT)(cutLength[k]*x[i,k]));
solve minimize loss;
output ["loss=\(show_float(2, 2, loss))\n"] ++
["pipeCuts="] ++ [show2d(x)] ++
["usePipe="] ++ [show(z)];
Running gives:
loss="1.50"
pipeCuts=[| 0, 0 |
0, 0 |
0, 0 |
0, 1 |
2, 0 |
2, 0 |]
usePipe=[0, 0, 0, 1, 1, 1]
The same MILP-model could also be implemented in e.g. PuLP.
I've created the group (its GF4 algebra) that has 4 elements:
OrderMat = {0, 1, lambda, lambda + 1}
And definition of operation (.) with this Matrix realized by function:
| 0 | 1 | lambda | lambda+1 |
______________________________________________
0|| 0 | 0 | 0 | 0 |
1|| 0 | 1 | lambda | lambda+1 |
lambda|| 0 | lambda | lambda+1 | 1 |
lambda+1|| 0 |lambda+1| 1 | lambda |
OPMatrix = {{0, 0, 0, 0},
{0, 1, lambda, lambda + 1},
{0, lambda, lambda + 1, 1},
{0, lambda + 1, 1, lambda}}
GF4Mult[x_, y_] := OPMatrix[[Position[OrderMat, x][[1]][[1]]]][[Position[OrderMat, y][[1]][[1]]]]
Now I would like to Solve equations in this group.
for example:
Solve[x.lambda == 1,x] ... x=>lambda+1
or like this:
Solve[GF4Mult[x,lambda]== 1,x] ... x=>lambda+1
Is this possible ? do i have to use some other structure to define group ?
I don't know if this is a good way of doing this, but it seems closer to what you are asking for than the last couple of things I tried. And it uses the notation that you chose, except for Mathematica reordering lambda+1 to be 1+lambda on output.
First let's define your multiplication operator
times={{0,0,0},{0,1,0},{0,lambda,0},{0,lambda+1,0},
{1,0,0},{1,1,1},{1,lambda,lambda},{1,lambda+1,lambda+1},
{lambda,0,0},{lambda,1,lambda},{lambda,lambda,lambda+1},{lambda,lambda+1,1},
{lambda+1,0,0},{lambda+1,1,lambda+1},{lambda+1,lambda,1},{lambda+1,lambda+1,lambda}};
That is exactly what you had except for my flattening that into a vector.
Now lets show a method somewhat similar to Solve that might work for you.
Suppose as a first example you wonder is there a lambda+1*something=lambda+1
Cases[times,{lambda+1,x_,lambda+1}]
and that shows you there is only one value which satisfies that, the identity.
{{1+lambda,1,1+lambda}}
Another example
Cases[times,{lambda+1,x_,lambda}]
gives you
{{1+lambda,1+lambda,lambda}}
Another example, is there lambda+1*anythingBUTlambda+1=lambda
Cases[times,{lambda+1,Except[lambda+1],lambda}]
gives you
{}
which shows there is no such value.
Another example
Cases[times,{lambda+1,x_,Except[x_]}]
gives you
{{1+lambda,1,1+lambda},{1+lambda,lambda,1},{1+lambda,1+lambda,lambda}}
That has a lot of flexibility because you can have unknowns in any position. But because of that flexibility it doesn't just return a single value to you. Perhaps you can use this for what you are thinking of or perhaps you can think of ways to adapt this to what you are trying to do.
If you want to extract one value of a result then you can do things like this:
Cases[times,{lambda+1,x_,lambda}:>x]
which will return
{1+lambda}
which is the value, or values, of x which satisfied that.
Check this carefully to see if you can find any mistakes before you depend on it.
I have a data file containing values of longitudes and latitudes (displayed on two columns) measured by a GPS along a profile at regular intervals. at a certain point on my profile, the GPS stopped working, hence in my data i have zeros instead of values of longitudes and latitudes. I want to interpolate between this fields to get values of longitudes and latitudes instead of zeros.
to be more clear here is a simple example of how my file looks like.
[12 7] ;
[14 8 ];
[0 0];
[0 0];
[20 11];
[22 12]
NB: the number are on two columns, it's the editor's problem
i want to interpolate where i got zeros. i am working on bash and i have no idea on how to do it
You might have luck with a linear regression done once for the first column and once for the second column.
Assume we're working on the first column. The input / x axis is the index of the measurement, and the output / y axis is the measurement itself. So your data can become ((1, 12), (2, 14), (3, 0), (4, 0), (5, 20), (6, 22)). Based on the known input-output relationships, for indices (1, 2, 5, 6), you need to deduce a formula of the form y = ax + b. So you basically need to find a and b. Once you have those you can find the y for input 3 as 3a + b and the y for input 4 as 4a + b.
You'll find a different a and b for the second column.
How to find a and b is a little bit complicated. You can look at this article for a nice introduction as well as the formulas for computing a and b (named b0 and b1 inside).
One last thing - I would not attempt doing such a thing in Bash. While it is possible, as Bash has support for arrays and math, it is not what it was designed for. Call out to Matlab/Octave or R, and use their results. Those tools have builtin support for reading files such as yours as well as for doing the regression.
You can do that with awk, here is a script:
script.awk
BEGIN { FS="[ [\\];]+"
# decide on the number of floating digits for the interpolated figures
FMTStr= "[%.1f, %.1f];\n"
}
{ if( ($2== 0) && ( $3 == 0) ) { zeroLines++ }
else {
for( i = 1; i <= zeroLines; i++ ) {
t1 = prev1 + (($2 - prev1) / (zeroLines + 1 )) * i
t2 = prev2 + (($3 - prev2) / (zeroLines + 1 ) ) * i
printf(FMTStr, t1, t2)
}
# either printf(FMTStr, $2, $3) #or
print $0
prev1 = $2
prev2 = $3
zeroLines = 0
}
}
Use it so: awk -f script.awk yourfile, it gives you
[12 7] ;
[14 8 ];
[16.0, 9.0];
[18.0, 10.0];
[20 11];
[22 12];
I am fairly new to the framework and I simply cannot find a simple example of a matrix that uses scales to compute the x and y of a rect. Here's an example of something I am trying to achieve:
w = 400
h = 600
| column1 | column2 |
--------------------------
row1 | value1 | value2 |
row2 | value3 | value4 |
row3 | value5 | value6 |
My dataset looks something like this:
dataset = [
[row1-col1, row1,col2],
[row2-col1, row2,col2],
[row3-col1, row3,col2],
]
I merge it, using d3.merge, so that I append rects. NB: The resulting array as 6 elements and not groups of 2.
.selectAll('rect')
.data(d3.merge(dataset))
.enter()
.append('rect')
Question:
What scale do I use so that it wraps on two columns based on the width? That is, I would like the following behaviour when i is passed to the xscale when the width == 2.:
xscale(1) == 0, xscale(2) == 1
xscale(3) == 0, xscale(4) == 1
xscale(5) == 0, xscale(6) == 1
So, [1,3,5] -> 0, [2,4,5] -> 1.
I also presume this is possible for the y scale as well? I would be very surprised if this were not possible, however I have been hunting around and I cannot find a simple example demonstrating such functionality. I do not want to have to manually wrap (using %) when the row limit is reached. If this isn't part of the standard library it should be included. I wonder how many people are manually implementing this.
Thanks for the help
The problem looks like this,
You have to draw N px width line as a M uniform dashes.
If for example N=13 and M=5 you our dash will have 2 px width and we will have 3 px error.
We can do better, we can draw dashes with following widths: 3, 3, 3, 2, 2 .
But we can do even better the dashes can have following widths: 3, 2, 3, 2, 3 .
If I have a list a = ( 3, 3, 3, 2, 2 ) how can I find such list that the distance 'D' between all pairs in the list will be maximum?
In this example D(a) = 0 + 0 + 1 + 0 = 1.
For list b = ( 3, 2, 3, 2, 3 ), D(b) = 1+1+1+1 = 4.
What is the fastest/simplest method?
The simplest method I know of ? Using floating point numbers...
In Python:
def pace(D,M): return [round(float(D) / M * i) for i in range(1,M+1)]
I have already seen this somewhere here I think.
Something inspired by Bresenham's algorithm should do the trick. Believe me, you don't want to maximize D over all permutations of your set. This problem is overly complex (complexity is O(n!), so unless n is very small, this won't work)