// 3 decimal points of precision is enough. Floating points on Bezier curves can reach the level of precision where different machines round differently.
return&RelativePoint{
XPercentage:TruncateDecimals(xPercentage),
YPercentage:TruncateDecimals(yPercentage),
}
}
typePointstruct{
Xfloat64`json:"x"`
Yfloat64`json:"y"`
}
funcNewPoint(x,yfloat64)*Point{
return&Point{X:x,Y:y}
}
func(p1*Point)Equals(p2*Point)bool{
ifp1==nil{
returnp2==nil
}elseifp2==nil{
returnfalse
}
return(p1.X==p2.X)&&(p1.Y==p2.Y)
}
func(p1*Point)Compare(p2*Point)int{
xCompare:=Sign(p1.X-p2.X)
ifxCompare==0{
returnSign(p1.Y-p2.Y)
}
returnxCompare
}
func(p*Point)Copy()*Point{
return&Point{X:p.X,Y:p.Y}
}
typePoints[]*Point
func(psPoints)Equals(otherPoints)bool{
ifps==nil{
returnother==nil
}elseifother==nil{
returnfalse
}
pointsSet:=make(map[Point]struct{})
for_,p:=rangeps{
pointsSet[*p]=struct{}{}
}
for_,otherPoint:=rangeother{
if_,exists:=pointsSet[*otherPoint];!exists{
returnfalse
}
}
returntrue
}
func(psPoints)GetMedian()*Point{
xs:=make([]float64,0)
ys:=make([]float64,0)
for_,p:=rangeps{
xs=append(xs,p.X)
ys=append(ys,p.Y)
}
sort.Float64s(xs)
sort.Float64s(ys)
middleIndex:=len(xs)/2
medianX:=xs[middleIndex]
medianY:=ys[middleIndex]
iflen(xs)%2==0{
medianX+=xs[middleIndex-1]
medianX/=2
medianY+=ys[middleIndex-1]
medianY/=2
}
return&Point{X:medianX,Y:medianY}
}
// GetOrientation gets orientation of pFrom to pTo
// E.g. pFrom ---> pTo, here, pFrom is to the left of pTo, so Left would be returned