Unable to modify label text in the past for a simple Pine Script - label

I'm trying to modify the text for labels already plotted on the chart, but I'm not able to.
Example: in this Pivot script I want to change the black check mark symbol to a red X when price moves above the high of the Pivot Candle. Meaning that all Pivot Candles whose highs are lower than current price should be red Xs.
In this image the red circles represent what should be red Xs, while the green circles are right as they are.
Thank you in advance!
//#version=4
study("change labels in the past", overlay=true)
// Pivot definition
highPiv = pivothigh(high, 2, 2)
barcolor(highPiv ? color.blue : na, offset=-2)
// If price at the current time is higher than any High Pivot, change the Pivot Icon to a red X (oonly the ones currently under the price line)
HighVal = valuewhen(highPiv, high[2], 0)
priceOverHigh = close > HighVal
if highPiv
a=label.new(bar_index[2], close[2], text="✔️", style=label.style_label_down, color=color.new(color.black, 100), size=size.normal)
if priceOverHigh
label.set_text(id=a, text="❌")

Related

What is the Google Map zoom algorithm?

I'm working on a map zoom algorithm which change the area (part of the map visible) coordinates on click.
For example, at the beginning, the area has this coordinates :
(0, 0) for the corner upper left
(100, 100) for the corner lower right
(100, 100) for the center of the area
And when the user clicks somewhere in the area, at a (x, y) coordinate, I say that the new coordinates for the area are :
(x-(100-0)/3, y-(100-0)/3) for the corner upper left
(x+(100-0)/3, y+(100-0)/3) for the corner upper right
(x, y) for the center of the area
The problem is that algorithm is not really powerful because when the user clicks somewhere, the point which is under the mouse moves to the middle of the area.
So I would like to have an idea of the algorithm used in Google Maps to change the area coordinates because this algorithm is pretty good : when the user clicks somewhere, the point which is under the mouse stays under the mouse, but the rest of area around is zoomed.
Somebody has an idea of how Google does ?
Lets say you have rectangle windowArea which holds drawing area coordinates(i.e web browser window area in pixels), for example if you are drawing map on the whole screen and the top left corner has coordinates (0, 0) then that rectangle will have values:
windowArea.top = 0;
windowArea.left = 0;
windowArea.right = maxWindowWidth;
windowArea.bottom = maxWindowHeight;
You also need to know visible map fragment, that will be longitude and latitude ranges, for example:
mapArea.top = 8.00; //lat
mapArea.left = 51.00; //lng
mapArea.right = 12.00; //lat
mapArea.bottom = 54.00; //lng
When zooming recalculate mapArea:
mapArea.left = mapClickPoint.x - (windowClickPoint.x- windowArea.left) * (newMapWidth / windowArea.width());
mapArea.top = mapClickPoint.y - (windowArea.bottom - windowClickPoint.y) * (newMapHeight / windowArea.height());
mapArea.right = mapArea.left + newWidth;
mapArea.bottom = mapArea.top + newHeight;
mapClickPoint holds map coordinates under mouse pointer(longitude, latitude).
windowClickPoint holds window coordinates under mouse pointer(pixels).
newMapHeight and newMapWidth hold new ranges of visible map fragment after zoom:
newMapWidth = zoomFactor * mapArea.width;//lets say that zoomFactor = <1.0, maxZoomFactor>
newMapHeight = zoomFactor * mapArea.height;
When you have new mapArea values you need to stretch it to cover whole windowArea, that means mapArea.top/left should be drawn at windowArea.top/left and mapArea.right/bottom should be drawn at windowArea.right/bottom.
I am not sure if google maps use the same algorithms, it gives similar results and it is pretty versatile but you need to know window coordinates and some kind of coordinates for visible part of object that will be zoomed.
Let us state the problem in 1 dimension, with the input (left, right, clickx, ratio)
So basically, you want to have the ratio to the click from the left and to the right to be the same:
Left'-clickx right'-clickx
------------- = --------------
left-clickx right-clickx
and furthermore, the window is reduced, so:
right'-left'
------------ = ratio
right-left
Therefore, the solution is:
left' = ratio*(left -clickx)+clickx
right' = ratio*(right-clickx)+clickx
And you can do the same for the other dimensions.

Folding a selection of points on a 3D cube

