Dafny function returning a set of points - dafny

Let Rectangle and Pair be Dafny datatypes that are defined as follows :
datatype Rectangle = rect(pos: Pair, width: int, height: int)
datatype Pair = pair(x: int, y: int)
One mathematical abstraction/representation for this rectangle, which I would like to code in Dafny, is the set of all points (i,j) that this rectangle contains. For example the rectangle rect(pos:(5,5), width=2, height=3) represents the set of points : {(5,5), (6,5), (7,5), (5,6), (6,6), (7,6)}
Let abs be a function method (one line method) that returns this abstraction in the form of a set<Pair>, given a variable of type Rectangle
function method abs(rect: Rectangle): set<Pair>
{
//..?
}
Does anyone know how to express this set in one line in Dafny?

Your example seems to swap the meaning of height and width that I'd expect, but here's a solution:
function method abs(rect: Rectangle): set<Pair>
{
set x:int, y:int | 0 <= x - rect.pos.x < rect.height &&
0 <= y - rect.pos.y < rect.width :: pair(x, y)
}
The following lemma demonstrates that the solution satisfies your test case:
lemma lemma_Test()
{
var r := rect(pair(5, 5), 2, 3);
var s := abs(r);
assert s == {pair(5,5), pair(6,5), pair(7,5), pair(5,6),
pair(6,6), pair(7,6)};
}

Related

Calculating if CGPoint is on a line segment?

