# Geometric modeling

using BasicBSpline
using StaticArrays
using Plots
using LinearAlgebra
plotly()
Plots.PlotlyBackend()

## Arc

p = 2
k = KnotVector([0,0,0,1,1,1])
P = BSplineSpace{p}(k)
t = 1  # angle in radians
a = [SVector(1,0), SVector(1,tan(t/2)), SVector(cos(t),sin(t))]
w = [1,cos(t/2),1]
M = RationalBSplineManifold(a,w,P)
plot(M, xlims=(0,1.1), ylims=(0,1.1), aspectratio=1)

## Circle

p = 2
k = KnotVector([0,0,0,1,1,2,2,3,3,4,4,4])
P = BSplineSpace{p}(k)
a = [
SVector( 1, 0),
SVector( 1, 1),
SVector( 0, 1),
SVector(-1, 1),
SVector(-1, 0),
SVector(-1,-1),
SVector( 0,-1),
SVector( 1,-1),
SVector( 1, 0)
]
w = [1,1/√2,1,1/√2,1,1/√2,1,1/√2,1]
M = RationalBSplineManifold(a,w,P)
plot(M, xlims=(-1.2,1.2), ylims=(-1.2,1.2), aspectratio=1)

## Torus

R = 3
r = 1

a0 = [
SVector( 1, 0, 0),
SVector( 1, 1, 0),
SVector( 0, 1, 0),
SVector(-1, 1, 0),
SVector(-1, 0, 0),
SVector(-1,-1, 0),
SVector( 0,-1, 0),
SVector( 1,-1, 0),
SVector( 1, 0, 0)
]

a1 = (R+r)*a0
a5 = (R-r)*a0
a2 = [p+r*SVector(0,0,1) for p in a1]
a3 = [p+r*SVector(0,0,1) for p in R*a0]
a4 = [p+r*SVector(0,0,1) for p in a5]
a6 = [p-r*SVector(0,0,1) for p in a5]
a7 = [p-r*SVector(0,0,1) for p in R*a0]
a8 = [p-r*SVector(0,0,1) for p in a1]
a9 = a1

a = hcat(a1,a2,a3,a4,a5,a6,a7,a8,a9)
M = RationalBSplineManifold(a,w*w',P,P)
plot(M)

## Paraboloid

p = 2
k = KnotVector([-1,-1,-1,1,1,1])
P = BSplineSpace{p}(k)
a = [SVector(i,j,2i^2+2j^2-2) for i in -1:1, j in -1:1]
M = BSplineManifold(a,P,P)
plot(M)

## Hyperbolic paraboloid

a = [SVector(i,j,2i^2-2j^2) for i in -1:1, j in -1:1]
M = BSplineManifold(a,P,P)
plot(M)