/* * Solves the system [a] + [b]s = [u] + [v]t * [a - u] = [v]t - [b]s */ private static void SolveLinearSystem2(Point2Float a, Vector2Float b, out float s, Point2Float u, Vector2Float v, out float t) { Vector2Float constants = a - u; double det_denom = Vector2Float.Determinant(v, -b); double det_v = Vector2Float.Determinant(constants, -b); double det_b = Vector2Float.Determinant(v, constants); t = (float)(det_v / det_denom); s = (float)(det_b / det_denom); }
public override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { BlendEffectConfigToken token = parameters as BlendEffectConfigToken; Point2Float start = new Point2Float(); Point2Float end = new Point2Float(); Point2Float p; Point2Float q; if (token.blendDirection == BlendDirection.BL_TR) { start = new Point2Float(bounds.Left - 0.5f, bounds.Bottom + 0.5f); end = new Point2Float(bounds.Right + 0.5f, bounds.Top - 0.5f); } else if (token.blendDirection == BlendDirection.BR_TL) { start = new Point2Float(bounds.Right, bounds.Bottom); end = new Point2Float(bounds.Left, bounds.Top); } else if (token.blendDirection == BlendDirection.TL_BR) { start = new Point2Float(bounds.Left, bounds.Top); end = new Point2Float(bounds.Right, bounds.Bottom); } else if (token.blendDirection == BlendDirection.TR_BL) { start = new Point2Float(bounds.Right, bounds.Top); end = new Point2Float(bounds.Left, bounds.Bottom); } if (token.blendDirection == BlendDirection.BL_TR || token.blendDirection == BlendDirection.TR_BL) { p = new Point2Float(bounds.Right, bounds.Bottom); q = new Point2Float(bounds.Left, bounds.Top); } else { p = new Point2Float(bounds.Left, bounds.Bottom); q = new Point2Float(bounds.Right, bounds.Top); } Vector2Float lineDir = Vector2Float.Normalize(p - q); for (int i = startIndex; i < length; ++i) { Rectangle rect = rois[i]; for (int y = rect.Top; y < rect.Bottom; ++y) { for (int x = rect.Left; x < rect.Right; ++x) { Point2Float current = new Point2Float(x, y) + new Vector2Float(0.5f, 0.5f); Vector2Float dir = Vector2Float.Normalize(end - current); float distToCross = 0; float dist_ignore = 0; SolveLinearSystem2(current, dir, out distToCross, p, Vector2Float.Normalize(q - p), out dist_ignore); Point2Float center = new Point2Float(bounds.Left + bounds.Width / 2, bounds.Top + bounds.Height / 2); Vector2Float distToCenter = current - center; distToCenter.X /= bounds.Width / 2; distToCenter.Y /= bounds.Height / 2; Point2Float from2; if (Math.Abs(distToCenter.X) > Math.Abs(distToCenter.Y)) { from2 = new Point2Float(start.X, end.Y); } else { from2 = new Point2Float(end.X, start.Y); } float distToStart = 0; float dist_ignore2 = 0; SolveLinearSystem2(current, -dir, out distToStart, from2, Vector2Float.Normalize(from2 - start), out dist_ignore2); if (distToCross > 0) { float t = distToStart / (distToStart + distToCross); ColorBgra pixle = srcArgs.Surface.GetPoint(x, y); pixle.A = (byte)(t * pixle.A); //pixle.R = (byte)(255 * t); //pixle.G = 0; // (byte)(from2.Y); //pixle.B = 0; dstArgs.Surface.SetPoint(x, y, pixle); } else { dstArgs.Surface.SetPoint(x, y, srcArgs.Surface.GetPoint(x, y)); } } } } }