analytics

Monday, July 6, 2015

Focoid's with source code

In this picture the blue dot is the centroid of all the black dots, and the red dots are what I call the focoids... The physical interpretation is that if these dots all weighed the same and were on a weightless plate, the centroid would be the place you could put one support to balance out the plate, and the focoids are two points where you could put supports so the plate would balance and there would be an even amount of weight on both supports...
I call them the focoids because of the analogy, the center of a circle is to the centroid as the focii of an ellipse are to the focoids...
In the program I wrote the dots are divided into 2 groups during the process of finding the focoids, the two groups each being a collection of points whose centroid is focoid 1 and the other whose centroid is focoid 2, so it is natural to make those points of each group a new set and find the focoids of each of those, and one could recurse until the last focoids found are the points of the original set as the centroid of just one point is the point in question... Below is shown the points from the leftmost group of the original points and it's centroid and focoids...


The program below can extend to any number and arrangement of points...


**Go Source Code**

package main

import (
    "fmt"
    "math"
)
func distance(a []float64, b []float64) float64{
    var c float64 = math.Pow(float64(a[0]-b[0]), 2) + math.Pow(float64(a[1]-b[1]), 2)
    return c
}
func centroid(a [][]float64) []float64{
    sumx :=0.0
    sumy :=0.0
    for i :=0; i<len(a); i++{
        sumx+=float64(a[i][0])
        sumy+=float64(a[i][1])
    }
    sumx /= float64(len(a))
    sumy /= float64(len(a))
    var c = []float64{
        sumx,sumy,
        }
    return c
}
func focoids(a [][]float64) ([][]float64, [][]float64, []float64, []float64){
    c := centroid(a)
    var centerred = []float64{0.0, 0.0}
    var centerblue = []float64{0.0, 0.0}
    var reds = make([][]float64, 0)
    var blues = make([][]float64,0)
    nred := 0.0
    nblue := 0.0
    for i:=0; i < len(a); i++{
        x := float64(a[i][0])
        y := float64(a[i][1])
        l := float64(len(a))
        cvx :=(c[0]-x)/distance(c, a[i])
        cvy :=(c[1]-y)/distance(c, a[i])
        c2x := (c[0]*l - x)/(l-1)-cvx
        c2y := (c[1]*l - y)/(l-1)-cvy
        c2 := []float64{c2x, c2y}
        cv := []float64{cvx, cvy}
        c2[0] /= distance(c2, cv)
        c2[1] /= distance(c2, cv)
        d := cv[0]*c2[1]-cv[1]*c2[0]
        if d < 0{
            reds = append(reds, a[i])
            centerred[0] += x
            centerred[1] += y
            nred += 1 
        }
        if d > 0{
            blues = append(blues, a[i])
            centerblue[0] += x
            centerblue[1] += y
            nblue += 1
            
        }
    }
    centerred[0]/=nred
    centerred[1]/=nred
    centerblue[0]/=nblue
    centerblue[1]/=nblue
    return reds, blues, centerred, centerblue
    
    
}
func main() {
    var a = [][]float64{
        {283,265},
        {119,99},
        {309,84},
        {461,151},
        {77,445},
        {284,451},
        {139,236},
        {678,207},
        {174,594},
        {491,525},
        {664,440},
        {531,671},
        {369,701},
    }

    var reds = make([][]float64, 0)
    var blues = make([][]float64, 0)
    var centerred = make([]float64, 2)
    var centerblue = make([]float64, 2)
    reds, blues, centerred, centerblue = focoids(a)
    fmt.Println(reds,blues)
    fmt.Println(centerred, centerblue)
    reds, blues, centerred, centerblue = focoids(blues)
    fmt.Println(reds,blues)
    fmt.Println(centerred, centerblue)
}


No comments:

Post a Comment