Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- open System.Windows.Forms
- open System.Drawing
- // Lightweight controls: astrazione programmativa che imita i controlli grafici
- type LWC() =
- let mutable parent : Control = null
- let mutable location = PointF()
- let mutable size = SizeF()
- let mouseDown = Event<MouseEventArgs>()
- let mouseMove = Event<MouseEventArgs>()
- let mouseUp = Event<MouseEventArgs>()
- member val MouseEventHandled = false with get, set
- member this.MouseDown with get() = mouseDown.Publish
- member this.MouseMove with get() = mouseMove.Publish
- member this.MouseUp with get() = mouseUp.Publish
- abstract OnMouseDown : MouseEventArgs -> unit
- default this.OnMouseDown e = mouseDown.Trigger(e)
- abstract OnMouseMove : MouseEventArgs -> unit
- default this.OnMouseMove e = mouseMove.Trigger(e)
- abstract OnMouseUp : MouseEventArgs -> unit
- default this.OnMouseUp e = mouseUp.Trigger(e)
- abstract OnPaint : PaintEventArgs -> unit
- default this.OnPaint _ = ()
- abstract HitTest : PointF -> bool
- default this.HitTest p =
- (RectangleF(PointF(), size)).Contains(p)
- member this.Invalidate() =
- if parent <> null then parent.Invalidate()
- member this.Location
- with get() = location
- and set(v) = location <- v; this.Invalidate()
- member this.Size
- with get() = size
- and set(v) = size <- v; this.Invalidate()
- member this.Parent
- with get() = parent
- and set(v) = parent <- v
- type LWContainer() =
- inherit UserControl()
- let controls = ResizeArray<LWC>()
- let cloneMouseEvent (c:LWC) (e:MouseEventArgs) =
- new MouseEventArgs(e.Button, e.Clicks, e.X - int(c.Location.X), e.Y - int(c.Location.Y), e.Delta)
- let correlate (e:MouseEventArgs) (f:LWC->MouseEventArgs->unit) =
- let mutable found = false
- for i in { (controls.Count - 1) .. -1 .. 0 } do
- if not found then
- let c = controls.[i]
- if c.HitTest(PointF(single(e.X) - c.Location.X, single(e.Y) - c.Location.Y)) then
- found <- true
- f c (cloneMouseEvent c e)
- let mutable captured : LWC option = None
- member this.LWControls = controls
- member val LWMouseEventHandled = false with get, set
- override this.OnMouseDown e =
- this.LWMouseEventHandled <- false
- correlate e (fun c ev -> captured <- Some(c); c.OnMouseDown(ev); this.LWMouseEventHandled <- c.MouseEventHandled; c.MouseEventHandled <- false)
- base.OnMouseDown e
- override this.OnMouseUp e =
- this.LWMouseEventHandled <- false
- correlate e (fun c ev -> c.OnMouseUp(ev); this.LWMouseEventHandled <- c.MouseEventHandled; c.MouseEventHandled <- false)
- match captured with
- | Some c -> c.OnMouseUp(cloneMouseEvent c e); captured <- None
- | None -> ()
- base.OnMouseUp e
- override this.OnMouseMove e =
- this.LWMouseEventHandled <- false
- correlate e (fun c ev -> c.OnMouseMove(ev); this.LWMouseEventHandled <- c.MouseEventHandled; c.MouseEventHandled <- false)
- match captured with
- | Some c -> c.OnMouseMove(cloneMouseEvent c e)
- | None -> ()
- base.OnMouseMove e
- override this.OnPaint e =
- controls |> Seq.iter (fun c ->
- let s = e.Graphics.Save()
- e.Graphics.TranslateTransform(c.Location.X, c.Location.Y)
- e.Graphics.Clip <- new Region(RectangleF(0.f, 0.f, c.Size.Width + 1.f, c.Size.Height + 1.f))
- let r = e.Graphics.ClipBounds
- let evt = new PaintEventArgs(e.Graphics, new Rectangle(int(r.Left), int(r.Top), int(r.Width), int(r.Height)))
- c.OnPaint evt
- e.Graphics.Restore(s)
- )
- base.OnPaint(e)
- open System.Drawing
- let computeCollision (me) (other) =
- let mutable (meRec:Rectangle, meDir:Size, mePrec:Point) = me
- let mutable (otherRec:Rectangle, otherDir:Size, otherPrec:Point) = other
- if Region(meRec).IsVisible(otherRec) then
- let deltaDir = Size(-meDir.Width, -meDir.Height)
- meRec.Location <- mePrec + Size(meDir.Width, -meDir.Height)
- if Region(meRec).IsVisible otherRec then
- meRec.Location <- mePrec + Size(-meDir.Width, meDir.Height)
- ()
- let a1 = new ResizeArray<Rectangle * Size * Point>()
- let a2 = new ResizeArray<Rectangle * Size * Point>()
- let a3 = a1
- |> Seq.append a2
- |> Seq.toArray
- for me in a1 do
- for other in a3 do
- if me <> other then
- computeCollision me other
- ()
- open System.Windows.Forms
- open System.Drawing
- let f = new Form(Text="Midterm exercise 3", TopMost=true)
- f.Show()
- type RoundButton() =
- inherit LWC()
- member val Text : string = "" with get, set //alloca una var locale che si chiama Text e genera due membri uno get e uno set
- //disegna il bottone
- override this.OnPaint e =
- let g = e.Graphics
- g.DrawEllipse(Pens.Black, 0.f, 0.f, this.Size.Width, this.Size.Height)// disegno in tutta la mia area sta a chi mi chiama definire quale è
- let r = g.MeasureString(this.Text, this.Parent.Font)// per sapere la dimensione del test per disegnarlo al centro del bottone. Il font è nel controllo, quindi invoco il parent. Tutti i controlli hanno un font. Restituisce un rettangolo r che è la label.
- let x, y = (this.Size.Width - r.Width) / 2.f, (this.Size.Height - r.Height) / 2.f
- g.DrawString(this.Text, this.Parent.Font, Brushes.Black, PointF(x, y))// scrive
- type RectButton() =
- inherit LWC()
- member val Text : string = "" with get, set //alloca una var locale che si chiama Text e genera due membri uno get e uno set
- override this.OnPaint e =
- let g = e.Graphics
- g.DrawRectangle(Pens.Black, 0.f, 0.f, this.Size.Width, this.Size.Height)
- let r = g.MeasureString(this.Text, this.Parent.Font)// per sapere la dimensione del test per disegnarlo al centro del bottone. Il font è nel controllo, quindi invoco il parent. Tutti i controlli hanno un font. Restituisce un rettangolo r che è la label.
- let x, y = (this.Size.Width - r.Width) / 2.f, (this.Size.Height - r.Height) / 2.f
- g.DrawString(this.Text, this.Parent.Font, Brushes.Black, PointF(x, y))// scrive
- type VWCoordinates() =
- let mutable wv = new Drawing2D.Matrix()
- let mutable vw = new Drawing2D.Matrix()
- member this.WV with get() = wv and set(v) = wv <- v
- member this.VW with get() = vw and set(v) = vw <- v
- member this.Clone() =
- let ret = VWCoordinates()
- ret.WV <- wv.Clone()
- ret.VW <- vw.Clone()
- ret
- member this.Multiply(m:VWCoordinates, ?order:Drawing2D.MatrixOrder) =
- let wo = match order with Some(Drawing2D.MatrixOrder.Append) -> Drawing2D.MatrixOrder.Append | _ -> Drawing2D.MatrixOrder.Prepend
- let vo = match order with Some(Drawing2D.MatrixOrder.Prepend) -> Drawing2D.MatrixOrder.Prepend | _ -> Drawing2D.MatrixOrder.Append
- wv.Multiply(m.WV, wo)
- vw.Multiply(m.VW, vo)
- member this.Rotate(a:single) =
- wv.Rotate(a)
- vw.Rotate(-a, Drawing2D.MatrixOrder.Append)
- member this.RotateAt(a:single, p:PointF) =
- wv.RotateAt(a, p)
- vw.RotateAt(-a, p, Drawing2D.MatrixOrder.Append)
- member this.Translate(tx:single, ty:single) =
- wv.Translate(tx, ty)
- vw.Translate(-tx, -ty, Drawing2D.MatrixOrder.Append)
- member this.Scale(sx:single, sy:single) =
- wv.Scale(sx, sy)
- vw.Scale(1.f / sx, 1.f / sy, Drawing2D.MatrixOrder.Append)
- member this.TransformPointVW (p:Point) =
- let toPointF (p:Point) = PointF(single p.X, single p.Y)
- let a = [| p |> toPointF |]
- this.VW.TransformPoints(a)
- a.[0]
- member this.FTransformPointVW(p:PointF) =
- let a = [| p |]
- this.VW.TransformPoints(a)
- a.[0]
- member this.ScaleAtV(sx:single, sy: single, cv:Point) =
- let cw = cv |> this.TransformPointVW
- this.Scale(sx, sy)
- let cwp = cv |> this.TransformPointVW
- this.Translate(cwp.X - cw.X, cwp.Y - cw.Y)
- //fine classe Coordinate Vista Mondo.
- ///PALLINE RIMBALZINE ///////////////////////////////////////////////////////////////////////////////
- type BouncingBall() =
- let mutable location = PointF()
- let mutable speed = SizeF(10.f,10.f) // px/s
- let mutable lastT = System.DateTime.Now
- // let mutable mass = 1.f
- let mutable size = SizeF(1.f,1.f)// la size del rettangolo che contiene la pallina
- let mutable precLocation = PointF()
- // let matrix = VWCoordinates()
- // let transformPointVW p = matrix.TransformPointVW(p)
- member this.Location with get() = location and set(v) = location <- v
- member this.Speed with get() = speed and set(v) = speed <- v
- member this.Size with get() = size and set(v) = size <- v
- member this.Bounds = new RectangleF(location, size)
- member this.CenterLocation with get() = PointF(location.X + size.Width / 2.f, location.Y + size.Height / 2.f)
- member this.Region with get() = new Region(this.Bounds)
- member this.PrecPos with get() = precLocation and set(v) = precLocation <- v
- // member this.Mass with get() = mass and set(v) = mass <- v
- member this.UpdateSpeed(balls:BouncingBall seq, rectangles:RectangleF seq) = //aggiorna le velocità a restituisce una coppia, NB Speed è una size fatta da una componente x e una y
- let vb (b:BouncingBall, r:RectangleF) (vx : single, vy : single) =
- let ct, cb = this.CenterLocation, b.CenterLocation
- // let cr = PointF(r.Location.X + r.Size.Width / 2.f, r.Location.Y + r.Size.Height / 2.f) // centro dei rettangoli
- let cx, cy = cb.X - ct.X, cb.Y - ct.Y
- let sp = cx*vx + cy*vy
- let cr, vr = sqrt(cx*cx + cy*cy), sqrt(vx*vx+vy*vy)
- let cosa = sp / (cr*vr)
- let sina = sqrt(1.f - cosa*cosa)
- let vtb, votb = - vr * cosa, vr * sina
- let beta = atan2 cy cx
- let pi = single(System.Math.PI)
- let vtbx, vtby = vtb * cos(beta), vtb * sin(beta)
- let votbx, votby = votb * cos(pi / 2.f - beta), votb * sin(pi / 2.f - beta)
- (votbx + vtbx, votby + vtby)
- for b in balls do // per ogni pallina che non è sè stessa e che collide, aggiorna la velocità
- for r in rectangles do
- if b <> this && (this.CollideWithBalls(b) || this.CollideWithRect(this, r)) then
- let vx, vy = vb (b, r) (speed.Width, speed.Height)
- speed <- SizeF(vx, vy)
- member this.UpdatePosition() = //aggiorna la posizione e il tempo al quale è stata aggiornata
- let t = System.DateTime.Now
- let dt = t - lastT
- let vx = speed.Width / 1000.f
- let vy = speed.Height / 1000.f
- let dx = vx * single(dt.TotalMilliseconds)
- let dy = vy * single(dt.TotalMilliseconds)
- // let rnd = new System.Random()
- precLocation <- location
- location <- PointF(location.X + dx, location.Y + dy)
- //location <- PointF(location.X + single(rnd.NextDouble()) * dx, location.Y + single(rnd.NextDouble()) * dy)
- //location <- PointF(single(rnd.NextDouble()) * 50.f, single(rnd.NextDouble()) * 50.f)
- lastT <- t
- member this.CollideWithBalls (b:BouncingBall) =
- let sqdist (p1:PointF) (p2:PointF) =
- let dx, dy = p1.X - p2.X, p1.Y - p2.Y
- dx * dx + dy * dy
- let c1, c2 = this.CenterLocation, b.CenterLocation
- let d1, d2 = this.Size.Width / 2.f, b.Size.Width / 2.f
- sqdist c1 c2 <= (d1 + d2)*(d1 + d2)
- //collision con rettangoli
- member this.CollideWithRect (b:BouncingBall, r: RectangleF) =
- let sqdist (p1:PointF) (p2:PointF) =
- let dx, dy = p1.X - p2.X, p1.Y - p2.Y
- dx * dx + dy * dy
- let cball = b.CenterLocation
- let crect = PointF(r.Location.X + r.Size.Width / 2.f, r.Location.Y + r.Size.Height / 2.f)
- let rwidth, bwidht = r.Size.Width / 2.f, b.Size.Width / 2.f
- //caso ovvio che la pallina entri dentro il rettangolo
- sqdist cball crect <= rwidth*rwidth
- ////////////FINE CLASSE PALLINE RIMBALZINE
- //Dichiarazione del mio sistema di coordinate
- type CollisionTester() as this =
- inherit LWContainer()
- let balls = new ResizeArray<BouncingBall>()
- let rectangles = ResizeArray<RectangleF>()
- // do balls.Add(new BouncingBall(Location=PointF(20.f, 30.f), Speed=SizeF(30.f, 30.f))) // do serve per dichiarare uno statement, in questo caso aggiunge una pallina al buffer
- // let updateBalls() =
- // balls |> Seq.iter (fun b ->
- // b.UpdatePosition() // Per la collision detection
- // b.UpdateSpeed(balls, rectangles)
- // if b.Location.X < 0.f || b.Location.X + b.Size.Width > single(this.Width) then
- // b.Speed <- SizeF(- b.Speed.Width, b.Speed.Height)
- // if b.Location.Y < 0.f || b.Location.Y + b.Size.Height > single(this.Height) then
- // b.Speed <- SizeF(b.Speed.Width, - b.Speed.Height)
- // )
- let computeExit (me:BouncingBall) (other:RectangleF) =
- if me.CenterLocation.X > other.Left && me.CenterLocation.X < other.Right then
- if abs (me.CenterLocation.Y - other.Bottom) < abs (me.CenterLocation.Y - other.Top) then
- me.Location <- PointF(me.Location.X, me.Location.Y + abs(me.Location.Y - other.Bottom) + 2.f)
- me.PrecPos <- me.Location
- else
- me.Location <- PointF(me.Location.X, me.Location.Y - abs(me.Location.Y - other.Top) - 2.f)
- me.PrecPos <- me.Location
- else if me.CenterLocation.Y > other.Top && me.CenterLocation.Y < other.Bottom then
- if abs (me.CenterLocation.X - other.Left) < abs (me.CenterLocation.X - other.Right) then
- me.Location <- PointF(me.Location.X - abs(me.Location.X - other.Left) - 2.0f, me.Location.Y)
- me.PrecPos <- me.Location
- else
- me.Location <- PointF(me.Location.X + abs(me.Location.X - other.Right) + 2.f, me.Location.Y)
- me.PrecPos <- me.Location
- let computeCollisionRect (me:BouncingBall) (other:RectangleF) =
- if me.Region.IsVisible other then
- computeExit me other
- me.Location <- me.PrecPos + SizeF(me.Speed.Width, -me.Speed.Height)
- me.Speed <- SizeF(me.Speed.Width, -me.Speed.Height)
- if me.Region.IsVisible other then
- me.Speed <- SizeF(-me.Speed.Width, me.Speed.Height)
- me.Location <- me.PrecPos
- let computeCollisionBall (me:BouncingBall) (other:BouncingBall) =
- if me.Region.IsVisible other.Bounds then
- me.Location <- me.PrecPos + SizeF(me.Speed.Width, -me.Speed.Height)
- me.Speed <- SizeF(me.Speed.Width, -me.Speed.Height)
- if me.Region.IsVisible other.Bounds then
- me.Speed <- SizeF(-me.Speed.Width, me.Speed.Height)
- me.Location <- me.PrecPos
- let updateBalls() =
- for me in balls do
- me.UpdatePosition()
- for other in balls do
- if me <> other then computeCollisionBall me other
- for other in rectangles do
- computeCollisionRect me other
- ()
- //inizio dell'animazione
- let t = new Timer(Interval=10)
- do
- t.Tick.Add(fun _ ->
- updateBalls()
- this.Invalidate()
- )
- t.Start()
- //fine dell'animazione
- let mutable bip : BouncingBall option = None
- let mutable mousePos = PointF()
- //Dichiaro come costruire rettangoli e punti
- let toRectangle (r:RectangleF) = Rectangle(int r.X, int r.Y, int r.Width, int r.Height)
- let toPointF (p:Point) = PointF(single p.X, single p.Y)
- let mkRectangleF(p1:PointF, p2:PointF) =
- let x1, y1 = min p1.X p2.X, min p1.Y p2.Y
- let x2, y2 = max p1.X p2.X, max p1.Y p2.Y
- RectangleF(x1, y1, x2 - x1, y2 - y1)
- let mutable dragStart = None
- let mutable position = PointF()
- //creo i bottoni
- let up = RoundButton(Text="Up",Parent=this,Location=PointF(50.f, 0.f), Size=SizeF(35.f, 35.f))
- let left = RoundButton(Text="Left",Parent=this,Location=PointF(0.f, 50.f), Size=SizeF(35.f, 35.f))
- let right = RoundButton(Text="Right",Parent=this,Location=PointF(100.f, 50.f), Size=SizeF(35.f, 35.f))
- let down = RoundButton(Text="Down",Parent=this,Location=PointF(50.f, 100.f), Size=SizeF(35.f, 35.f))
- let rotateLeft = RoundButton(Text="RtLeft",Parent=this,Location=PointF(20.f, 150.f), Size=SizeF(40.f, 40.f))
- let rotateRight = RoundButton(Text="RtRight",Parent=this,Location=PointF(70.f, 150.f), Size=SizeF(40.f, 40.f))
- let zoomIn = RoundButton(Text="+",Parent=this,Location=PointF(45.f, 60.f), Size=SizeF(20.f, 20.f))
- let zoomOut = RoundButton(Text="-",Parent=this,Location=PointF(70.f, 60.f), Size=SizeF(20.f, 20.f))
- let createRect = RectButton(Text="Create Rect", Parent=this,Location=PointF(20.f, 200.f), Size=SizeF(90.f, 40.f))
- let createCirc = RectButton(Text="Create Circ", Parent=this,Location=PointF(20.f, 260.f), Size=SizeF(90.f, 40.f))
- let selectionTool = RectButton(Text="Selection Tool",Parent=this,Location=PointF(20.f, 340.f), Size=SizeF(90.f, 40.f))
- let mutable rectornot : bool = true
- let mutable circornot : bool = false
- let mutable selectornot : bool = false
- let mat = VWCoordinates()
- let transformPointVW p = mat.TransformPointVW(p)
- // definisco i comportamenti dei bottoni
- do
- this.SetStyle(ControlStyles.AllPaintingInWmPaint ||| ControlStyles.OptimizedDoubleBuffer, true)//get rid of flickering
- this.LWControls.AddRange([| up; left; right; down; rotateLeft; rotateRight; zoomIn; zoomOut; createRect; createCirc; selectionTool |])
- up.MouseDown.Add(fun _ -> mat.Translate(0.f, 10.f); up.MouseEventHandled <- true; this.Invalidate())
- left.MouseDown.Add(fun _ -> mat.Translate(10.f, 0.f); up.MouseEventHandled <- true; this.Invalidate())
- right.MouseDown.Add(fun _ -> mat.Translate(-10.f, 0.f); up.MouseEventHandled <- true; this.Invalidate())
- down.MouseDown.Add(fun _ -> mat.Translate(0.f, -10.f); up.MouseEventHandled <- true; this.Invalidate())
- rotateLeft.MouseDown.Add(fun _ -> mat.RotateAt(5.f, Point((this.Width / 2), (this.Height / 2)) |> transformPointVW); this.Invalidate())
- rotateRight.MouseDown.Add(fun _ -> mat.RotateAt(-5.f, Point((this.Width / 2), (this.Height / 2)) |> transformPointVW); this.Invalidate())
- zoomIn.MouseDown.Add(fun _ -> mat.ScaleAtV(1.1f, 1.1f, Point(this.Width / 2, this.Height / 2)); this.Invalidate())
- zoomOut.MouseDown.Add(fun _ -> mat.ScaleAtV(1.f / 1.1f, 1.f / 1.1f, Point(this.Width / 2, this.Height / 2)); this.Invalidate())
- createRect.MouseDown.Add(fun _ ->
- match rectornot with
- | true -> ()
- | false -> circornot <- false; selectornot <- false; rectornot <- true
- createRect.MouseEventHandled <- true; this.Invalidate())
- createCirc.MouseDown.Add(fun _ ->
- match circornot with
- | true -> ()
- | false -> rectornot <- false; selectornot <- false; circornot <- true
- createCirc.MouseEventHandled <- true; this.Invalidate())
- selectionTool.MouseDown.Add(fun _ ->
- match selectornot with
- | true -> ()
- | false -> rectornot <- false; circornot <- false; selectornot <- true
- selectionTool.MouseEventHandled <- true; this.Invalidate())
- // timer per aumeto massa
- let updateMass() =
- match bip with
- | Some(b) -> b.Size <- SizeF(b.Size.Width*1.1f, b.Size.Height*1.1f)
- | _ -> ()
- let masstimer = new Timer(Interval=30)
- let mutable count = 0
- do
- masstimer.Tick.Add(fun _ ->
- updateMass()
- this.Invalidate()
- )
- masstimer.Start()
- // let y = Screen.PrimaryScreen.Bounds.Bottom - this.Height;
- // disegno un puntatore che mi indica il centro della vista
- override this.OnPaint e =
- let g = e.Graphics
- let initTransform = g.Transform
- // let currentTransform = g.Transform
- g.DrawLine(Pens.Black, this.Width / 2 - 10, this.Height / 2, this.Width / 2 + 10, this.Height / 2)
- g.DrawLine(Pens.Black, this.Width / 2, this.Height / 2 - 10, this.Width / 2, this.Height / 2 + 10)
- g.Transform <- mat.WV
- for r in rectangles do
- g.DrawRectangle(Pens.Black, r |> toRectangle)
- if dragStart.IsSome then
- let r = mkRectangleF(dragStart.Value |> mat.FTransformPointVW, position) |> toRectangle
- g.DrawRectangle(Pens.Red, r)
- // palline //////////////////////////////////
- let paintball (b : BouncingBall) =
- let r = b.Bounds
- g.FillEllipse(Brushes.Blue, r)
- g.DrawEllipse(Pens.DarkBlue, r)
- balls |> Seq.iter paintball
- // g.Transform <- initTransform
- // sto disegnando una pallina
- match bip with
- | Some b ->
- use p = new Pen(Brushes.Black)
- p.EndCap <- Drawing2D.LineCap.ArrowAnchor
- g.DrawLine(p, PointF(b.Location.X + b.Size.Width / 2.f, b.Location.Y + b.Size.Height / 2.f), mousePos|> mat.FTransformPointVW)
- paintball b
- | None -> ()
- g.Transform <- initTransform
- base.OnPaint(e)
- override this.OnMouseDown e =
- base.OnMouseDown e
- if not(this.LWMouseEventHandled) then
- if rectornot then dragStart <- Some(e.Location |> mat.TransformPointVW)
- else if circornot then
- let b = BouncingBall()
- mousePos <- e.Location |> mat.TransformPointVW
- b.Location <- PointF(single(e.X) - b.Size.Width / 2.f, single(e.Y) - b.Size.Height / 2.f) |> mat.FTransformPointVW
- bip <- Some(b)
- this.Invalidate()
- else ()//fai select
- override this.OnMouseMove e =
- base.OnMouseMove e
- count <- count+1
- if not(this.LWMouseEventHandled) then
- if rectornot && dragStart.IsSome then position <- e.Location |> mat.TransformPointVW; this.Invalidate()
- else if circornot then
- match bip with
- | Some b ->
- mousePos <- PointF(single(e.X), single(e.Y))
- if(count%5 = 0) then
- this.Invalidate()
- | None -> ()
- else ()//fai select
- override this.OnMouseUp e =
- base.OnMouseUp e
- if not(this.LWMouseEventHandled) then
- if rectornot && dragStart.IsSome then
- position <- e.Location |> mat.TransformPointVW
- rectangles.Add(mkRectangleF(dragStart.Value, position))
- dragStart <- None
- this.Invalidate()
- else if circornot then
- match bip with
- | Some b ->
- let x0, y0 = b.Location.X + b.Size.Width / 2.f, b.Location.Y + b.Size.Height / 2.f
- let x1,y1 = PointF(single(e.X), single(e.Y)) |> mat.FTransformPointVW |> (fun p -> (p.X, p.Y))
- b.Speed <- SizeF((x1 - x0) / 2.f, (y1 - y0) / 2.f)
- balls.Add(b)
- bip <- None
- this.Invalidate()
- | None -> ()
- else ()//fai select
- let c = new CollisionTester(Dock=DockStyle.Fill)
- f.Controls.Add(c)
- c.Focus()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement