<commit_before>//
//  Demos.swift
//  BezierKit
//
//  Created by <NAME> on 3/6/17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import Foundation
import BezierKit

typealias DemoDrawFunction = (_ context: CGContext, _ demoState: DemoState) -> Void

struct Demo {
    var title: String
    var quadraticControlPoints: [CGPoint]
    var cubicControlPoints: [CGPoint]
    var drawFunction: DemoDrawFunction
}

struct DemoState {
    var quadratic: Bool             // whether the demo is set to quadratic (or if false: cubic) mode
    var lastInputLocation: CGPoint? // location of mouse / touch input if applicable
    var curve: BezierCurve?         // a user-draggable Bezier curve if applicable
}

class Demos {
    private static let cubicControlPoints = [CGPoint(x: 100, y: 25),
                                     CGPoint(x: 10, y: 90),
                                     CGPoint(x: 110, y: 100),
                                     CGPoint(x: 150, y: 195)]
    private static let quadraticControlPoints = [CGPoint(x: 150, y: 40),
                                         CGPoint(x: 80, y: 30),
                                         CGPoint(x: 105, y: 150)]
    
    static let demo1 = Demo(title: "new Bezier(...)",
                            quadraticControlPoints: quadraticControlPoints,
                            cubicControlPoints: cubicControlPoints,
                            drawFunction: {(context: CGContext, demoState: DemoState) in
                                let curve = demoState.curve!
                                Draw.drawSkeleton(context, curve: curve)
                                Draw.drawCurve(context, curve: curve)
                                
    })
    static let demo2 = Demo(title: "Bezier.quadraticFromPoints",
                            quadraticControlPoints: [],
                            cubicControlPoints: [],
                            drawFunction: {(context: CGContext, demoState: DemoState) in
                                if demoState.quadratic {
                                    let B = BKPoint(x: 100, y: 50)
                                    let tvalues: [BKFloat] = [0.2, 0.3, 0.4, 0.5]
                                    let curves: [QuadraticBezierCurve] = tvalues.map({(t: BKFloat) -> QuadraticBezierCurve in
                                        return QuadraticBezierCurve(start: BKPoint(x:150, y: 40),
                                                                    end: BKPoint(x:35, y:160),
                                                                    mid: B,
                                                                    t: t)
                                    })
                                    let offset = BKPoint(x:45,y:30)
                                    for (i, b) in curves.enumerated() {
                                        Draw.drawSkeleton(context, curve: b, offset: offset, coords: true)
                                        Draw.setColor(context, color: Draw.transparentBlack)
                                        Draw.drawCircle(context, center: b.points[1], radius: 3, offset: offset)
                                        Draw.drawText(context, text: "t=\(tvalues[i])", offset: BKPoint(
                                            x: b.points[1].x + offset.x - 15,
                                            y: b.points[1].y + offset.y - 20
                                        ))
                                        Draw.setRandomColor(context)
                                        Draw.drawCurve(context, curve: b, offset: offset)
                                    }
                                    Draw.setColor(context, color: Draw.black)
                                    Draw.drawCircle(context, center: curves[0].points[0], radius:3, offset: offset)
                                    Draw.drawCircle(context, center: curves[0].points[2], radius:3, offset: offset)
                                    Draw.drawCircle(context, center: B, radius: 3, offset: offset)
                                }
                                else {
                                    let p1 = BKPoint(x: 110, y: 50)
                                    let B = BKPoint(x: 50, y: 80)
                                    let p3 = BKPoint(x:135, y:100)
                                    let tvalues: [BKFloat] = [0.2, 0.3, 0.4, 0.5]
                                    let curves: [CubicBezierCurve] = tvalues.map({
                                        (t: CGFloat) -> (CubicBezierCurve) in
                                        return CubicBezierCurve(start: p1, end: p3, mid: B, t: t)
                                        }
                                    )
                                    let offset = BKPoint(x: 0.0, y: 0.0)
                                    for curve in curves {
                                        Draw.setRandomColor(context)
                                        Draw.drawCurve(context, curve: curve, offset: offset)
                                    }
                                    Draw.setColor(context, color: Draw.black)
                                    Draw.drawCircle(context, center: curves[0].points[0], radius: 3, offset: offset)
                                    Draw.drawCircle(context, center: curves[0].points[3], radius: 3, offset: offset)
                                    Draw.drawCircle(context, center: B, radius: 3, offset: offset)
                                }
    })
    static let demo3 = Demo(title: ".getLUT(steps)",
                            quadraticControlPoints: quadraticControlPoints,
                            cubicControlPoints: cubicControlPoints,
                            drawFunction: {(context: CGContext, demoState: DemoState) in
                                let curve = demoState.curve!
                                Draw.drawSkeleton(context, curve: curve)
                                let LUT = curve.generateLookupTable(withSteps: 16)
                                for p in LUT {
                                    Draw.drawCircle(context, center: p, radius: 2)
                                }
    })
    static let demo4 = Demo(title: ".length()",
                            quadraticControlPoints: quadraticControlPoints,
                            cubicControlPoints: [CGPoint(x: 100, y: 25), CGPoint(x: 10, y: 90), CGPoint(x: 110, y: 100), CGPoint(x: 132, y: 192)],
                            drawFunction: {(context: CGContext, demoState: DemoState) in
                                let curve = demoState.curve!
                                Draw.drawSkeleton(context, curve: curve)
                                Draw.drawCurve(context, curve: curve)
                                Draw.setColor(context, color: Draw.red)
                                let arclength = curve.length()
                                let offset = curve.offset(distance: -10)
                                let last = offset.count-1
                                for idx in 0 ..< offset.count {
                                    let c = offset[idx]
                                    Draw.drawCurve(context, curve: c)
                                    if(idx==last) {
                                        let p1 = curve.offset(t: 0.95, distance: -15)
                                        let p2 = c.compute(1)
                                        let p3 = curve.offset(t: 0.95, distance: -5)
                                        Draw.drawLine(context, from: p1, to: p2)
                                        Draw.drawLine(context, from: p2, to: p3)
                                        let label = String(format: "%3.1fpx", arclength)
                                        Draw.drawText(context, text: label, offset: BKPoint(x: p2.x+7, y: p2.y-3))
                                    }
                                }
    })
    static let demo5 = Demo(title: ".get(t) and .compute(t)",
                            quadraticControlPoints: quadraticControlPoints,
                            cubicControlPoints: cubicControlPoints,<commit_msg>changed px to pt since it isnt really a pixel on a modern retina machine.<commit_after>//
//  Demos.swift
//  BezierKit
//
//  Created by <NAME> on 3/6/17.
//  Copyright © 2017 <NAME>. All rights reserved.
//

import Foundation
import BezierKit

typealias DemoDrawFunction = (_ context: CGContext, _ demoState: DemoState) -> Void

struct Demo {
    var title: String
    var quadraticControlPoints: [CGPoint]
    var cubicControlPoints: [CGPoint]
    var drawFunction: DemoDrawFunction
}

struct DemoState {
    var quadratic: Bool             // whether the demo is set to quadratic (or if false: cubic) mode
    var lastInputLocation: CGPoint? // location of mouse / touch input if applicable
    var curve: BezierCurve?         // a user-draggable Bezier curve if applicable
}

class Demos {
    private static let cubicControlPoints = [CGPoint(x: 100, y: 25),
                                     CGPoint(x: 10, y: 90),
                                     CGPoint(x: 110, y: 100),
                                     CGPoint(x: 150, y: 195)]
    private static let quadraticControlPoints = [CGPoint(x: 150, y: 40),
                                         CGPoint(x: 80, y: 30),
                                         CGPoint(x: 105, y: 150)]
    
    static let demo1 = Demo(title: "new Bezier(...)",
                            quadraticControlPoints: quadraticControlPoints,
                            cubicControlPoints: cubicControlPoints,
                            drawFunction: {(context: CGContext, demoState: DemoState) in
                                let curve = demoState.curve!
                                Draw.drawSkeleton(context, curve: curve)
                                Draw.drawCurve(context, curve: curve)
                                
    })
    static let demo2 = Demo(title: "Bezier.quadraticFromPoints",
                            quadraticControlPoints: [],
                            cubicControlPoints: [],
                            drawFunction: {(context: CGContext, demoState: DemoState) in
                                if demoState.quadratic {
                                    let B = BKPoint(x: 100, y: 50)
                                    let tvalues: [BKFloat] = [0.2, 0.3, 0.4, 0.5]
                                    let curves: [QuadraticBezierCurve] = tvalues.map({(t: BKFloat) -> QuadraticBezierCurve in
                                        return QuadraticBezierCurve(start: BKPoint(x:150, y: 40),
                                                                    end: BKPoint(x:35, y:160),
                                                                    mid: B,
                                                                    t: t)
                                    })
                                    let offset = BKPoint(x:45,y:30)
                                    for (i, b) in curves.enumerated() {
                                        Draw.drawSkeleton(context, curve: b, offset: offset, coords: true)
                                        Draw.setColor(context, color: Draw.transparentBlack)
                                        Draw.drawCircle(context, center: b.points[1], radius: 3, offset: offset)
                                        Draw.drawText(context, text: "t=\(tvalues[i])", offset: BKPoint(
                                            x: b.points[1].x + offset.x - 15,
                                            y: b.points[1].y + offset.y - 20
                                        ))
                                        Draw.setRandomColor(context)
                                        Draw.drawCurve(context, curve: b, offset: offset)
                                    }
                                    Draw.setColor(context, color: Draw.black)
                                    Draw.drawCircle(context, center: curves[0].points[0], radius:3, offset: offset)
                                    Draw.drawCircle(context, center: curves[0].points[2], radius:3, offset: offset)
                                    Draw.drawCircle(context, center: B, radius: 3, offset: offset)
                                }
                                else {
                                    let p1 = BKPoint(x: 110, y: 50)
                                    let B = BKPoint(x: 50, y: 80)
                                    let p3 = BKPoint(x:135, y:100)
                                    let tvalues: [BKFloat] = [0.2, 0.3, 0.4, 0.5]
                                    let curves: [CubicBezierCurve] = tvalues.map({
                                        (t: CGFloat) -> (CubicBezierCurve) in
                                        return CubicBezierCurve(start: p1, end: p3, mid: B, t: t)
                                        }
                                    )
                                    let offset = BKPoint(x: 0.0, y: 0.0)
                                    for curve in curves {
                                        Draw.setRandomColor(context)
                                        Draw.drawCurve(context, curve: curve, offset: offset)
                                    }
                                    Draw.setColor(context, color: Draw.black)
                                    Draw.drawCircle(context, center: curves[0].points[0], radius: 3, offset: offset)
                                    Draw.drawCircle(context, center: curves[0].points[3], radius: 3, offset: offset)
                                    Draw.drawCircle(context, center: B, radius: 3, offset: offset)
                                }
    })
    static let demo3 = Demo(title: ".getLUT(steps)",
                            quadraticControlPoints: quadraticControlPoints,
                            cubicControlPoints: cubicControlPoints,
                            drawFunction: {(context: CGContext, demoState: DemoState) in
                                let curve = demoState.curve!
                                Draw.drawSkeleton(context, curve: curve)
                                let LUT = curve.generateLookupTable(withSteps: 16)
                                for p in LUT {
                                    Draw.drawCircle(context, center: p, radius: 2)
                                }
    })
    static let demo4 = Demo(title: ".length()",
                            quadraticControlPoints: quadraticControlPoints,
                            cubicControlPoints: [CGPoint(x: 100, y: 25), CGPoint(x: 10, y: 90), CGPoint(x: 110, y: 100), CGPoint(x: 132, y: 192)],
                            drawFunction: {(context: CGContext, demoState: DemoState) in
                                let curve = demoState.curve!
                                Draw.drawSkeleton(context, curve: curve)
                                Draw.drawCurve(context, curve: curve)
                                Draw.setColor(context, color: Draw.red)
                                let arclength = curve.length()
                                let offset = curve.offset(distance: -10)
                                let last = offset.count-1
                                for idx in 0 ..< offset.count {
                                    let c = offset[idx]
                                    Draw.drawCurve(context, curve: c)
                                    if(idx==last) {
                                        let p1 = curve.offset(t: 0.95, distance: -15)
                                        let p2 = c.compute(1)
                                        let p3 = curve.offset(t: 0.95, distance: -5)
                                        Draw.drawLine(context, from: p1, to: p2)
                                        Draw.drawLine(context, from: p2, to: p3)
                                        let label = String(format: "%3.1fpt", arclength)
                                        Draw.drawText(context, text: label, offset: BKPoint(x: p2.x+7, y: p2.y-3))
                                    }
                                }
    })
    static let demo5 = Demo(title: ".get(t) and .compute(t)",
                            quadraticControlPoints: quadraticControlPoints,
                            cubicControlPoints: cubicControlPoints,
{'fraction_non_alphanumeric': 0.08490796050225527, 'fraction_numerical': 0.02194319151529928, 'mean_word_length': 0.94441810855653, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 170, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3602442', 'n_tokens_mistral': 4129, 'n_tokens_neox': 3728, 'n_words': 973}