I am trying to find an effective algorithm for the following 3D Cube Selection problem:
Imagine a 2D array of Points (lets make it square of size x size) and call it a side.
For ease of calculations lets declare max as size-1
Create a Cube of six sides, keeping 0,0 at the lower left hand side and max,max at top right.
Using z to track the side a single cube is located, y as up and x as right
public class Point3D {
public int x,y,z;
public Point3D(){}
public Point3D(int X, int Y, int Z) {
x = X;
y = Y;
z = Z;
}
}
Point3D[,,] CreateCube(int size)
{
Point3D[,,] Cube = new Point3D[6, size, size];
for(int z=0;z<6;z++)
{
for(int y=0;y<size;y++)
{
for(int x=0;x<size;x++)
{
Cube[z,y,x] = new Point3D(x,y,z);
}
}
}
return Cube;
}
Now to select a random single point, we can just use three random numbers such that:
Point3D point = new Point(
Random(0,size), // 0 and max
Random(0,size), // 0 and max
Random(0,6)); // 0 and 5
To select a plus we could detect if a given direction would fit inside the current side.
Otherwise we find the cube located on the side touching the center point.
Using 4 functions with something like:
private T GetUpFrom<T>(T[,,] dataSet, Point3D point) where T : class {
if(point.y < max)
return dataSet[point.z, point.y + 1, point.x];
else {
switch(point.z) {
case 0: return dataSet[1, point.x, max]; // x+
case 1: return dataSet[5, max, max - point.x];// y+
case 2: return dataSet[1, 0, point.x]; // z+
case 3: return dataSet[1, max - point.x, 0]; // x-
case 4: return dataSet[2, max, point.x]; // y-
case 5: return dataSet[1, max, max - point.x];// z-
}
}
return null;
}
Now I would like to find a way to select arbitrary shapes (like predefined random blobs) at a random point.
But would settle for adjusting it to either a Square or jagged Circle.
The actual surface area would be warped and folded onto itself on corners, which is fine and does not need compensating ( imagine putting a sticker on the corner on a cube, if the corner matches the center of the sticker one fourth of the sticker would need to be removed for it to stick and fold on the corner). Again this is the desired effect.
No duplicate selections are allowed, thus cubes that would be selected twice would need to be filtered somehow (or calculated in such a way that duplicates do not occur). Which could be a simple as using a HashSet or a List and using a helper function to check if the entry is unique (which is fine as selections will always be far below 1000 cubes max).
The delegate for this function in the class containing the Sides of the Cube looks like:
delegate T[] SelectShape(Point3D point, int size);
Currently I'm thinking of checking each side of the Cube to see which part of the selection is located on that side.
Calculating which part of the selection is on the same side of the selected Point3D, would be trivial as we don't need to translate the positions, just the boundary.
Next would be 5 translations, followed by checking the other 5 sides to see if part of the selected area is on that side.
I'm getting rusty in solving problems like this, so was wondering if anyone has a better solution for this problem.
#arghbleargh Requested a further explanation:
We will use a Cube of 6 sides and use a size of 16. Each side is 16x16 points.
Stored as a three dimensional array I used z for side, y, x such that the array would be initiated with: new Point3D[z, y, x], it would work almost identical for jagged arrays, which are serializable by default (so that would be nice too) [z][y][x] but would require seperate initialization of each subarray.
Let's select a square with the size of 5x5, centered around a selected point.
To find such a 5x5 square substract and add 2 to the axis in question: x-2 to x+2 and y-2 to y+2.
Randomly selectubg a side, the point we select is z = 0 (the x+ side of the Cube), y = 6, x = 6.
Both 6-2 and 6+2 are well within the limits of 16 x 16 array of the side and easy to select.
Shifting the selection point to x=0 and y=6 however would prove a little more challenging.
As x - 2 would require a look up of the side to the left of the side we selected.
Luckily we selected side 0 or x+, because as long as we are not on the top or bottom side and not going to the top or bottom side of the cube, all axis are x+ = right, y+ = up.
So to get the coordinates on the side to the left would only require a subtraction of max (size - 1) - x. Remember size = 16, max = 15, x = 0-2 = -2, max - x = 13.
The subsection on this side would thus be x = 13 to 15, y = 4 to 8.
Adding this to the part we could select on the original side would give the entire selection.
Shifting the selection to 0,6 would prove more complicated, as now we cannot hide behind the safety of knowing all axis align easily. Some rotation might be required. There are only 4 possible translations, so it is still manageable.
Shifting to 0,0 is where the problems really start to appear.
As now both left and down require to wrap around to other sides. Further more, as even the subdivided part would have an area fall outside.
The only salve on this wound is that we do not care about the overlapping parts of the selection.
So we can either skip them when possible or filter them from the results later.
Now that we move from a 'normal axis' side to the bottom one, we would need to rotate and match the correct coordinates so that the points wrap around the edge correctly.
As the axis of each side are folded in a cube, some axis might need to flip or rotate to select the right points.
The question remains if there are better solutions available of selecting all points on a cube which are inside an area. Perhaps I could give each side a translation matrix and test coordinates in world space?
Found a pretty good solution that requires little effort to implement.
Create a storage for a Hollow Cube with a size of n + 2, where n is the size of the cube contained in the data. This satisfies the : sides are touching but do not overlap or share certain points.
This will simplify calculations and translations by creating a lookup array that uses Cartesian coordinates.
With a single translation function to take the coordinates of a selected point, get the 'world position'.
Using that function we can store each point into the cartesian lookup array.
When selecting a point, we can again use the same function (or use stored data) and subtract (to get AA or min position) and add (to get BB or max position).
Then we can just lookup each entry between the AA.xyz and BB.xyz coordinates.
Each null entry should be skipped.
Optimize if required by using a type of array that return null if z is not 0 or size-1 and thus does not need to store null references of the 'hollow cube' in the middle.
Now that the cube can select 3D cubes, the other shapes are trivial, given a 3D point, define a 3D shape and test each part in the shape with the lookup array, if not null add it to selection.
Each point is only selected once as we only check each position once.
A little calculation overhead due to testing against the empty inside and outside of the cube, but array access is so fast that this solution is fine for my current project.

