Does anyone know how to place labels on arbitrary borders of a polygon, when using JSXGraph?
I'm looking to implement something like this:
And I am creating a polygon like so (The script is interpreted via board.jc.parse):
A = point(-5,-5) << withLabel:false, visible:false>>;
B = point(-5,5) << withLabel:false, visible:false>>;
C = point(5,5) << withLabel:false, visible:false>>;
D = point(5, -5) << withLabel:false, visible:false>>;
polygon(A,B,C,D);
I'm thinking I can do something like this (put a label on the point and then move it over by a few pixels), but... blehk, that it ugly. I'd like to attach the label to the side of the polygon or the lines themselves.
// Don't want to do it this way
text(A.X(), A.Y(), 'label') << id: 'TT1' >>;
In JessieCode / JSXGraph labels for borders of a polygon can be set with the attribute sub-object 'borders':
A = point(-5, -5) << withLabel:false, visible:false>>;
B = point(-5, 5) << withLabel:false, visible:false>>;
C = point(5, 5) << withLabel:false, visible:false>>;
D = point(5, -5) << withLabel:false, visible:false>>;
polygon(A,B,C,D) <<
borders: <<
names: ['a', 'b', 'c', 'd'],
withLabel: true
>>
>>;
Related
The current project that I am working on involves a multidimensional world, which can have many more than just 3 dimensions, and need to get values for each position of that world. I already have a good Pseudo Random Number Generator (PRNG) that takes a seed and a single value. What I need is to have a function that can use as many inputs as are provided, and return a value based on those positions. The PRNG also should not have to rely on its previous values to determine it's next state, and should work (as close as possible to) the same on any browser or system.
My current PRNG, works very well for 1 input (xxHash):
function random(seed, x) {
/* mix around the bits in x: */
x = x * 3266489917 + 374761393;
x = (x << 17) | (x >> 15);
/* mix around the bits in y and mix those into x: */
x += seed * 3266489917;
/* Give x a good stir: */
x *= 668265263;
x ^= x >> 15;
x *= 2246822519;
x ^= x >> 13;
x *= 3266489917;
x ^= x >> 16;
/* trim the result and scale it to a float in [0,1): */
return (x & 0x00ffffff) * (1 / 0x1000000);
}
I tried adding more parameters and mixing them up, but that didn't go so well (Below):
function rand(seed, ...prams){
let x = prams[0] + seed;
x = x * 3266489917 + 374761393;
x = (x << 17) | (x >> 15);
/* mix around the bits in y and mix those into x: */
for(let i =1; i< prams.length; i++){
prams[i] *= seed;
x *= prams[i] * 3266489917
}
/* Give x a good stir: */
x *= 668265263;
x ^= x >> 15;
x *= 2246822519;
x ^= x >> 13;
x *= 3266489917;
x ^= x >> 16;
/* trim the result and scale it to a float in [0,1): */
let val = ((x & 0x00ffffff) * (1.0 / 0x1000000))
return val;
}
This one didn't return any errors, but if the inputs were in a different order, the value was the same, which means that rand(seed, 5, 1, 1) === rand(seed, 1, 5, 1) === rand(seed, 1, 1, 5) , Which is not great behavior.
I need a function random(seed, ...position) that will generate a pseudo random number between 0 and 1 that is affected by both the order and all the values in the position array.
I have two lines defined by two points each(P1, P2, P3, P4).
I'd like to find the 2 points(X0, Y0) that are distanced r units from both lines.
I found a way but I think it's too long to solve(too difficult for me) and maybe there's one shorter(https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line).
my way:
Without solving it it's impossible tp create the function
I'd like to have the solution not the sistem.
Example(I'd like to find the yellow points knowing r):
Thanks.
(Sorry for my terrible english)
Variant A:
represent your lines in general form
a * x + b * y + c = 0
d * x + e * y + f = 0
with normalized coefficients (divide equation by Sqrt(a^2+b^2))
For this form point lies at distance r if
|a * x + b * y + c| = r
|d * x + e * y + f| = r
Open absolute value brackets with all possible +/- sign combinations and get 4 linear systems for 4 possible points
Variant B:
1) Find unit direction vectors of both lines da and db
2) Find intersection point C of two lines
3) Calculate angle between lines as
Fi = atan2(da.cross.db, da.dot.db)
4) Find unit bisector vector
b = (da + db).Normalized
5) Find perpendicular bisector
pb = (-b.y, b.x)
6) Get needed points as
C + b * r / Sin(Fi/2)
C - b * r / Sin(Fi/2)
C + pb * r / Cos(Fi/2)
C - pb * r / Cos(Fi/2)
I am storing id (which is a value comprised in 24bit-range) into an Float32Array(3) for latter retrieval in WebGL:
var r = 0,
g = 0,
b = id;
if (b >= 65536) {
r = ~~(b / 65536);
b -= r * 65536;
}
if (b >= 256) {
g = ~~(b / 256);
b -= g * 256;
}
var fa = new Float32Array([r/255, g/255, b/255]);
For the sake of completeness, here is how i am using that value:
gl.uniform3fv(uniforms['u_id'], fa);
...and this is how i get my id back from WebGLRenderingContext.readPixels():
var result = new Uint8Array(4);
gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, result);
var id = result[0] << 16 | result[1] << 8 | result[2];
Which is the correct way to split that value into my Float32Array? I strongly believe that such task could be accomplished in a more efficient and elegant way (actually, what i am doing is working but is really hurting my eyes).
id has a form like this:
0000 0000 rrrr rrrr gggg gggg bbbb bbbb
A part (r, g or b) can be extracted by putting it in the lowest byte and masking the rest away. Sometimes one of those steps is unnecessary. So:
b = id & 255 // b is already in the low byte, so no shift
g = (id >> 8) & 255
r = id >> 16 // no mask because there is nothing "above" r
This can be put together with the division and putting it in an array:
[(id >> 16) / 255, ((id >> 8) & 255) / 255, (id & 255) / 255]
I can already convert 32bit integers into their rgba values like this:
pixelData[i] = {
red: pixelValue >> 24 & 0xFF,
green: pixelValue >> 16 & 0xFF,
blue: pixelValue >> 8 & 0xFF,
alpha: pixelValue & 0xFF
};
But I don't really know how to reverse it.
To reverse it, you just have to combine the bytes into an integer.
Simply use left-shift and add them, and it will work.
var rgb = (red << 24) + (green << 16) + (blue << 8) + (alpha);
Alternatively, to make it safer, you could first AND each of them with 0xFF:
var r = red & 0xFF;
var g = green & 0xFF;
var b = blue & 0xFF;
var a = alpha & 0xFF;
var rgb = (r << 24) + (g << 16) + (b << 8) + (a);
(You may use bitwise OR | instead of + here, the outcome will be the same).
I have various hexadecimal RRGGBBAA colors as stop values in a heat map gradient but I have noticed that setting different Alpha values for some of the stop doesn't change the opacity in my code, I always get the same view -although setting the last two alpha bits to 00 as 0.0 opacity works for some reason-. The RRGGBBAA values are written like this:
0xaa00007f (the last two bits, 7f should be 0.5 opacity)
0xaa0000ff (ff is the 1.0 opacity)
The setGradientStops function that takes the stop values is like this -this is from a heat map library, not my code-
setGradientStops: function(stops) {
var ctx = document.createElement('canvas').getContext('2d');
var grd = ctx.createLinearGradient(0, 0, 256, 0);
for (var i in stops) {
grd.addColorStop(i, 'rgba(' +
((stops[i] >> 24) & 0xFF) + ',' +
((stops[i] >> 16) & 0xFF) + ',' +
((stops[i] >> 8) & 0x7F) + ',' +
((stops[i] >> 0) & 0x7F) + ')');
}
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 256, 1);
this.gradient = ctx.getImageData(0, 0, 256, 1).data;
}
The problem is that opacity expects a value in the range of 0 - 1 and there you are outputting a value in the range of 0 - 127. I would try...
grd.addColorStop(i, 'rgba(' +
((stops[i] >> 24) & 0xFF) + ',' +
((stops[i] >> 16) & 0xFF) + ',' +
((stops[i] >> 8) & 0xFF) + ',' +
(((stops[i] >> 0) & 0xFF) / 255) + ')');
So it takes the bits from the part that represents the alpha (all of them rather than almost all of them) by using the & bit operator on 0xFF rather than 0x7F. So...
0xFF (11111111) & 0xFF (11111111) = 0xFF (11111111) = 255
Rather than...
0xFF (11111111) & 0x7F (01111111) = 0x7F (01111111) = 127
and then you have the value in the range of 0 - 255, divide by 255 to get this to the required range.
0xFF / 255 = 1, 0x7F / 255 = 0.498, 0x00 / 255 = 0
So then for 0xaa00007f, grd.addColorStop would be given the string 'rgba(170,0,0,0.498)'