void ComputePupils(TPoint mouse, TPoint[] pupils) { TRectangle screen, sp; screen = new TRectangle(); sp = null; if (eyes.Distance) { var scr = widgetSelf.Handle.Screen; var r = widgetSelf.Handle.Screen.RootWindowOfScreen; var cod = new TonNurako.X11.XCoordinates(); widgetSelf.Handle.Display.TranslateCoordinates(widgetSelf.Handle.Window, r, 0, 0, cod); screen.X = Tx(-cod.DestX, -cod.DestY, eyes.Transform); screen.Y = Ty(-cod.DestX, -cod.DestY, eyes.Transform); screen.Width = Twidth(scr.WidthOfScreen, scr.HeightOfScreen, eyes.Transform); screen.Height = Theight(scr.WidthOfScreen, scr.HeightOfScreen, eyes.Transform); sp = screen; } pupils[0] = ComputePupil(0, mouse, sp); pupils[1] = ComputePupil(1, mouse, sp); }
void Trectangle(Transform t, TRectangle i, TRectangle o) { o.X = t.Mx * i.X + t.Bx; o.Y = t.My * i.Y + t.By; o.Width = t.Mx * i.Width; o.Height = t.My * i.Height; if (o.Width < 0) { o.X += o.Width; o.Width = -o.Width; } if (o.Height < 0) { o.Y += o.Height; o.Height = -o.Height; } }
void DrawEllipse(EyesPart part, double centerx, double centery, double oldx, double oldy, double diam) { TRectangle tpos = new TRectangle( centerx - diam / 2.0, centery - diam / 2.0, diam, diam); TRectangle pos = new TRectangle(); Trectangle(eyes.Transform, tpos, pos); if (part == EyesPart.PART_CLEAR) { eyes.GC[(int)EyesPart.PART_CENTER].FillRectangle( widgetSelf.Handle, (int)pos.X, (int)pos.Y, (int)pos.Width + 2, (int)pos.Height + 2); return; } if (eyes.Render && part != EyesPart.PART_SHAPE && (!eyes.ShapeWindow || part != EyesPart.PART_OUTLINE) && null != eyes.Picture) { int n, i; double hd, c, s, sx, sy, x, y, px, py; pos.X = pos.X + pos.Width / 2.0; pos.Y = pos.Y + pos.Height / 2.0; hd = Math.Sqrt(Math.Pow(pos.Width, 2.0) + Math.Pow(pos.Height, 2.0)) / 2; n = (int)((Math.PI / Math.Acos(hd / (hd + 1.0))) + 0.5); if (n < 2) { n = 2; } c = Math.Cos(Math.PI / n); s = Math.Sin(Math.PI / n); sx = -(pos.Width * s) / pos.Height; sy = (pos.Height * s) / pos.Width; n *= 2; var p = new TonNurako.X11.Extension.XPointDouble[n]; x = 0; y = pos.Height / 2.0; for (i = 0; i < n; i++) { p[i].X = x + pos.X; p[i].Y = y + pos.Y; px = x; py = y; x = c * px + sx * py; y = c * py + sy * px; } if (!TEqual(oldx, TPOINT_NONE) || !TEqual(oldy, TPOINT_NONE)) { DrawEllipse(EyesPart.PART_CLEAR, oldx, oldy, TPOINT_NONE, TPOINT_NONE, diam); } TonNurako.X11.Extension.XRender.CompositeDoublePoly( widgetSelf.Handle.Display, TonNurako.X11.Extension.PictOp.Over, eyes.Fill[(int)part], eyes.Picture, TonNurako.X11.Extension.XRender.FindStandardFormat(widgetSelf.Handle.Display, TonNurako.X11.Extension.PictStandard.A8), 0, 0, 0, 0, p, 0); p = null; return; } if (!TEqual(oldx, TPOINT_NONE) || !TEqual(oldy, TPOINT_NONE)) { DrawEllipse(EyesPart.PART_CLEAR, oldx, oldy, TPOINT_NONE, TPOINT_NONE, diam); } var dst = (part == EyesPart.PART_SHAPE) ? eyes.ShapeMask : (IDrawable)widgetSelf.Handle; eyes.GC[(int)part].FillArc( dst, (int)(pos.X + 0.5), (int)(pos.Y + 0.5), (int)(pos.Width + 0.0), (int)(pos.Height + 0.0), 90 * 64, 360 * 64); }
TPoint ComputePupil(int num, TPoint mouse, TRectangle screen) { double cx, cy; double dist; double angle; double dx, dy; double cosa, sina; TPoint ret = new TPoint(); cx = EYE_X(num); dx = mouse.X - cx; cy = EYE_Y(num); dy = mouse.Y - cy; if (dx != 0 || dy != 0) { angle = Math.Atan2((double)dy, (double)dx); cosa = Math.Cos(angle); sina = Math.Sin(angle); dist = BALL_DIST; if (null != screen) { double x0, y0, x1, y1; var a = new double[4]; x0 = screen.X - cx; y0 = screen.Y - cy; x1 = x0 + screen.Width; y1 = y0 + screen.Height; a[0] = Math.Atan2(y0, x0); a[1] = Math.Atan2(y1, x0); a[2] = Math.Atan2(y1, x1); a[3] = Math.Atan2(y0, x1); if (AngleBetween(angle, a[0], a[1])) { dist *= dx / x0; } else if (AngleBetween(angle, a[1], a[2])) { dist *= dy / y1; } else if (AngleBetween(angle, a[2], a[3])) { dist *= dx / x1; } else if (AngleBetween(angle, a[3], a[0])) { dist *= dy / y0; } if (dist > BALL_DIST) { dist = BALL_DIST; } } if (dist > Math.Sqrt(Math.Pow(dx, 2.0) + Math.Pow(dy, 2.0))) { cx += dx; cy += dy; } else { cx += dist * cosa; cy += dist * sina; } } ret.X = cx; ret.Y = cy; return(ret); }