Pie chart icon placing algorithm

I have a problem when trying to draw a pie chart.
Of course, there is no problem with drawing the chart, the problem is the icon placement.
Ideally, the icons should be placed on a circle (let's forget the percent labels for now).
However, the design obviously breaks when there are neighbor items with small values.
Could you recommend an algorithm solving this issue? To simplify, as input we have:
PIE_RADIUS - The outer radius of the pie.
ICON_RADIUS - The radius of the icon circle.
ICON_PLACEMENT_RADIUS - The radius of the circle when icon center should be ideally placed.
NUM_ICONS - Number of icons to place.
iconAngles Angle for every icon, in the center of its section
Required output:
Either iconAngles for items placed around the pie or iconPositions when moving the icons out of their ideal circle.
I know how to check whether two icons overlap.
We can consider the center of the pie to be at (0, 0).
(The implementation is part of an iOS application but I am interested in a general algorihm).
A first naive algorithm , we "push" the icons that overlap with an other icon:
FOR iconToPlace in icons do:
isPlaced = false
WHILE(not isPlaced) DO:
isPlaced = true
FOR icon in icons DO:
IF overlap(iconToPlace, icon) AND iconToPlace != icon THEN:
isPlaced = false
push(iconToPlace) // same angle but the icon is now further
BREAK
ENDIF
ENDFOR
ENDWHILE
ENDFOR
With this first algorithm some icons will be futher from the center than other. But it does not exploit the possible place by changing the angle. By applying this to your second design (with small values) it is clear that the solution will be far away from the ideal one.
A second less naive algorithm, first we allocate a new angle (difference less than DeltaAngleMax) for each icon then we apply the first algo:
icons = SORT(icons)
iconsRef = icons
isFinished = false
WHILE(not isFinished) DO:
isFinished = true
FOR i = 0 TO i = NUM_ICONS-1 DO:
IF overlap(icons(i), icons(i+1 % NUM_ICONS))
AND not overlap(icons(i), icons(i-1 % NUM_ICONS)) //seems useless
AND not overlap(icons(i)-DeltaAngle % 360, icons(i-1 % NUM_ICONS))
AND ABS(icons(i)-iconsRef(i)) <= DeltaAngleMax THEN:
//overlap with next icon but not with previous,
//if we decrease angle we still not overlap with previous icon and
//the futur delta angle is less than DeltaAngleMax
//then we can move the icon :
icons(i) = icons(i)-DeltaAngle
isFinished = false
ELSE IF overlap(icons(i), icons(i-1 % NUM_ICONS))
AND not overlap(icons(i), icons(i+1 % NUM_ICONS)) //seems useless
AND not overlap(icons(i)+DeltaAngle % 360, icons(i+1 % NUM_ICONS))
AND ABS(icons(i)-iconsRef(i)) <= DeltaAngleMax THEN:
//vice et versa:
icons(i) = icons(i)+DeltaAngle
isFinished = false
ENDFOR
ENDWHILE
APPLY_FIRST_ALGO
Choose wisely deltaAngle and DeltaAngleMax. A too little deltaAngle will lead to a big running time.
To go further you should have a look at the force-directed graph drawing algorithm which is much more robust method to achieve your goal, one of the difficulty is to find the correct forces of the nodes (your icons, you have no edges).
Just brainstorming:
A genetic algorithm with a fitness function that has a high penalty for overlaps plus a penalty equal to the sum of the squares of the angular distances between each candidate location and its ideal location (centered relative to its slice).
The solution I implemented was the following:
Calculate the position for all the icons relative to their slice (icon centered on ICON_PLACEMENT_RADIUS)
Find sequences of overlapping icons (iterate the icons and check if the next is overlapping with the previous).
Calculate the minimum angular distance between two icons (approximately (2.0f * ICON_RADIUS + 1.0f) / ICON_PLACEMENT_RADIUS)
Calculate the center of the sequence (sum all the slices for the sequence and find the center), place the icons together (distance between them is the minimum angular distance).
When all icons placed, check if icons overlap, if yes, merge their sequences and iterate.
Note this algorithm works only if all the number of icons is small comparing to the size of the circle but it's simple and very fast.
The result is:

How to get the Position & Dimension of a Shape in Powerpoint?

I'm playing around with OpenXmlSDK to see if it's a viable solution for our Powerpoint needs. One thing that is required is the ability to position shapes in the Powerpoint. I've been searching around for a way to get the position of a Shape, but have only come across is the MSDN "How To" http://msdn.microsoft.com/en-us/library/cc850828.aspx and a Position class (but no way to get it from a Shape) http://msdn.microsoft.com/en-us/library/office/documentformat.openxml.wordprocessing.position%28v=office.14%29.aspx.
How do I do something like:
PresentationDocument presentationDocument = PresentationDocument.Open("C:\\MyDoc.pptx", true);
IdPartPair pp = presentationDocument.PresentationPart.SlideParts.First().Parts.FirstOrDefault();
var shape = pp.OpenXmlPart;
// How do I get the position and dimensions?
You have 2 variables for the dimension of the shape :
- Offset gives the position of the top corner of your shape
- Extents gives the size off your shape
shape.ShapeProperties.Transform2D.Offset.X //gives the x position of top left corner
shape.ShapeProperties.Transform2D.Offset.Y //gives the y position of top left corner
shape.ShapeProperties.Transform2D.Extents.X //gives the x size of the shape : the width
shape.ShapeProperties.Transform2D.Extents.Y //gives the y size of the shape : the height
Go through the XML for the slide in question and look for xfrm elements, which should contain off (offset) and ext (extent) sub-elements. The measurements are in EMUs (see last page of Wouter van Vugt's document).
Sometimes ShapeProperties is not displayed as a Shape property, you must write
var sP = ((DocumentFormat.OpenXml.Presentation.Shape)shape).ShapeProperties;
After you can use Transform2D and find coordinates as Deunz wrote.

Detect a rectangle bound of an character or object in black/white or binary image

I'm developing a handwriting recognition project. one of the requirements of this project is getting an image input, this image only contains some character object in a random location, and firstly I must extract this characters to process in next step.
Now I'm confusing a hard problem like that: how to extract one character from black/white (binary)image or how to draw a bound rectangle of a character in black - white (binary) image?
Thanks very much!
If you are using MATLAB (which I hope you are, since it it awesome for tasks like these), I suggest you look into the built in function bwlabel() and regionprops(). These should be enough to segment out all the characters and get their bounding box information.
Some sample code is given below:
%Read image
Im = imread('im1.jpg');
%Make binary
Im(Im < 128) = 1;
Im(Im >= 128) = 0;
%Segment out all connected regions
ImL = bwlabel(Im);
%Get labels for all distinct regions
labels = unique(ImL);
%Remove label 0, corresponding to background
labels(labels==0) = [];
%Get bounding box for each segmentation
Character = struct('BoundingBox',zeros(1,4));
nrValidDetections = 0;
for i=1:length(labels)
D = regionprops(ImL==labels(i));
if D.Area > 10
nrValidDetections = nrValidDetections + 1;
Character(nrValidDetections).BoundingBox = D.BoundingBox;
end
end
%Visualize results
figure(1);
imagesc(ImL);
xlim([0 200]);
for i=1:nrValidDetections
rectangle('Position',[Character(i).BoundingBox(1) ...
Character(i).BoundingBox(2) ...
Character(i).BoundingBox(3) ...
Character(i).BoundingBox(4)]);
end
The image I read in here are from 0-255, so I have to threshold it to make it binary. As dots above i and j can be a problem, I also threshold on the number of pixels which make up the distinct region.
The result can be seen here:
https://www.sugarsync.com/pf/D775999_6750989_128710
The better way to extract the character in my case was the segmentation for histogram i only can share with you some papers.
http://cut.by/j7LE8
http://cut.by/PWJf1
may be this can help you
One simple option is to use an exhaustive search, like (assuming text is black and background is white):
Starting from the leftmost column, step through all the rows checking for a black pixel.
When you encounter your first black pixel, save your current column index as left.
Continue traversing the columns until you encounter a column with no black pixels in it, save this column index as right.
Now traverse the rows in a similar fashion, starting from the topmost row and stepping through each column in that row.
When you encounter your first black pixel, save your current row index as top.
Continue traversing the rows until you find one with no black pixels in it, and save this row as `bottom.
You character will be contained within the box defined by (left - 1, top - 1) as the top-left corner and (right, bottom) as the bottom-right corner.

Resources