I'm looking for a way to calculate if a CGPoint is on a line segment. Are there any built-in methods in Swift or any of Apple's libraries?
I don't mind converting to a different type as long as it is part of Apple's code (e.g. similar to how instead of performing complex calculations on double4x4 matrix, you can convert it to an SCNNode).
I quickly came up with brute force solution, but it's neither elegant, nor accurate (given floating point comparisons everywhere):
extension CGPoint {
func isOnLineSegment(start: CGPoint, end: CGPoint) -> Bool {
func value(_ value: CGFloat, isBetween one: CGFloat, and two: CGFloat) -> Bool {
let a = [one, two].sorted()
return a[0] <= value && value <= a[1]
}
let slope = (end.y - start.y) / (end.x - start.x)
if slope.isInfinite {
let isOnLine = x.isNearlyEqual(to: start.x)
let isWithinYValues = value(y, isBetween: start.y, and: end.y)
return isOnLine && isWithinYValues
}
let isOnLine = y.isNearlyEqual(to: slope * (x - start.x) + start.y) // y = m * (x - x1) + y1
let isWithinXValues = value(x, isBetween: start.x, and: end.x)
return isOnLine && isWithinXValues
}
}
A possible approach is to transform the whole configuration such that the start point of the segment is transformed to the origin, and the end point is transformed to the point (1, 0). This can be done with a CGAffineTransformation. The problem then reduces to determining if the given point is on the line segment between (0, 0) and (1,0). Here is a possible implementation:
extension CGPoint {
func isOnLineSegment(start: CGPoint, end: CGPoint) -> Bool {
// Transformation which maps (0,0) to start and (1, 0) to end:
let t = CGAffineTransform(a: end.x - start.x, b: end.y - start.y,
c: start.y - end.y, d: end.x - start.x,
tx: start.x, ty: start.y)
// Apply the inverse transformation to our point:
let q = self.applying(t.inverted())
// Check (with some tolerance) if q is on the segment from (0, 0) to (1, 0):
let eps = CGFloat.ulpOfOne.squareRoot()
return q.x > -eps && q.x < 1.0 + eps && q.y.magnitude < eps
}
}
As tolerance I chose the square root of .ulpOfOne (as suggested here), but you can adjust it to your needs.
Another approach is to use the fact that a point P is on the line segment from P1 to P2 exactly if
| P - P1 | + | P - P2 | = | P1 - P2 |
where | . | denotes the (Euclidean) distance:
extension CGPoint {
func distance(to p: CGPoint) -> CGFloat {
return hypot(p.x - self.x, p.y - self.y)
}
func isOnLineSegment(start: CGPoint, end: CGPoint) -> Bool {
let eps = CGFloat.ulpOfOne.squareRoot()
return self.distance(to: start) + self.distance(to: end) <= start.distance(to: end) + eps
}
}
If you fear floating-point inaccuracies, you'd better compute the distance to the line segment and check if it falls under a tolerance. (I will not expand on how to select this tolerance.)
An efficient computation scheme is as follows, using complex numbers (I use them for convenience, but there are equivalent vector forms, or just scalar expressions):
translate one of the endpoints to the origin (now the segment is 0 to P1-P0 and the tested point is Q-P0);
rotate to make the segment horizontal; for this, you multiply by (R:= (P1-P0)*/|P1-P0|, where * denotes the complex conjugate.
now the real part of (Q-P0).R tells you if the point projects to the segment (when 0≤Im≤|P1-P0|).
if yes, the imaginary part is the distance to the segment;
if no, compute the distance to the nearest endpoint (you know which by looking at the above real part).
The picture illustrates the three different cases to get the distance to the segment (transformed points).
Technical notes:
Depending on your needs, you can adopt different strategies for the handling of the endpoints:
a point past the endpoint can be considered outside the segment;
a point past the endpoint horizontally by more than the tolerance can be considered outside the segment;
a point past the endpoint obliquely by more than the tolerance can be considered outside the segment.
These options correspond to acceptance domains with respective shapes being tight rectangle, larger rectangle and rounded rectangle.
This method preserves scale, making the tolerance an absolute distance criterion.

F# FS0001: This Expression was expected to have type figure, but her has type int*int

I am currently working on a program that is supposed to take a 'figure' and move it along a vector. For this I have created the function 'move' which takes a 'figure' and a vector.
I am then trying to use pattern-matching to update the values of the figure.
type point = (int*int)
type figure =
|Circle of point * int * string
|Rectangle of point * point * string
|Mix of figure * figure
let circ = Circle((50,50),45,"Red")
let rect = Rectangle((40,40),(90,110),"Blue")
let figTest : figure = Mix(circ,rect)
I have the above types and the starting figure, 'figTest'.
I then call 'move figTest', but it gives the error FS0001: This expression was expected to have type 'figure' but here has type 'int * int -> figure'.
let rec move figure (v:int*int) : figure=
let vx = fst v
let vy = snd v
match figure with
| Circle ((cx,cy) , radius, colour) -> Circle(point(cx + vx, cy-vy), radius, colour)
| Rectangle((x0,y0), (x1,y1), colour) -> Rectangle(point(x0 + vx, y0 + vy),point(x1 + vx, y1 + vy), colour)
| Mix(f1,f2) ->
let newCirc = move(f1)
let newRect = move(f2)
let newFig = Mix(newCirc, newRect)
newFig
The error seems to occur when i give 'newFig' the new circle and rectangle, but I can't quite figure out what is wrong. I struggle quite a bit with these type errors in f# pretty often, so I thought I was getting the hang of it, but I just can't find the cause of this...
This is very close to working, so don't get discouraged. There are two minor problems:
When you call move recursively, you have to pass v again. So let newCirc = move f1 v is correct instead of let newCirc = move(f1). (Note that newCirc might not actually be a circle, so you might want to use a different variable name.)
Since point is just a synonym for int * int, it doesn't have its own constructor function. So (cx + vx, cy-vy) is correct instead of point(cx + vx, cy-vy).
When I made these two changes, your code worked correctly for me. There are a number of other issues with your code that you might want to address, but those are the only two that are show-stoppers at this point.

F# Incomplete Structured Construct Caused By Type Specification

So, I have a function, corners, that I want to take a 2D array (with abbreviated type HieghtMap) and return a list of the record type of Coordinates. Initially, I wasn't specifying matrixLocal's type, which led to
System.Exception: Operation could not be completed due to earlier error
 The type 'matrixLocal' is not defined. at 30,28
Now that I am specifying the type, I get this new error
 Syntax error in labelled type argument at 30,39
Incomplete structured construct at or before this point in
interaction. Expected incomplete structured construct at or before
this point, ';', ';;' or other token.
I believe this is due to farside (as it does not function even on its own), but I do not know why, hence I am here. The other questions that I found regarding the latter error do not seem to apply in this case (one was about indenting, and the other was about trying to redefine a variable in a loop).
The Code:
module DiamondSquare =
//create type for defining shapes
///Defined by length of the side of a square that the ovject is inscribed in
type Shape =
| Square of int
| Diamond of int
///the X and Y position
type Coordinates = {X: int; Y: int}
///The Hieghtmap of a given chunk of region as a series of floats that are the offset from the base hieght
//was HieghtMap = HieghtMap of float[,], but was changed so that any 2D float array would be accepted
type HieghtMap = float[,]
//Create matrix of zeroes of chunk size to initilize this variable
let matrix = Array2D.zeroCreate<float> 9 9
//locate center of shape
// since each shape is a square, or can be inscribed within one, pass it a matrix and find the
// coordinate of the center (same value for i and j)
///Finds center of shape inscribed within a square. Takes a matrix, returns coordinates for within the matrix
let locateCenterpoint matrixLocal =
let coord = int ((Array2D.length1 matrixLocal) - 1) / 2
{X = coord; Y = coord;}
//locate corners of a shape that is inscribed in a square
///Returns list of corner values for a given shape. Takes a matrix and returns a list of Coordinates
let corners shape:Shape matrixLocal:HieghtMap =
let farSide = Array2D.length1 matrixLocal - 1
let getSquareCorners =
{X = 0; Y = 0}::{X = farSide; Y = 0}::{X = 0; Y = farSide}::{X = farSide; Y = farSide}::[]
let getDiamondCorners =
{X = farSide / 2; Y = 0}::{X = farSide; Y = farSide / 2}::{X = farSide / 2; Y = farSide}::{X = 0; Y = farSide / 2}::[]
match shape with
| Square -> getSquareCorners
| Diamond -> getDiamondCorners
| _ -> None
When defining a value in F#, the first colon signifies the end of value names and start of the type declaration. For example:
let f x y : string = ...
In this declaration, string is the return type of the function, and not type of the y parameter. In order to apply type declaration to a single value in the list, use parentheses:
let f x (y: string) = ...
This way, string is the type of y.
For your specific case, look at this line:
let corners shape:Shape matrixLocal:HieghtMap =
See what the problem is? Shape is being parsed as the return type of the corners function, and this makes the subsequent matrixLocal:HeightMap nonsensical. To fix, apply parentheses:
let corners (shape:Shape) (matrixLocal:HieghtMap) =

How to use this complex parametric equation to draw curve in iOS

just found this demo code to using parametric equation draw in iOS
you can see that key code is to generate this array of points
let points: [CGPoint] = 0.stride(to: M_PI * 2, by: 0.01).map
{
let x = pow(sin($0), 3)
var y = 13 * cos($0)
y -= 5 * cos(2 * $0)
y -= 2 * cos(3 * $0)
y -= cos(4 * $0)
y /= 16
return CGPoint(x: 320 + (x * 300), y: 280 + (y * -300))
}
which is just using this equation
now what I want to draw is more complex one mao curve
but the problem I encounter is there is a mathematic sign in the parametric equation provided by the site that I don't know how to convert to iOS code, this one
UPDATE: now I encounter a new problem: "Expression was too complex to be solved in reasonable time", any idea besides break it down into small expression like the heart curve did in its y above, because manually break it down it's too overwhelming
and the whole code is list below
func sgn(t: Double) -> Double{
switch t {
case _ where t < 0:
return -1.0
case _ where t > 0:
return 1.0
default:
return 0.0
}
}
func theta(t: Double) -> Double {
switch t {
case _ where t < 0:
return 0.0
case _ where t > 0:
return 1.0
default:
return 0.5
}
}
let pi = M_PI
let layer = CAShapeLayer()
layer.lineCap = kCALineCapRound
layer.lineJoin = kCALineCapRound
self.view.layer.addSublayer(layer)
let points: [CGPoint] = 0.stride(to: M_PI * 2, by: 0.01).map
{ t in
var x = ((-10/47*sin(30/41-17*t)-11/4*sin(83/58-15*t)-47/17*sin(79/53-13*t)+21080/33*sin(t+63/40)+179/32*sin(2*t+28/17)+263/25*sin(3*t+85/54)+1552/47*sin(4*t+146/31)+2015/77*sin(5*t+30/19)+286/31*sin(6*t+117/25)+1308/17*sin(7*t+67/42)+158/37*sin(8*t+77/17)+1017/26*sin(9*t+61/38)+107/18*sin(10*t+79/46)+863/39*sin(11*t+29/18)+74/23*sin(12*t+12/7)+110/63*sin(14*t+163/35)+29/31*sin(16*t+75/41)+2/7*sin(18*t+64/25)+305/37*sin(19*t+18/11)+9/34*sin(20*t+91/32)+316/45*sin(21*t+64/39)+16/15*sin(22*t+119/27)+179/35*sin(23*t+23/14)+38/51*sin(24*t+131/65)+1969/19)*theta(103*pi-t)*theta(t-99*pi)+(-44/31*sin(81/52-6*t)-47/19*sin(14/9-5*t)-206/75*sin(39/25-4*t)-77/16*sin(69/44-3*t)-416/25*sin(25/16-2*t)-1496/19*sin(47/30-t)-3315/19)*theta(99*pi-t)*theta(t-95*pi)+(732/7*sin(t+41/26)+111/17*sin(2*t+18/11)+187/20*sin(3*t+43/27)+37/24*sin(4*t+44/27)+157/45*sin(5*t+59/37)+5507/30)*theta(95*pi-t)*theta(t-91*pi)+(-19/42*sin(37/24-2*t)+3067/18*sin(t+11/7)+281/16*sin(3*t+96/61)+13/27*sin(4*t+159/34)+215/38*sin(5*t+30/19)+1121/34)*theta(91*pi-t)*theta(t-87*pi)+(-1/20*sin(17/14-16*t)+3995/36*sin(t+11/7)+353/25*sin(2*t+69/44)+209/18*sin(3*t+11/7)+349/66*sin(4*t+49/31)+67/17*sin(5*t+43/27)+84/43*sin(6*t+60/37)+79/30*sin(7*t+149/93)+93/38*sin(8*t+30/19)+37/22*sin(9*t+74/47)+91/57*sin(10*t+68/43)+43/29*sin(11*t+43/27)+42/23*sin(12*t+45/28)+28/31*sin(13*t+77/47)+17/36*sin(14*t+41/25)+17/86*sin(15*t+8/5)+12/29*sin(17*t+65/42)+11/31*sin(18*t+49/31)+31/47*sin(19*t+45/28)+13/31*sin(20*t+33/20)+5/43*sin(21*t+168/37)+9/46*sin(22*t+109/68)+26/29*sin(23*t+41/26)+31/47*sin(24*t+43/27)+5/21*sin(25*t+50/31)+2855/14)*theta(87*pi-t)*theta(t-83*pi)+(-5/33*sin(32/21-24*t)-16/17*sin(20/13-23*t)-64/39*sin(80/51-17*t)-1/28*sin(14/9-15*t)+3240/31*sin(t+11/7)+341/25*sin(2*t+52/33)+888/71*sin(3*t+63/40)+286/191*sin(4*t+31/19)+170/29*sin(5*t+68/43)+18/29*sin(6*t+80/17)+67/23*sin(7*t+91/58)+2/33*sin(8*t+36/31)+19/36*sin(9*t+51/32)+23/28*sin(10*t+21/13)+39/34*sin(11*t+65/41)+3/26*sin(12*t+39/20)+47/43*sin(13*t+37/23)+1/117*sin(14*t+825/206)+58/35*sin(16*t+47/30)+34/19*sin(18*t+62/39)+27/29*sin(19*t+127/27)+3/28*sin(20*t+245/52)+54/37*sin(21*t+53/33)+23/31*sin(22*t+21/13)-6998/27)*theta(83*pi-t)*theta(t-79*pi)+(2069/16*sin(t+11/7)+82/21*sin(2*t+14/3)+443/29*sin(3*t+19/12)+79/30*sin(4*t+30/19)+148/29*sin(5*t+19/12)+27/25*sin(6*t+33/20)+73/31*sin(7*t+27/17)+8893/37)*theta(79*pi-t)*theta(t-75*pi)+(-11/32*sin(31/22-2*t)+4451/49*sin(t+11/7)+515/68*sin(3*t+102/65)+1/20*sin(4*t+9/13)+79/30*sin(5*t+47/30)+17/37*sin(6*t+11/7)+47/30*sin(7*t+107/68)-10305/46)*theta(75*pi-t)*theta(t-71*pi)+(-5/24*sin(74/59-26*t)-22/25*sin(16/11-23*t)-5/29*sin(29/25-20*t)-62/41*sin(46/31-17*t)-48/25*sin(20/13-15*t)-113/24*sin(38/25-12*t)-231/40*sin(39/25-9*t)-89/39*sin(47/32-7*t)-104/19*sin(48/31-5*t)-182/15*sin(37/24-4*t)-140/19*sin(31/20-2*t)+3287/23*sin(t+107/68)+564/23*sin(3*t+113/24)+8/3*sin(6*t+13/8)+241/30*sin(8*t+37/23)+71/30*sin(10*t+14/9)+17/12*sin(11*t+44/27)+16/25*sin(13*t+67/39)+10/11*sin(14*t+81/52)+3*sin(16*t+21/13)+17/14*sin(18*t+127/27)+56/39*sin(19*t+117/73)+41/44*sin(21*t+159/34)+54/65*sin(22*t+27/17)+17/35*sin(24*t+159/34)+5/27*sin(25*t+44/29)-17/10)*theta(71*pi-t)*theta(t-67*pi)+(1987/31*sin(t+11/7)+305/28*sin(2*t+80/17)+751/28*sin(3*t+11/7)+191/30*sin(4*t+30/19)+313/33*sin(5*t+63/40)+122/73*sin(6*t+127/27)+113/34*sin(7*t+41/26)+23/30*sin(8*t+11/7)+73/27*sin(9*t+68/43)+3943/17)*theta(67*pi-t)*theta(t-63*pi)+(1593/29*sin(t+179/38)+191/29*sin(2*t+127/27)+678/97*sin(3*t+113/24)+44/19*sin(4*t+169/36)+63/34*sin(5*t+108/23)+17/16*sin(6*t+75/16)-6319/33)*theta(63*pi-t)*theta(t-59*pi)+(-9/29*sin(32/51-88*t)-39/29*sin(64/41-85*t)-19/27*sin(114/115-26*t)-30/43*sin(45/31-21*t)-14/11*sin(42/29-15*t)-13/38*sin(20/33-9*t)+15919/28*sin(t+39/25)+5859/34*sin(2*t+61/13)+1289/20*sin(3*t+229/49)+899/26*sin(4*t+26/17)+315/16*sin(5*t+145/31)+707/104*sin(6*t+26/17)+71/20*sin(7*t+3/2)+142/17*sin(8*t+188/41)+182/31*sin(10*t+28/19)+69/43*sin(11*t+356/79)+84/19*sin(12*t+55/39)+376/51*sin(13*t+87/62)+89/13*sin(14*t+67/46)+152/27*sin(16*t+69/47)+73/20*sin(17*t+57/43)+13/9*sin(18*t+3/2)+5/34*sin(19*t+70/41)+19/9*sin(20*t+47/36)+143/43*sin(22*t+43/33)+191/30*sin(23*t+31/24)+107/23*sin(24*t+35/27)+78/25*sin(25*t+32/25)+139/33*sin(27*t+43/33)+155/37*sin(28*t+43/33)+375/47*sin(29*t+141/106)+16/25*sin(30*t+145/38)+265/18*sin(31*t+232/53)+849/29*sin(32*t+61/14)+451/18*sin(33*t+204/47)+18/13*sin(34*t+327/77)+453/19*sin(35*t+6/5)+821/39*sin(36*t+43/37)+371/48*sin(37*t+37/32)+139/29*sin(38*t+107/25)+67/12*sin(39*t+343/78)+1033/100*sin(40*t+38/33)+435/59*sin(41*t+46/45)+327/43*sin(42*t+37/32)+264/53*sin(43*t+55/13)+19/35*sin(44*t+51/77)+771/71*sin(45*t+35/32)+85/24*sin(46*t+11/12)+30/23*sin(47*t+67/40)+139/22*sin(48*t+109/26)+170/41*sin(49*t+46/41)+195/32*sin(50*t+46/51)+154/71*sin(51*t+41/34)+63/17*sin(52*t+54/13)+42/25*sin(53*t+91/24)+185/77*sin(54*t+17/30)+773/103*sin(55*t+16/15)+68/11*sin(56*t+73/17)+113/24*sin(57*t+48/35)+351/53*sin(58*t+92/21)+643/60*sin(59*t+65/59)+153/23*sin(60*t+193/45)+62/25*sin(61*t+66/47)+37/33*sin(62*t+31/8)+79/20*sin(63*t+153/35)+213/25*sin(64*t+25/23)+721/68*sin(65*t+59/14)+237/28*sin(66*t+33/29)+20/7*sin(67*t+131/28)+242/41*sin(68*t+31/32)+57/86*sin(69*t+1/21)+86/21*sin(70*t+147/38)+203/102*sin(71*t+12/17)+159/47*sin(72*t+29/35)+23/16*sin(73*t+400/87)+28/25*sin(74*t+87/34)+377/113*sin(75*t+177/43)+173/61*sin(76*t+29/31)+25/21*sin(77*t+7/17)+69/19*sin(78*t+94/25)+34/33*sin(79*t+19/5)+9/28*sin(80*t+199/83)+140/93*sin(81*t+178/39)+339/127*sin(82*t+61/48)+107/20*sin(83*t+125/31)+81/20*sin(84*t+29/32)+27/26*sin(86*t+47/14)+9/25*sin(87*t+15/19)+149/75*sin(89*t+45/89)+29/21*sin(90*t+151/44)+75/26*sin(91*t+251/66)+50/21*sin(92*t+23/32)+62/55*sin(93*t+8/63)+23/11*sin(94*t+55/16)+51/26*sin(95*t+257/72)+38/25*sin(96*t+227/57)+314/209*sin(97*t+15/37)+11/9*sin(98*t+416/119)+11584/59)*theta(59*pi-t)*theta(t-55*pi)+(-43/31*sin(53/34-18*t)-58/35*sin(61/39-17*t)-55/19*sin(36/23-16*t)-155/59*sin(61/39-15*t)-45/19*sin(41/27-9*t)-46/13*sin(95/61-8*t)-360/23*sin(58/37-7*t)-77/15*sin(53/34-4*t)+27845/41*sin(t+91/58)+259/26*sin(2*t+212/45)+7843/86*sin(3*t+146/31)+2557/50*sin(5*t+146/31)+3931/786*sin(6*t+271/58)+31/23*sin(10*t+174/37)+79/24*sin(11*t+75/16)+86/47*sin(12*t+135/29)+97/24*sin(13*t+174/37)+76/29*sin(14*t+136/29)+30867/253)*theta(55*pi-t)*theta(t-51*pi)+(-5/31*sin(1/3-12*t)-23/52*sin(119/99-11*t)-166/33*sin(17/12-4*t)-196/41*sin(123/88-3*t)+327/34*sin(t+155/58)+297/40*sin(2*t+35/17)+35/44*sin(5*t+142/61)+3/5*sin(6*t+5/19)+11/19*sin(7*t+19/25)+23/58*sin(8*t+67/31)+12/31*sin(9*t+62/45)+5/12*sin(10*t+57/32)+27/13)*theta(51*pi-t)*theta(t-47*pi)+(2957/51*sin(t+7/22)+296/41)*theta(47*pi-t)*theta(t-43*pi)+(-1/2*sin(46/37-12*t)-233/35*sin(58/41-6*t)-491/47*sin(12/13-4*t)-227/12*sin(26/29-2*t)+7589/21*sin(t+23/18)+825/43*sin(3*t+19/24)+103/39*sin(5*t+7/12)+29/37*sin(7*t+43/14)+69/20*sin(8*t+130/31)+17/14*sin(9*t+137/56)+16/25*sin(10*t+129/37)+28/41*sin(11*t+71/29)+18979/130)*theta(43*pi-t)*theta(t-39*pi)+(-13/48*sin(31/24-7*t)-7/24*sin(29/25-6*t)-35/18*sin(59/69-2*t)+127/34*sin(t+7/55)+107/42*sin(3*t+94/21)+319/62*sin(4*t+569/122)+59/28*sin(5*t+22/13)+1/16*sin(8*t+139/37)+6/23*sin(9*t+4/27)+5/19*sin(10*t+119/41)+3/25*sin(11*t+44/19)+3/17*sin(12*t+338/89)-1419/7)*theta(39*pi-t)*theta(t-35*pi)+(-15/104*sin(31/38-10*t)-8/27*sin(26/29-8*t)-66/35*sin(4/23-4*t)-102/47*sin(41/36-t)+133/46*sin(2*t+31/13)+219/28*sin(3*t+93/35)+31/28*sin(5*t+182/67)+20/23*sin(6*t+5/38)+39/77*sin(7*t+119/53)+6/17*sin(9*t+95/28)+3/11*sin(11*t+73/24)+1/15*sin(12*t+26/29)+9908/49)*theta(35*pi-t)*theta(t-31*pi)+(-17/36*sin(29/32-3*t)-73/122*sin(53/38-2*t)+537/20*sin(t+5/4)+7/32*sin(4*t+184/41)+13/31*sin(5*t+21/5)+3/43*sin(6*t+9/22)+4507/22)*theta(31*pi-t)*theta(t-27*pi)+(-15/32*sin(40/31-6*t)-2/9*sin(2/7-5*t)-14/17*sin(73/55-4*t)-43/28*sin(50/37-2*t)+727/27*sin(t+20/17)+17/15*sin(3*t+4/35)-1416/7)*theta(27*pi-t)*theta(t-23*pi)+(-17/39*sin(35/33-16*t)-15/13*sin(5/8-14*t)-115/67*sin(52/35-10*t)-115/37*sin(11/45-7*t)-136/43*sin(26/25-6*t)-703/43*sin(41/28-4*t)-506/35*sin(1/114-3*t)-1405/34*sin(34/29-2*t)+413/48*sin(t+149/39)+241/32*sin(5*t+55/46)+195/44*sin(8*t+298/85)+73/27*sin(9*t+79/33)+59/28*sin(11*t+132/35)+13/22*sin(12*t+202/47)+11/20*sin(13*t+55/21)+99/74*sin(15*t+125/28)+5740/9)*theta(23*pi-t)*theta(t-19*pi)+(-23/26*sin(11/54-8*t)-112/29*sin(9/23-5*t)+137/33*sin(t+68/45)+33/19*sin(2*t+234/55)+604/57*sin(3*t+325/324)+541/47*sin(4*t+47/27)+36/19*sin(6*t+143/35)+37/28*sin(7*t+7/4)+26/33*sin(9*t+57/20)+24/49*sin(10*t+15/32)+1/8*sin(11*t+69/16)+17/42*sin(12*t+21/22)+901/40)*theta(19*pi-t)*theta(t-15*pi)+(4831/29*sin(t+46/29)+100/53*sin(2*t+38/29)+471/28*sin(3*t+49/29)+71/31*sin(4*t+95/31)+212/33*sin(5*t+38/25)+35/39*sin(6*t+164/55)+1163/291*sin(7*t+65/38)+14/23*sin(8*t+73/18)+467/36)*theta(15*pi-t)*theta(t-11*pi)+(-1/2*sin(4/25-8*t)-17/23*sin(1/20-6*t)-46/29*sin(1/12-4*t)-29/15*sin(36/37-2*t)+3308/37*sin(t+28/19)+576/67*sin(3*t+46/37)+87/25*sin(5*t+23/21)+78/47*sin(7*t+22/21)+3643/17)*theta(11*pi-t)*theta(t-7*pi)+(-41/20*sin(12/11-5*t)+9878/119*sin(t+76/33)+71/22*sin(2*t+133/29)+267/31*sin(3*t+76/21)+55/32*sin(4*t+3/31)+89/88*sin(6*t+23/24)+40/53*sin(7*t+3/25)+44/87*sin(8*t+34/11)+6/13*sin(9*t+40/27)-7131/31)*theta(7*pi-t)*theta(t-3*pi)+(-24/31*sin(16/17-16*t)-149/41*sin(50/37-9*t)-133/52*sin(23/32-8*t)-303/32*sin(1/734-7*t)+10523/20*sin(t+32/23)+431/20*sin(2*t+31/10)+1144/27*sin(3*t+139/36)+456/47*sin(4*t+81/34)+390/47*sin(5*t+146/81)+158/33*sin(6*t+14/27)+41/35*sin(10*t+43/20)+29/19*sin(11*t+82/33)+64/41*sin(12*t+42/31)+67/43*sin(13*t+47/43)+16/35*sin(14*t+41/20)+49/73*sin(15*t+59/88)+2388/37)*theta(3*pi-t)*theta(t+pi))*theta(sqrt(sgn(sin(t/2))))
var y = ((-407/57*sin(35/24-24*t)-42/31*sin(41/28-23*t)-49/16*sin(67/46-22*t)-26/37*sin(38/31-21*t)-76/35*sin(59/39-20*t)-310/73*sin(43/28-18*t)-11*sin(44/29-13*t)-580/41*sin(32/21-10*t)-3258/65*sin(63/41-9*t)-252/17*sin(56/37-8*t)-6254/51*sin(17/11-6*t)-1481/27*sin(71/46-5*t)-465/32*sin(73/47-3*t)+3651/50*sin(t+30/19)+8318/27*sin(2*t+30/19)+134/21*sin(4*t+127/27)+807/19*sin(7*t+19/12)+252/11*sin(11*t+155/97)+139/32*sin(12*t+49/30)+417/38*sin(14*t+51/31)+149/38*sin(15*t+117/70)+173/24*sin(16*t+13/8)+16/7*sin(17*t+12/7)+62/43*sin(19*t+87/56)-18494/25)*theta(103*pi-t)*theta(t-99*pi)+(-80/29*sin(47/30-5*t)-177/25*sin(113/72-3*t)-1901/33*sin(47/30-t)+599/31*sin(2*t+52/33)+77/41*sin(4*t+14/9)+11/9*sin(6*t+61/39)+2609/12)*theta(99*pi-t)*theta(t-95*pi)+(-1566/241*sin(58/37-3*t)-1857/50*sin(47/30-t)+464/31*sin(2*t+11/7)+59/24*sin(4*t+11/7)+20/17*sin(5*t+136/29)+7997/31)*theta(95*pi-t)*theta(t-91*pi)+(-15/29*sin(67/43-5*t)-129/25*sin(36/23-4*t)-148/61*sin(36/23-3*t)-103/33*sin(69/44-2*t)-29/17*sin(80/51-t)-4753/32)*theta(91*pi-t)*theta(t-87*pi)+(-24/19*sin(32/21-25*t)-229/98*sin(48/31-22*t)-83/31*sin(54/35-19*t)-37/9*sin(31/20-17*t)-46/19*sin(36/23-14*t)-71/23*sin(25/16-12*t)-29/19*sin(57/37-10*t)-49/15*sin(25/16-7*t)-396/113*sin(14/9-5*t)-181/36*sin(36/23-4*t)-176/25*sin(47/30-3*t)-1055/57*sin(80/51-2*t)-353/21*sin(113/72-t)+17/43*sin(6*t+63/40)+1/36*sin(8*t+1/22)+9/34*sin(9*t+50/33)+113/38*sin(11*t+47/30)+5/8*sin(13*t+27/17)+45/38*sin(15*t+174/37)+11/8*sin(16*t+61/39)+188/31*sin(18*t+19/12)+16/27*sin(20*t+61/13)+5/17*sin(21*t+23/13)+39/22*sin(23*t+68/43)+12/13*sin(24*t+25/16)+12966/29)*theta(87*pi-t)*theta(t-83*pi)+(-101/25*sin(23/15-23*t)-223/46*sin(25/16-19*t)-603/116*sin(80/51-17*t)-45/58*sin(14/9-15*t)-77/41*sin(65/42-11*t)-1/36*sin(59/98-10*t)-108/25*sin(47/30-9*t)-110/41*sin(39/25-7*t)-2479/826*sin(14/9-6*t)-166/33*sin(69/44-4*t)-266/23*sin(69/44-t)+62/33*sin(2*t+146/31)+1/7*sin(3*t+38/27)+1/64*sin(5*t+6/35)+27/23*sin(8*t+37/24)+49/40*sin(12*t+179/38)+39/11*sin(13*t+65/41)+53/71*sin(14*t+80/17)+255/98*sin(16*t+36/23)+110/17*sin(18*t+49/31)+8/33*sin(20*t+31/22)+38/11*sin(21*t+50/31)+35/32*sin(22*t+47/29)+11/23*sin(24*t+69/44)+52347/113)*theta(83*pi-t)*theta(t-79*pi)+(-128/59*sin(36/23-6*t)-75/29*sin(36/23-4*t)-853/40*sin(47/30-2*t)-1601/43*sin(102/65-t)+139/25*sin(3*t+39/25)+99/38*sin(5*t+19/12)+32/19*sin(7*t+81/52)+10547/30)*theta(79*pi-t)*theta(t-75*pi)+(-1/19*sin(57/37-7*t)+129/38*sin(t+41/26)+952/47*sin(2*t+212/45)+23/12*sin(3*t+169/36)+77/19*sin(4*t+146/31)+27/40*sin(5*t+35/22)+61/36*sin(6*t+146/31)+23311/66)*theta(75*pi-t)*theta(t-71*pi)+(-217/87*sin(49/32-8*t)+4673/114*sin(t+52/33)+1582/25*sin(2*t+30/19)+271/26*sin(3*t+65/41)+1036/29*sin(4*t+65/41)+151/43*sin(5*t+221/47)+240/19*sin(6*t+30/19)+277/31*sin(7*t+179/38)+346/35*sin(9*t+77/48)+136/23*sin(10*t+52/33)+41/13*sin(11*t+75/16)+29/23*sin(12*t+64/39)+23/35*sin(13*t+29/21)+5/27*sin(14*t+79/23)+12/31*sin(15*t+59/38)+41/16*sin(16*t+50/31)+17/30*sin(17*t+52/29)+5/17*sin(18*t+67/43)+23/25*sin(19*t+127/27)+43/38*sin(20*t+29/18)+11/17*sin(21*t+96/59)+23/45*sin(22*t+50/31)+13/44*sin(23*t+49/11)+20/33*sin(24*t+56/37)+1/12*sin(25*t+127/33)+4/27*sin(26*t+34/19)+3826/57)*theta(71*pi-t)*theta(t-67*pi)+(-67/36*sin(47/30-9*t)-629/118*sin(53/34-5*t)-49/30*sin(58/39-2*t)+7133/32*sin(t+245/52)+397/23*sin(3*t+146/31)+43/31*sin(4*t+48/31)+7/16*sin(6*t+50/33)+190/73*sin(7*t+245/52)+9/26*sin(8*t+18/11)-1822/15)*theta(67*pi-t)*theta(t-63*pi)+(4511/50*sin(t+179/38)+503/126*sin(2*t+65/41)+53/6*sin(3*t+179/38)+78/47*sin(4*t+51/32)+282/83*sin(5*t+80/17)+27/47*sin(6*t+51/32)+613/27)*theta(63*pi-t)*theta(t-59*pi)+(-8/9*sin(7/17-85*t)-12/17*sin(13/9-81*t)-22/31*sin(49/39-75*t)-29/41*sin(3/8-73*t)-22/19*sin(29/43-69*t)-31/47*sin(39/32-12*t)+353/3*sin(t+202/43)+4111/19*sin(2*t+61/13)+956/25*sin(3*t+14/9)+533/20*sin(4*t+89/19)+167/21*sin(5*t+183/40)+116/25*sin(6*t+131/28)+139/22*sin(7*t+55/36)+231/25*sin(8*t+149/32)+199/23*sin(9*t+70/47)+121/39*sin(10*t+649/139)+12/35*sin(11*t+66/35)+43/25*sin(13*t+17/11)+25/12*sin(14*t+79/17)+91/27*sin(15*t+41/29)+23/32*sin(16*t+205/44)+17/31*sin(17*t+121/27)+99/28*sin(18*t+114/25)+73/47*sin(19*t+19/13)+27/32*sin(20*t+193/43)+9/14*sin(21*t+64/33)+12/37*sin(22*t+197/46)+32/51*sin(23*t+119/29)+179/36*sin(24*t+190/43)+143/46*sin(25*t+131/30)+85/43*sin(26*t+146/33)+42/31*sin(27*t+536/119)+99/100*sin(28*t+108/23)+158/53*sin(29*t+76/65)+227/27*sin(30*t+27/23)+421/23*sin(31*t+17/14)+499/29*sin(32*t+65/54)+281/26*sin(33*t+73/61)+17/36*sin(34*t+78/17)+75/7*sin(35*t+178/41)+460/27*sin(36*t+125/29)+515/34*sin(37*t+73/17)+363/43*sin(38*t+179/42)+376/51*sin(39*t+412/97)+163/23*sin(40*t+38/9)+439/53*sin(41*t+174/41)+161/24*sin(42*t+127/30)+145/22*sin(43*t+106/25)+106/19*sin(44*t+135/32)+137/33*sin(45*t+67/16)+103/20*sin(46*t+245/57)+61/29*sin(47*t+94/23)+550/97*sin(48*t+171/40)+6/17*sin(49*t+187/72)+48/25*sin(50*t+102/23)+19/40*sin(51*t+41/12)+86/23*sin(52*t+101/24)+62/35*sin(53*t+157/40)+143/71*sin(54*t+251/57)+5/3*sin(55*t+41/29)+527/111*sin(56*t+47/11)+152/39*sin(57*t+47/39)+95/33*sin(58*t+49/11)+1381/345*sin(59*t+19/18)+167/125*sin(60*t+57/13)+19/31*sin(61*t+31/27)+37/32*sin(62*t+35/32)+63/94*sin(63*t+119/26)+16/13*sin(64*t+74/53)+29/6*sin(65*t+121/29)+57/47*sin(66*t+47/26)+61/27*sin(67*t+760/169)+241/39*sin(68*t+149/150)+31/12*sin(70*t+34/29)+49/37*sin(71*t+60/13)+73/37*sin(72*t+25/24)+25/28*sin(74*t+49/29)+42/23*sin(76*t+45/37)+69/25*sin(77*t+98/23)+41/27*sin(78*t+37/24)+29/15*sin(79*t+131/31)+16/11*sin(80*t+13/12)+29/28*sin(82*t+94/29)+11/21*sin(83*t+177/38)+32/17*sin(84*t+43/47)+31/28*sin(86*t+13/7)+145/42*sin(87*t+192/49)+49/32*sin(88*t+19/21)+67/48*sin(89*t+1/13)+33/28*sin(90*t+151/48)+40/21*sin(91*t+121/31)+33/20*sin(92*t+11/15)+106/49*sin(93*t+1/9)+17/19*sin(94*t+98/59)+7/3*sin(95*t+176/45)+97/29*sin(96*t+20/31)+50/27*sin(97*t+2/9)+17/7*sin(98*t+136/41)+16260/23)*theta(59*pi-t)*theta(t-55*pi)+(-142/41*sin(39/25-17*t)-68/33*sin(38/25-15*t)-25/12*sin(23/15-13*t)-23/12*sin(65/42-12*t)-497/33*sin(36/23-6*t)-105/19*sin(25/16-5*t)-1996/33*sin(47/30-4*t)-802/73*sin(113/72-t)+11015/34*sin(2*t+212/45)+354/35*sin(3*t+146/31)+109/14*sin(7*t+221/47)+16/15*sin(8*t+41/25)+217/69*sin(9*t+144/31)+17/13*sin(10*t+233/50)+82/29*sin(11*t+164/35)+3/7*sin(14*t+36/23)+224/79*sin(16*t+35/22)+43/14*sin(18*t+69/43)+7930/11)*theta(55*pi-t)*theta(t-51*pi)+(-13/25*sin(19/28-9*t)-16/33*sin(38/41-7*t)+181/15*sin(t+112/27)+159/32*sin(2*t+33/49)+259/38*sin(3*t+106/31)+57/13*sin(4*t+109/35)+8/27*sin(5*t+20/31)+35/22*sin(6*t+77/25)+41/32*sin(8*t+34/19)+23/42*sin(10*t+44/41)+22/35*sin(11*t+117/25)+17/32*sin(12*t+13/22)-9500/9)*theta(51*pi-t)*theta(t-47*pi)+(-2423/42*sin(36/29-t)-38027/36)*theta(47*pi-t)*theta(t-43*pi)+(-232/21*sin(59/47-5*t)-380/27*sin(2/17-4*t)-472/19*sin(19/18-3*t)+3307/21*sin(t+7/37)+1527/17*sin(2*t+76/65)+25/33*sin(6*t+23/20)+281/36*sin(7*t+134/33)+37/27*sin(8*t+57/25)+52/23*sin(9*t+54/13)+21/5*sin(10*t+19/9)+54/25*sin(11*t+172/51)+105/32*sin(12*t+53/46)-12945/26)*theta(43*pi-t)*theta(t-39*pi)+(-11/30*sin(36/43-11*t)-7/23*sin(3/11-7*t)-73/19*sin(1/49-3*t)-19/28*sin(4/31-t)+9/13*sin(2*t+21/62)+905/226*sin(4*t+4/25)+24/19*sin(5*t+111/40)+17/27*sin(6*t+41/23)+13/27*sin(8*t+57/20)+13/31*sin(9*t+5/27)+5/23*sin(10*t+59/18)+13/77*sin(12*t+123/37)+7606/23)*theta(39*pi-t)*theta(t-35*pi)+(-2/9*sin(7/25-11*t)-2/17*sin(17/32-9*t)-4/31*sin(25/17-7*t)-9/20*sin(41/39-5*t)+7/4*sin(t+53/28)+34/9*sin(2*t+109/26)+45/8*sin(3*t+217/51)+49/38*sin(4*t+37/36)+7/22*sin(6*t+90/181)+5/23*sin(8*t+11/25)+3/29*sin(10*t+169/41)+4/21*sin(12*t+305/76)+6727/20)*theta(35*pi-t)*theta(t-31*pi)+(-5/3*sin(23/34-3*t)-2989/130*sin(9/28-t)+13/30*sin(2*t+37/16)+5/6*sin(4*t+29/10)+15/41*sin(5*t+55/46)+5/23*sin(6*t+91/27)+9085/27)*theta(31*pi-t)*theta(t-27*pi)+(-56/45*sin(16/17-3*t)-2344/125*sin(19/43-t)+5/6*sin(2*t+20/19)+26/23*sin(4*t+75/31)+4/35*sin(5*t+654/187)+28/113*sin(6*t+118/37)+14511/44)*theta(27*pi-t)*theta(t-23*pi)+(-31/17*sin(29/48-14*t)-50/27*sin(33/98-13*t)-41/15*sin(11/39-10*t)-133/66*sin(5/18-8*t)-1171/19*sin(7/29-2*t)-1421/10*sin(27/22-t)+1347/59*sin(3*t+25/8)+942/43*sin(4*t+29/20)+740/49*sin(5*t+18/17)+47/8*sin(6*t+132/35)+167/13*sin(7*t+169/94)+67/19*sin(9*t+53/33)+16/81*sin(11*t+49/44)+35/18*sin(12*t+4/15)+9/23*sin(15*t+116/37)+19/11*sin(16*t+9/37)+2031/17)*theta(23*pi-t)*theta(t-19*pi)+(-23/30*sin(25/63-12*t)-163/109*sin(17/27-10*t)-sin(20/31-8*t)-104/11*sin(22/35-3*t)-98/27*sin(53/52-t)+138/55*sin(2*t+251/58)+177/17*sin(4*t+8/37)+269/84*sin(5*t+75/17)+28/29*sin(6*t+72/23)+20/19*sin(7*t+55/28)+68/45*sin(9*t+66/31)+31/37*sin(11*t+155/59)-6747/22)*theta(19*pi-t)*theta(t-15*pi)+(-103/38*sin(25/34-8*t)-439/219*sin(19/17-7*t)-159/31*sin(3/13-5*t)-35/26*sin(7/24-4*t)-387/83*sin(5/7-3*t)+944/19*sin(t+79/26)+329/31*sin(2*t+17/36)+25/12*sin(6*t+155/44)-4790/31)*theta(15*pi-t)*theta(t-11*pi)+(-84/31*sin(92/61-4*t)-3*sin(14/9-3*t)-381/31*sin(39/35-2*t)+925/46*sin(t+259/86)+48/43*sin(5*t+53/16)+27/29*sin(6*t+105/44)+11/21*sin(7*t+38/21)+7/31*sin(8*t+227/76)+11503/35)*theta(11*pi-t)*theta(t-7*pi)+(-16/21*sin(13/16-7*t)+245/12*sin(t+26/21)+199/20*sin(2*t+11/20)+47/26*sin(3*t+17/7)+70/51*sin(4*t+41/21)+22/9*sin(5*t+258/59)+29/31*sin(6*t+242/81)+7/24*sin(8*t+13/22)+26/37*sin(9*t+55/64)+8693/27)*theta(7*pi-t)*theta(t-3*pi)+(-16/9*sin(27/31-12*t)-103/38*sin(37/36-8*t)-63/25*sin(5/26-7*t)-58204/85*sin(4/21-t)+371/34*sin(2*t+109/27)+632/39*sin(3*t+71/27)+262/33*sin(4*t+13/16)+283/41*sin(5*t+43/24)+58/33*sin(6*t+79/32)+59/21*sin(9*t+77/20)+42/19*sin(10*t+81/35)+178/179*sin(11*t+17/19)+11/35*sin(13*t+67/16)+11/25*sin(14*t+14/13)+11/30*sin(15*t+135/29)+16/49*sin(16*t+70/43)+6851/32)*theta(3*pi-t)*theta(t+pi))*theta(sqrt(sgn(sin(t/2))))
return CGPoint(x: 320 + (x * 300), y: 280 + (y * -300))
}
let path = CGPathCreateMutable()
CGPathAddLines(path, nil, points, points.count)
layer.path = path
There a few issues here:
If look at the bottom of that formula on that web site, it defines θ to be the Heaviside step function.
You are doing integer division. You really want to be doing floating point division. E.g. rather than 10/47, you want 10.0/47.0.
You are striding from 0 to 2π, but you need to go from 0 to 104π.
These formulae are too complicated for Swift to compile. You'll want to split them up into separate lines.
In that equation you found online, there's something that looked curious, namely two occurrences of θ(sqrt(sgn(sin(t/2)))). Taking the square root of the sgn function is wrong (the is no real square root of -1). So I simplified those to just θ(sin(t/2)) and the curve behaved more reasonably.
Pulling this all together, I've taken your code sample, done some macros to split up those long formulae into separate statements, you end up with something like the code snippet here: https://gist.github.com/robertmryan/427f7e9b562ae153c7c1 (Stack Overflow is not letting me paste the full code here because it exceeds the maximum allowed length of a post.)
That yields the following image:
Note, all of those annoying lines back to the origin are a result of how this Mao curve is represented. It's not a single stroke, but rather a series of separate curves misleading stored as a single set of points. You could test for 0.0, 0.0, to eliminate that, but personally I'd break it up into separate arrays of points. I'll leave that for you.

F# Quadruple Double Function

According to the TryF#.org site this function below returns quadruple of the number entered.
let quadruple x =
let double x = x * 2
double(double(x))
Can anyone explain why as I interpret it as like follows? Quadruple doesn't perform any mutation or multiple calls.
function quadruple(x)
return function double(x)
return x * 2
or C#
int a(int x) { return b(x); }
int b(int x) { return x * 2; }
I think this is just a confused indentation. The function should probably look like this:
let quadruple x =
let double x = x * 2
double(double(x))
This should hopefully make more sense - the quadruple function defines a function double and then calls it on the input x (multiplying it by 2) and then applies double on the result, multiplying it by 2 again, so the result is (x * 2) * 2.
Using the indentation in your sample, the code would not compile, because it is not syntactically valid (a function body cannot end with a let line - it needs to end with an expression representing some result to be returned).

Resources