Seems like it's not as simple as RGB1*A1 + RGB2*A2...how are values clipped? Weighted? Etc.
And is this a context-dependent question? Are there different algorithms, that produce different results? Or one standard implementation?
I'm particularly interested in OpenGL-specific answers, but context from other environments is useful too.
I don't know about OpenGL, but one pixel of opacity A is usually drawn on another pixel like so:
result.r = background.r * (1 - A) + foreground.r * A
result.g = background.g * (1 - A) + foreground.g * A
result.b = background.b * (1 - A) + foreground.b * A
Repeat this operation for multiple pixels.
The above answer works if the image isn't premultiplied alpha. However if you use that type of blending with a premultiplied alpha image, there will be a black border.
Premultiplied Alpha:
When the image is created, the color values are multiplied by the alpha channel. Take a look at this one pixel example:
Pixel: r = 1, g = 0, b = 0, a = 0.5
When it's saved, the rgb vales will be multiplied by the alpha value giving:
Pixel: r = 0.5, g = 0, b = 0, a = 0.5
To blend this kind of image you need to use the following formula:
result.r = background.r * (1 - A) + foreground.r
result.g = background.g * (1 - A) + foreground.g
result.b = background.b * (1 - A) + foreground.b
Non-premultiplied Alpha
In this example, the alpha channel is completely separate to the color channels.
Pixel: r = 1, g = 0, b = 0, a = 0.5
When it's saved:
Pixel: r = 1, g = 0, b = 0, a = 0.5
It's the same. In this case the answer provided by minitech is correct.
More details can be found here: Premultiplied alpha
Related
I am trying to draw a railway in the way it is implemented in railroad tycoon 3. I have understood some of the patterns by which this is done, but I cannot find a formula for their application. I am trying to build an arc using only two points and some initial direction. For simplicity, let's assume that I can only plot a path in the range from 0 to 90 degrees. The arc should always start in the direction of "Initial direction". I need a method that would implement this. I tried to depict the idea in the drawings. Any pseudocode would do I guess.
general idea
borderline case at alpha = 0
borderline case at alpha = 90 degrees
Center C lies at middle perpendicular to SE segment, so we should find vectors
se = (E.x - S.x, E.y - S.y)
perp = (-se.y, se.x) = (S.y - E.y, E.x - S.x) //MC direction
and middle point
M = ((E.x + S.x)/2, (E.y - S.y)/2)
and express C coordinates using parametric equation
C = M + perp*t
Note that initial arc direction d is perpendicular to radius CS, so their dot product is zero:
(C - S).dot.d = 0
(M.x + perp.x * t - S.x)*d.x + (M.y + perp.y * t - S.y)*d.y = 0
This is linear equation for unknown parameter t, after solving it we know center C and can build the arc.
Python code. Perhaps examples are too simple to reveal bugs, but the first with half-circle gives R=L/2, center at M, and the second one shows correct C position and R.
from math import hypot, atan2
def arcfromptsdir(sx, sy, ex, ey, dx, dy):
sex = ex - sx
sey = ey - sy
perpx = -sey
perpy = sex
mx = (ex + sx) / 2
my = (ey + sy) / 2
#equation
#(sex/2 + perpx * t )*dx + (sey/2 + perp.y * t )*dy = 0
p = perpx * dx + perpy * dy
if p:
t = -0.5*(sex*dx + sey*dx) / p
else:
return None
#centerx, centery, radius
cx = mx + perpx * t
cy = my + perpy * t
radius = hypot(cx-sx, cy-sy)
arcangle = atan2((sx-cx) * (ey-cy) - (sy-cy) * (ex-cx),
(sx-cx) * (ex-cx) + (sy-cy) * (ey-cy))
return (cx, cy, radius, arcangle)
print(arcfromptsdir(0, 0, 2, 0, 0, 1))
print(arcfromptsdir(0, 0, 2, 0, 0.7071, 0.7071))
(1.0, 0.0, 1.0, -3.141592653589793)
(1.0, -1.0, 1.4142135623730951, -1.5707963267948966)
Seems like it's not as simple as RGB1*A1 + RGB2*A2...how are values clipped? Weighted? Etc.
And is this a context-dependent question? Are there different algorithms, that produce different results? Or one standard implementation?
I'm particularly interested in OpenGL-specific answers, but context from other environments is useful too.
I don't know about OpenGL, but one pixel of opacity A is usually drawn on another pixel like so:
result.r = background.r * (1 - A) + foreground.r * A
result.g = background.g * (1 - A) + foreground.g * A
result.b = background.b * (1 - A) + foreground.b * A
Repeat this operation for multiple pixels.
The above answer works if the image isn't premultiplied alpha. However if you use that type of blending with a premultiplied alpha image, there will be a black border.
Premultiplied Alpha:
When the image is created, the color values are multiplied by the alpha channel. Take a look at this one pixel example:
Pixel: r = 1, g = 0, b = 0, a = 0.5
When it's saved, the rgb vales will be multiplied by the alpha value giving:
Pixel: r = 0.5, g = 0, b = 0, a = 0.5
To blend this kind of image you need to use the following formula:
result.r = background.r * (1 - A) + foreground.r
result.g = background.g * (1 - A) + foreground.g
result.b = background.b * (1 - A) + foreground.b
Non-premultiplied Alpha
In this example, the alpha channel is completely separate to the color channels.
Pixel: r = 1, g = 0, b = 0, a = 0.5
When it's saved:
Pixel: r = 1, g = 0, b = 0, a = 0.5
It's the same. In this case the answer provided by minitech is correct.
More details can be found here: Premultiplied alpha
Given the equation-> (index+rotation)%rot=f; if i konw the values of f , rotation , rot
what is the formula to calculate index.I am not so good in mathematics but i want to know to calculate index in my programming.
(index + rotation)%rot = f
means
index + rotation = rot*k + f, k is an integer (.., -2, -1, 0, 1, 2,..)
therefore
index = rot*k + f - rotation, k: integer
If you want to have index > 0, make sure to choose k > (rotation - f) / rot
Given a mesh model (e.g. a box) and a robot template containing volume, aspect ratio and linkage info of sub-parts (basically cuboids), we want to have a cutting algorithm to cut the mesh model into pieces that can match the robot template. We are using Maya for the modelling job.
For example, the mesh model is a 1X1X1 volume=1 box, the robot template has a 1:1:2 volume 0.5 head link with body, and a 1:1:2 volume 0.5 body link with head, then what we need is to cut the box into half.
The matching of volume, aspect ratio and linkage are not strict, reasonable errors can be accepted.
Is there any existing algorithms that can do the job or is there any related topics on this?
Also if you have any idea to solve this problem please enlighten me. Thanks!
EDIT
The problem is, given a mesh object, and a robot template, we need to transform it to the robot.
So now my idea is first cut the object into subparts which match the template, then transform the subparts into robot using Inverse Kinematic maybe.
Sample input and output:
I'd try to just cubes to the correct dimensions by setting the aspect ratio in the cube shape
import maya.cmds as cmds
def scaled_cube(volume, w, d, h):
scale_factor = pow( float(volume) / float(h* w * d), 1.0/3)
return cmds.polyCube(w = w * scale_factor, d = d * scale_factor, h = h * scale_factor)
Edit: After the above comments, this will cut out the portion of a mesh contained in a cuboid (defined here as a maya style bounding box (minx, miny, minz, maxx, maxy, maxz - the same thing you'd get from querying the maya bbox):
def cut_to_fit_bounds(mesh, bbox):
'''
splits an existing mesh
'''
cutmesh = cmds.duplicate(mesh)
minx, miny, minz, maxx, maxy, maxz = bbox
cmds.select(cutmesh)
cmds.polyCut(pc = (minx, 0, 0), ro = (0, 90,0), df =1, ch=0 )
cmds.polyCloseBorder(ch=0)
cmds.polyCut(pc = (maxx, 0, 0), ro = (0, -90,0), df = 1, ch=0)
cmds.polyCloseBorder(ch=0)
cmds.polyCut(pc = (0, 0, minz), ro = (0, 0,0), df =1, ch=0 )
cmds.polyCloseBorder(ch=0)
cmds.polyCut(pc = (0, 0, maxz), ro = (0, 180,0), df = 1, ch=0)
cmds.polyCloseBorder(ch=0)
cmds.polyCut(pc = (0, miny, 0), ro = (-90, 0,0), df =1,ch=0 )
cmds.polyCloseBorder(ch=0)
cmds.polyCut(pc = (0, maxy, 0), ro = (90, 0,0), df = 1, ch=0)
cmds.polyCloseBorder(ch=0)
cmds.select(cutmesh)
The previous routine could be used to create appropriately sized volumes - by placing them correctly and grabbing their bounding boxes with cmds.xform(q=True, bb=True) cut volumes could be made. After that you should have a cut up copy of the original, although I'd worry about normal artifacts, sliver polys and material issues which are common when using polyCut.
how can i calculate the polynomial that has the tangent lines (1) y = x where x = 1, and (2) y = 1 where x = 365
I realize this may not be the proper forum but I figured somebody here could answer this in jiffy.
Also, I am not looking for an algorithm to answer this. I'd just like like to see the process.
Thanks.
I guess I should have mentioned that i'm writing an algorithm for scaling the y-axis of flotr graph
The specification of the curve can be expressed as four constraints:
y(1) = 1, y'(1) = 1 => tangent is (y=x) when x=1
y(365) = 1, y'(365) = 0 => tangent is (y=1) when x=365
We therefore need a family of curves with at least four degrees of freedom to match these constraints; the simplest type of polynomial is a cubic,
y = a*x^3 + b*x^2 + c*x + d
y' = 3*a*x^2 + 2*b*x + c
and the constraints give the following equations for the parameters:
a + b + c + d = 1
3*a + 2*b + c = 1
48627125*a + 133225*b + 365*c + d = 1
399675*a + 730*b + c = 0
I'm too old and too lazy to solve these myself, so I googled a linear equation solver to give the answer:
a = 1/132496, b = -731/132496, c = 133955/132496, d = -729/132496
I will post this type of question in mathoverflow.net next time. thanks
my solution in javascript was to adapt the equation of a circle:
var radius = Math.pow((2*Math.pow(365, 2)), 1/2);
var t = 365; //offset
this.tMax = (Math.pow(Math.pow(r, 2) - Math.pow(x, 2), 1/2) - t) * (t / (r - t)) + 1;
the above equation has the above specified asymptotes. it is part of a step polynomial for scaling an axis for a flotr graph.
well, you are missing data (you need another point to determine the polynomial)
a*(x-1)^2+b*(x-1)+c=y-1
a*(x-365)^2+b*(x-365)+c=y-1
you can solve the exact answer for b
but A depends on C (or vv)
and your question is off topic anyways, and you need to revise your algebra