# Geometry from Image

![](https://1430428134-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ld8QK19sjP1I9rhLouo%2F-Lh9EECxTP007WtieUZy%2F-Lh9Elfm_t-ewmYoypM_%2FImgTrace.png?alt=media\&token=4aed53cc-8371-4438-9612-cb4b325125ee)

{% file src="<https://1430428134-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ld8QK19sjP1I9rhLouo%2F-Lh9EECxTP007WtieUZy%2F-Lh9F17PVmfYqBB1xk3h%2FimgTrace.zip?alt=media&token=82f074ce-a27a-4b05-92df-cadcdd48687b>" %}

```d
pntSeq(grpPnts(pts));

	// Group Contiguous Points
	def grpPnts(pts:var[]..[])
    {
    	dis1 = pts<1>.DistanceTo(pts<2>)<2;
    	ind1 = List.AllIndicesOf(dis1<1>,true);
    	bln1 = true;
    	ind2 = [Imperative]
    	{
    		while (bln1)
    		{
    			cnt1 = List.Count(ind1);
    			ind1 = grpIndx(ind1);
    			cnt2 = List.Count(ind1);
    			bln1 = cnt2!=cnt1;
    		}
    		return = ind1;
    	}
    	pts1 = List.GetItemAtIndex(pts,ind2);
    	return = pts1;
    };

    def grpIndx(ind:var[]..[])
    {
    	ind1 = List.SetIntersection(ind<1>,ind<2>);
    	cnt1 = List.Count(ind1<1><2>)>0;
    	ind2 = List.FilterByBoolMask(ind,cnt1<1>)["in"];
    	ind3 = List.UniqueItems(List.Flatten(ind2<1>,-1)<1>);
    	ind4 = List.UniqueItems(List.Sort(ind3<1>));
    	return = ind4;
    };

    def pntSeq(pnt:var[]..[])
	{
		c = Point.ByCoordinates(Math.Sum(pnt.X)/List.Count(pnt<1>),
		Math.Sum(pnt.Y)/List.Count(pnt<1>));
		a = (Vector.ByTwoPoints(c,pnt).Normalized()).AngleAboutAxis
		(Vector.XAxis(),Vector.ZAxis());
		p = List.SortByKey(pnt<1>,a<1>)["sorted list"];
		return p;

	};
```

![](https://1430428134-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ld8QK19sjP1I9rhLouo%2F-Lh9EECxTP007WtieUZy%2F-Lh9EsOBRI2OO3VXS9RS%2FimgTrcSmpl.png?alt=media\&token=4779d6e9-c9a2-44e0-a615-5938800a958d)
