How to create horizontal rectangle that fills up or decreases color area depending on input value - xcode

I know there's a name for this, but I can't seem to think of it (or even provide a better title description.)
Image an empty horizontal rectangle - left edge has a value of 0, right edge has a value of 5. Now above it, there's a graph with an x-axis range of 0-5. When the plotting of the graph begins, the x-axis value is used as input to the horizontal rectangle in order to show, using a specific color, the area of the value.
Example: when input is given to the rectangle, the graph's x-axis value is 2.5. The rectangle now has half of it's area covered in red starting from the left edge. The value now is 3. Same idea, the area now stretches to "3".
It's a dynamic horizontal graph of sorts. Anywho, how do I go about creating this for iOS? Is there a class that's already built? Or do I just use rectangle drawing methods in a UIView subclass?
Thanks
update: here's an image of what I'm after: Bar

Related

algorithm to draw image selection

I have an image with size of M*N. Each pixel can be selected or not selected.
Given selection values for each pixel (selected or not), what is the most efficient algorithm to get the set of polygons which represents a selection?
Diagonals might be tricky, because of pixel-exact rounding errors, so I would go only for rectangles with horizontal and vertical lines (overlapping ones can be merges to a polygon)
I would perform the following steps:
connect selected neighbours of selected pixels to horizontal lines
connect horizontal lines to rectangles
connect overlapping/touching rectangles to a polygon
I think any filling algorithm can be suitable:
get a selected pixel not already used
start from it and fill the surface defined by all its connected pixels
this will define a polygon (just retain horizontal/vertical extremas)
restart with any selected pixel already not considered to get another polygon

Fill area chart based on values in three.js

I created an area chart with three.js. Each datapoint creates two triangles, one from bottom to height of the value to the next value height, one to fill the gap. Pretty similiar to the work of gmarland at http://gmarland.github.io/mercer/ (which I found after creating it when researching for a solution for this question, hard luck...).
Not knowing of any option to fill the area with a gradient as a whole, I filled the single triangles with vertexColors. Works, but obviously low values have the same color-gradient as higher ones just at another scale. Creating a nice effect but not visualizing the actual data. So here is the challenge where I can't think of a nice solution yet:
I would like to fill the area with a gradient that reflects the values. I.e. from 0 (yellow) to 100 (blue) and if a value is in between it stops somewhere at orange.
If I'd apply that logic using vertexColors for my triangles, the single triangles would get visible, as they'd have different colors at different heights, so that's not an option.
Any chance to fill the whole mesh (so, area of the chart) with a gradient?
Example of a 2D chart with that "effect": http://users.infragistics.com/2013.2/Ignite/Chart-Gradient.jpg
By the sounds of this i think you want to use a texture. You can generate several THREE.DataTexture all of witdh 1 and height 100. Several to make things simple with filtering. Fill them up with your values and then map them to your triangles using some logic.
Either scaled by the max height of these graphs, or the entire graph (looks like the red represent the peak of the curve, not the ceiling of the graph).
This is very similar to what you are doing with vertex colors, but instead of vertex colors, you need to generate UVs. U can always be 0 for every vertex, V is just the height of the vertex, normalized.

Algorithm for placing rectangle with certain size into free area in matrix

Problem
I need to place rectangle with size n×m into free area of matrix with size N×M, where N=n*2-1, M=m*2-1. Matrix cell is considered free if it's true, and occupied if it's false. Center cell is always true, and always will be inside rectangle due to rectangle and matrix's sizes.
Additional requirement is that distance between upper left corner of rectangle and center cell must be as minimal as possible.
Example with n=8 and m=5:
Where gray cells - occupied, green - center cell, blue cells - solution rectangle, red line - distance between upper left corner of rectangle and center cell.
Attempts
Brute force solution would have O(N×M×n×m) time complexity, which is not very optimal. I can eliminate calculations in some cells if I preprocess matrix, but that still would take too much time.
Initially I thought I can take Max Rectangle Problem and just modify condition from max to needed, but it went to dead end (I would need to list all rectangles in a histogram, which I don't know how). Then I thought it's like packing problem, but all I could find was versions of it with initially completely empty space and multiple rectangles, which is not applicable to this problem.
Context
In the past, when user clicks on a grid, my program would place rectangle, with upper left corner coinciding with a click point, if it's empty and fail if it have occupied cells where rectangle would lay. I decided to modify this behavior and instead of failing, find most suitable position for rectangle, while still containing a click point. In matrix pic above, click point is a green cell, and matrix size represents all possible positions of a rectangle.
P.S. I would prefer real language example instead of pseudo-code, if possible. My program is written in Java, but any language is fine.
You can do this in O(N.M) space and time complexity by:
Compute the summed area table in O(N.M)
Iterate over all top-left corners, check that the summed area in the rectangle is equal to n.m, and update the best position if the distance to the centre has improved. The test is O(1) per top-left corner, and there are O(N.M) top-left corners, so overall O(N.M)
The key idea is that the summed area table allows you to compute the sum of an arbitrary rectangle in O(1) time.

Footprint finding algorithm

I'm trying to come up with an algorithm to optimize the shape of a polygon (or multiple polygons) to maximize the value contained within that shape.
I have data with 3 columns:
X: the location on the x axis
Y: the location on the y axis
Value: Value of the block which can have positive and negative values.
This data is from a regular grid so the spacing between each x and y value is consistent.
I want to create a bounding polygon that maximizes the contained value with the added condition.
There needs to be a minimum radius maintained at all points of the polygon. This means that we will either lose some positive value blocks or gain some negative value blocks.
The current algorithm I'm using does the following
Finds the maximum block value as a starting point (or user defined)
Finds all blocks within the minimum radius and determines if it is a viable point by checking the overall value is positive
Removes all blocks in the minimum search radius from further value calculations and flags them as part of the final shape
Moves onto the next point determined by a spiraling around the original point. (center is always a grid point so moves by deltaX or deltaY)
This appears to be picking up some cells that aren't needed. I'm sure there are shape algorithms out there but I don't have any idea what to look up to find help.
Below is a picture that hopefully helps outline the question. Positive cells are shown in red (negative cells are not shown). The black outline shows the shape my current routine is returning. I believe the left side should be brought in more. The minimum radius is 100m the bottom left black circle is approximately this.
Right now the code is running in R but I will probably move to something else if I can get the algorithm correct.
In response to the unclear vote the problem I am trying to solve without the background or attempted solution is:
"Create a bounding polygon (or polygons) around a series of points to maximize the contained value, while maintaining a minimum radius of curvature along the polygon"
Edit:
Data
I should have included some data it can be found here.
The file is a csv. 4 columns (X,Y,Z [not used], Value), length is ~25k size is 800kb.
Graphical approach
I would approach this graphically. My intuition tells me that the inside points are fully inside the casted circles with min radius r from all of the footprint points nearby. That means if you cast circle from each footprint point with radius r then all points that are inside at least half of all neighboring circles are inside your polygon. To be less vague if you are deeply inside polygon then you got Pi*r^2 such overlapping circles at any pixel. if you are on edge that you got half of them. This is easily computable.
First I need the dataset. As you did provide just jpg file I do not have the vales just the plot. So I handle this problem like a binary image. First I needed to recolor the image to remove jpg color distortions. After that this is my input:
I choose black background to easily apply additive math on image and also I like it more then white and leave the footprint red (maximally saturated). Now the algorithm:
create temp image
It should be the same size and cleared to black (color=0). Handle its pixels like integer counters of overlapping circles.
cast circles
for each red pixel in source image add +1 to each pixel inside the circle with minimal radius r around the same pixel but in the temp image. The result is like this (Blue are the lower bits of my pixelformat):
As r I used r=24 as that is the bottom left circle radius in your example +/-pixel.
select inside pixels only
so recolor temp image. All the pixels with color < 0.5*pi*r^2 recolor to black and the rest to red. The result is like this:
select polygon circumference points only
Just recolor all red pixels near black pixels to some neutral color blue and the rest to black. Result:
Now just polygonize the result. To compare with the input image you can combine them both (I OR them together):
[Notes]
You can play with the min radius or the area treshold property to achieve different behavior. But I think this is pretty close match to your problem.
Here some C++ source code for this:
//picture pic0,pic1;
// pic0 - source
// pic1 - output/temp
int x,y,xx,yy;
const int r=24; // min radius
const int s=float(1.570796*float(r*r)); // half of min radius area
const DWORD c_foot=0x00FF0000; // red
const DWORD c_poly=0x000000FF; // blue
// resize and clear temp image
pic1=pic0;
pic1.clear(0);
// add min radius circle to temp around any footprint pixel found in input image
for (y=r;y<pic1.ys-r;y++)
for (x=r;x<pic1.xs-r;x++)
if (pic0.p[y][x].dd==c_foot)
for (yy=-r;yy<=r;yy++)
for (xx=-r;xx<=r;xx++)
if ((xx*xx)+(yy*yy)<=r*r)
pic1.p[y+yy][x+xx].dd++;
pic1.save("out0.png");
// select only pixels which are inside footprint with min radius (half of area circles are around)
for (y=0;y<pic1.ys;y++)
for (x=0;x<pic1.xs;x++)
if (pic1.p[y][x].dd>=s) pic1.p[y][x].dd=c_foot;
else pic1.p[y][x].dd=0;
pic1.save("out1.png");
// slect only outside pixels
pic1.growfill(c_foot,0,c_poly);
for (y=0;y<pic1.ys;y++)
for (x=0;x<pic1.xs;x++)
if (pic1.p[y][x].dd==c_foot) pic1.p[y][x].dd=0;
pic1.save("out2.png");
pic1|=pic0; // combine in and out images to compare
pic1.save("out3.png");
I use my own picture class for images so some members are:
xs,ys size of image in pixels
p[y][x].dd is pixel at (x,y) position as 32 bit integer type
clear(color) - clears entire image
resize(xs,ys) - resizes image to new resolution
[Edit1] I got a small bug in source code
I noticed some edges were too sharp so I check the code and I forgot to add the circle condition while filling so it filled squares instead. I repaired the source code above. I really just added line if ((xx*xx)+(yy*yy)<=r*r). The results are slightly changed so I also updated the images with new results
I played with the inside area coefficient ratio and this one:
const int s=float(0.75*1.570796*float(r*r));
Leads to even better match for you. The smaller it is the more the polygon can overlap outside footprint. Result:
If the solution set must be a union of disks of given radius, I would try a greedy approach. (I suspect that the problem might be intractable - exponential running time - if you want an exact solution.)
For all pixels (your "blocks"), compute the sum of values in the disk around it and take the one with the highest sum. Mark this pixel and adjust the sums of all the pixels that are in its disk by deducing its value, because the marked pixel has been "consumed". Then scan all pixels in contact with it by an edge or a corner, and mark the pixel with the highest sum.
Continue this process until all sums are negative. Then the sum cannot increase anymore.
For an efficient implementation, you will need to keep a list of the border pixels, i.e. the unmarked pixels that are neighbors of a marked pixel. After you have picked the border pixel with the largest sum and marked it, you remove it from the list and recompute the sums for the unmarked pixels inside its disk; you also add the unmarked pixels that touch it.
On the picture, the pixels are marked in blue and the border pixels in green. The highlighted pixels are
the one that gets marked,
the ones for which the sum needs to be recomputed.
The computing time will be proportional to the area of the image times the area of a disk (for the initial computation of the sums), plus the area of the shape times the area of a disk (for the updates of the sums), plus the total of the lengths of the successive perimeters of the shape while it grows (to find the largest sum). [As the latter terms might be costly - on the order of the product of the area of the shape by its perimeter length -, it is advisable to use a heap data structure, which will reduce the sum of the lengths to the sum of their logarithm.]

Photoshop smart object: get rotation angle via Applescript?

I have tried and failed to find an Applescript code that returns a smart object's current rotation angle in Photoshop. Anyone have an idea of where that property is listed? I'm beginning to think this feature isn't currently supported by Applescript.
In Photoshop, objects like a selection has no angle value, because it means nothing: if your selection is made by multiple segments making a complexe shape, there is no mathematical way you can define angle for that shape !
However, you can work with boundary rectangle (which includes that shape). You can rotate this complete boundary (i.e. the selection) and then you will get a new boundary (new rectangle where new rotated shape fits in).
A boundary rectangle is made of a list of for values :
top left corner horizontal position (X1)
top left corner vertical position (Y1)
bottom right corner horizontal position (X2)
bottom right corner vertical position (Y2)
Positions are real numbers, starting with border of canvas (not border of layer ! so you may have negative values). The units depends of the unit of measure of the document.
Once that's clear (I hope !) if you use mathematical calculation between initial boundary and new boundary, you can calculate the rotation angle:
(Pythagore triangle)
If you assume that initial rectangle borders were vertical and horizontal :
cosinus (Teta) = (X2-X1) / (X'2 - X'1)
Teta = angle you are looking for
X1, X2 are the positions of the boundary corners before rotation and X'1, X'2 are position of same corners after rotation.
Please note that this method is OK for selection (any shape), or layers.
It should also be OK for the full canvas, but I never test it for canvas.

Resources