gog

package module
v0.0.0-...-d8b9877 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2023 License: MIT Imports: 11 Imported by: 2

README

gog

golang geometry library between point and segments


package gog // import "github.com/Konstantin8105/gog"


CONSTANTS

const (
	CollinearPoints        OrientationPoints = -1
	ClockwisePoints                          = 0
	CounterClockwisePoints                   = 1
)
const (
	// Boundary edge
	Boundary = -1

	// Removed element
	Removed = -2

	// Undefined state only for not valid algorithm
	Undefined = -3
	Fixed     = 100
	Movable   = 200
)
const Eps3D = 1e-5
    Eps3D is default epsilon for 3D operations


VARIABLES

var (
	// ErrorDivZero is typical result with not acceptable solving
	ErrorDivZero = fmt.Errorf("div value is too small")

	// ErrorNotValidSystem is typical return only if system of
	// linear equation have not valid data
	ErrorNotValidSystem = fmt.Errorf("not valid system")
)
var (
	// Debug only for debugging
	Debug = false
	// Log only for minimal logging
	Log = false
)
var (
	// Eps is epsilon - precision of intersection
	Eps = 1e-10
)

FUNCTIONS

func AngleBetween(center, from, mid, to, a Point) (res bool)
    AngleBetween return true for angle case from <= a <= to

func Arc(Arc0, Arc1, Arc2 Point) (xc, yc, r float64)
    Arc return parameters of circle

func ArcSplitByPoint(Arc0, Arc1, Arc2 Point, pi ...Point) (res [][3]Point, err error)
    ArcSplitByPoint return points of arcs with middle point if pi is empty or
    slice of arcs.

        DO NOT CHECKED POINT ON ARC

func Area(
	tr0, tr1, tr2 Point,
) float64
    Area return area of triangle

func BorderIntersection(ps1, ps2 []Point3d) (intersect bool)
    BorderIntersection return true only if Borders are intersect

func Check(pps ...Point) error
    Check - check input data

func Distance(p0, p1 Point) float64
    Distance between two points

func Distance128(p0, p1 Point) float64
    Distance128 is distance between 2 points with 128-bit precisions

func Distance3d(p0, p1 Point3d) float64
    Distance3d is distance between 2 points in 3D

func IsParallelLine3d(
	a0, a1 Point3d,
	b0, b1 Point3d,
) (
	parallel bool,
)
    IsParallelLines3d return true, if lines are parallel

func Line(p0, p1 Point) (A, B, C float64)
    Line parameters by formula: Ax+By+C = 0

func LineArc(Line0, Line1 Point, Arc0, Arc1, Arc2 Point) (
	pi []Point,
	stA, stB State,
)
    LineArc return state and intersections points between line and arc

func LineLine(
	pa0, pa1 Point,
	pb0, pb1 Point,
) (
	pi []Point,
	stA, stB State,
)
    LineLine return analisys of two segments

    Design of segments:

                                                    //
        <-- rb00 -- pb0*==========*pb1 -- rb11 -->  // Segment B
                                                    //
        <-- ra00 -- pa0*==========*pa1 -- ra11 -->  // Segment A
        {   ray   }{      segment     }{   ray   }  //
                                                    //

    Input data:

        ipa0, ipa1 - point indexes of segment A
        ipb0, ipb1 - point indexes of segment B
        pps      - pointer of point slice

    Output data:

        pi - intersection point
        st - states of analisys

    Reference:

        [1]  https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection

func LineLine3d(
	a0, a1 Point3d,
	b0, b1 Point3d,
) (
	ratioA, ratioB float64,
	intersect bool,
)
    LineLine3d return intersection of two points. Point on line corner ignored

func Linear(
	a11, a12, b1 float64,
	a21, a22, b2 float64,
) (x, y float64, err error)
    Linear equations solving:

        a11*x + a12*y = b1
        a21*x + a22*y = b2

func Plane(
	p1, p2, p3 Point3d,
) (
	A, B, C, D float64,
)
    Plane equation `A*x+B*y+C*z+D=0`

func PlaneAverage(
	ps []Point3d,
) (
	A, B, C, D float64,
)
    PlaneAverage return parameters of average plane for points

func PointArc(pt Point, Arc0, Arc1, Arc2 Point) (
	pi []Point,
	stA, stB State,
)
    PointArc return state and intersections points between point and arc

func PointInCircle(point Point, circle [3]Point) bool
    PointInCircle return true only if point inside circle based on 3 circles
    points

func PointLine(
	pt Point,
	pb0, pb1 Point,
) (
	pi []Point,
	stA, stB State,
)
    PointLine return states between point and line.

func PointLine3d(
	p Point3d,
	l0, l1 Point3d,
) (
	intersect bool,
)
    PointLine3d return true only if point located on line segment

func PointLineDistance(
	pc Point,
	p0, p1 Point,
) (distance float64)
    PointLineDistance return distance between line and point.

    Equation of line:

        (y2-y1)*(x-x1) = (x2-x1)(y-y1)
        dy*(x-x1) = dx*(y-y1)
        dy*x-dy*x1-dx*y+dx*y1 = 0
        Ax+By+C = 0
        A = dy
        B = -dx
        C = -dy*x1+dx*y1

    Distance from point (xm,ym) to line:

        d = |(A*xm+B*ym+C)/sqrt(A^2+B^2)|

func PointOnPlane3d(
	A, B, C, D float64,
	p Point3d,
) (
	on bool,
)
    PointOnPlane3d return true if all points on plane

func PointPoint(
	pt0, pt1 Point,
) (
	pi []Point,
	stA, stB State,
)
    PointPoint return states between two points.

func PointPoint3d(
	p0 Point3d,
	p1 Point3d,
) (
	intersect bool,
)
    PointPoint3d return true only if points have same coordinate

func PointTriangle3d(
	p Point3d,
	t0, t1, t2 Point3d,
) (
	intersect bool,
)
    PointTriangle3d return true only if point located inside triangle but do not
    check point on triangle edge

func SamePoints(p0, p1 Point) bool
    SamePoints return true only if point on very distance or with same
    coordinates

func SamePoints3d(p0, p1 Point3d) bool
    SamePoints3d return true only if point on very distance or with same
    coordinates

func TriangleSplitByPoint(
	pt Point,
	tr0, tr1, tr2 Point,
) (
	res [][3]Point,
	lineIntersect int,
	err error,
)
    TriangleSplitByPoint split triangle on triangles only if point inside
    triangle or on triangle edge

func ZeroLine3d(
	l0, l1 Point3d,
) (
	zero bool,
)
    ZeroLine3d return true only if lenght of line segment is zero

func ZeroTriangle3d(
	t0, t1, t2 Point3d,
) (
	zero bool,
)
    ZeroTriangle3d return true only if triangle have zero area


TYPES

type Mesh struct {
	Points    []int    // tags for points
	Triangles [][3]int // indexes of near triangles

	// Has unexported fields.
}
    Mesh is based structure of triangulation. Triangle is data structure
    "Nodes, ribs и triangles" created by book "Algoritm building and analyse
    triangulation", A.B.Skvorcov

        Scketch:
        +------------------------------------+
        |              tr[0]                 |
        |  nodes[0]    ribs[0]      nodes[1] |
        | o------------------------o         |
        |  \                      /          |
        |   \                    /           |
        |    \                  /            |
        |     \                /             |
        |      \              /              |
        |       \            /  ribs[1]      |
        |        \          /   tr[1]        |
        |  ribs[2]\        /                 |
        |  tr[2]   \      /                  |
        |           \    /                   |
        |            \  /                    |
        |             \/                     |
        |              o  nodes[2]           |
        +------------------------------------+

func New(model Model) (mesh *Mesh, err error)
    New triangulation created by model

func (mesh *Mesh) AddLine(inp1, inp2 Point) (err error)
    AddLine is add line in triangulation with tag

func (mesh *Mesh) AddPoint(p Point, tag int, triIndexes ...int) (idp int, err error)
    AddPoint is add points with tag

func (mesh Mesh) Check() (err error)
    Check triangulation on point, line, triangle rules

func (mesh *Mesh) Clockwise()
    Clockwise change all triangles to clockwise orientation

func (mesh *Mesh) Delanay(triIndexes ...int) (err error)
    TODO delanay only for some triangles, if list empty then for all triangles

func (mesh *Mesh) GetMaterials(ps ...Point) (materials []int, err error)
    GetMaterials return materials for each point

func (mesh *Mesh) Materials() (err error)
    Materials indentify all triangles splitted by lines, only if points sliceis
    empty. If points slice is not empty, then return material mark number for
    each point

func (mesh *Mesh) RemoveMaterials(ps ...Point) (err error)
    RemoveMaterials remove material by specific points

func (mesh *Mesh) SetMaterial(p Point, material int) (err error)
    SetMaterial change material for point

func (mesh *Mesh) Smooth(pts ...int) (err error)
    Smooth move all movable point by average distance

func (mesh *Mesh) Split(factor float64) (err error)
    Split all triangles edge on distance `factor`

func (mesh *Mesh) SplitFunc(factorFunc func(p1, p2 Point) bool) (err error)
    SplitFunc split all triangles edge on distance only if function argument
    return true. Example of factorFunc:

        factorFunc = func(p1, p2 Point) bool {
        	d := gog.Distance(p1, p2)
        	return factor < d
        }

    If factorFunc is not valid, then splitting will be infinite.

type Model struct {
	Points    []Point  // Points is slice of points
	Lines     [][3]int // Lines store 2 index of Points and last for tag
	Arcs      [][4]int // Arcs store 3 index of Points and last for tag
	Triangles [][4]int // Triangles store 3 index of Points and last for tag/material
	Quadrs    [][5]int // Rectanges store 4 index of Points and last for tag/material
}
    Model of points, lines, arcs for prepare of triangulation

func (m *Model) AddArc(start, middle, end Point, tag int)
    AddArc add arc into model with specific tag

func (m *Model) AddCircle(xc, yc, r float64, tag int)
    AddCircle add arcs based on circle geometry into model with specific tag

func (m *Model) AddLine(start, end Point, tag int)
    AddLine add line into model with specific tag

func (m *Model) AddModel(from Model)
    AddModel inject model into model

func (m *Model) AddMultiline(tag int, ps ...Point)
    AddMultiline add many lines with specific tag

func (m *Model) AddPoint(p Point) (index int)
    AddPoint return index in model slice point

func (m *Model) AddTriangle(start, middle, end Point, tag int)
    AddTriangle add triangle into model with specific tag/material

func (m *Model) ArcsToLines()
    ArcsToLines convert arc to lines

func (m *Model) Combine(factorOneLine float64) (err error)
    Combine triangles to quadr with same tag

        factorOneLine from 1 to 2/sqrt(2) = 1.41

    Recommendation value is 1.05

func (m *Model) ConvexHullTriangles()
    ConvexHullTriangles add triangles of model convex hull

func (src Model) Copy() (dst Model)
    Copy return copy of Model

func (m Model) Dxf() string
    Dxf return string in dxf drawing format
    https://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf

func (model *Model) Get(mesh *Mesh)
    Get add into Model all triangles from Mesh Recommendation after `Get` :
    model.Intersection()

func (m *Model) Intersection()
    Intersection change model with finding all model intersections

func (m Model) JSON() (_ string, err error)
    JSON convert model in JSON format

func (to *Model) Merge(from Model)
    Merge `from` model to `to` model

func (m Model) MinPointDistance() (distance float64)
    MinPointDistance return minimal between 2 points

func (m Model) Mirror(p1, p2 Point) (mir Model, err error)
    Mirror return mirror of model

func (m *Model) Move(dx, dy float64)
    Move all points of model

func (m *Model) Read(filename string) (err error)
    Read model from file with filename in JSON format

func (m *Model) RemoveEmptyPoints()
    RemoveEmptyPoints removed point not connected to line, arcs, triangles

func (m *Model) RemovePoint(remove func(p Point) bool)
    RemovePoint removed point in accoding to function `filter`

func (m *Model) Rotate(xc, yc, angle float64)
    Rotate all points of model around point {xc,yc}

func (m *Model) Split(d float64)
    Split all model lines, arcs by distance `d`

func (m Model) String() string
    String return a stantard model view

func (m Model) TagProperty() (length []float64, area []float64)
    TagProperty return length of lines, area of triangles for each tag. Arcs are
    ignored

func (m Model) Write(filename string) (err error)
    Write model into file with filename in JSON format

type OrientationPoints int8
    OrientationPoints is orientation points state

func Orientation(p1, p2, p3 Point) OrientationPoints

func Orientation128(p1, p2, p3 Point) OrientationPoints

type Point struct {
	X, Y float64
}
    Point is store of point coordinates

func ConvexHull(points []Point, withoutCollinearPoints bool) (chain []int, res []Point)
    ConvexHull return chain of convex points

func MiddlePoint(p0, p1 Point) Point
    MiddlePoint calculate middle point precisionally.

func MirrorPoint(mp0, mp1 Point, sp ...Point) (
	mp []Point,
	err error,
)
    MirrorPoint return mirror point by line

func Rotate(xc, yc, angle float64, point Point) (p Point)
    Rotate point about (xc,yc) on angle

func (p Point) String() string
    String is implementation of Stringer implementation for formating output

type Point3d [3]float64
    Point3d is point coordinate in 3D decart system

func BorderPoints(ps ...Point3d) (min, max Point3d)
    BorderPoints return (min..max) points coordinates

func LineTriangle3dI1(
	l0, l1 Point3d,
	t0, t1, t2 Point3d,
) (
	intersect bool,
	pi []Point3d,
)
    LineTriangle3dI1 return intersection points for case if line and triangle is
    not on one plane. line intersect triangle in one point

func LineTriangle3dI2(
	l0, l1 Point3d,
	t0, t1, t2 Point3d,
) (
	intersect bool,
	pi []Point3d,
)
    LineTriangle3dI2 return intersection points if line and triangle located on
    one plane. Line on triangle plane Line is not zero ignore triangle point on
    line

func Mirror3d(plane [3]Point3d, points ...Point3d) (mir []Point3d)
    Mirror3d return mirror points by mirror plane

func PointLineRatio3d(
	l0, l1 Point3d,
	ratio float64,
) (
	p Point3d,
)
    PointLineRatio3d return point in accroding to line ratio

func TriangleTriangle3d(
	a0, a1, a2 Point3d,
	b0, b1, b2 Point3d,
) (
	intersect bool,
	pi []Point3d,
)
    TriangleTriangle3d return intersection points between two triangles.
    do not intersect with egdes

type State int64
    State is result of intersection

const (

	// VerticalSegment return if segment is vertical
	VerticalSegment State

	// HorizontalSegment return if segment is horizontal
	HorizontalSegment

	// ZeroLengthSegment return for zero length segment
	ZeroLengthSegment

	// Parallel is segment A and segment B.
	// Intersection point data is not valid.
	Parallel

	// Collinear return if:
	// Segment A and segment B are collinear.
	// Intersection point data is not valid.
	Collinear

	// OnSegment is intersection point on segment
	OnSegment

	// OnPoint0Segment intersection point on point 0 segment
	OnPoint0Segment

	// OnPoint1Segment intersection point on point 1 segment
	OnPoint1Segment

	// ArcIsLine return only if wrong arc is line
	ArcIsLine

	// ArcIsPoint return only if wrong arc is point
	ArcIsPoint
)
func (s State) Has(si State) bool
    Has is mean s-State has si-State

func (s State) Not(si State) bool
    Not mean s-State have not si-State

func (s State) String() string
    String is implementation of Stringer implementation for formating output

Documentation

Overview

Example
// *2   *0  //
//  \  /    //
//    X     //
//  /  \    //
// *1   *3  //
pps := []Point{
	Point{X: 1, Y: 1}, // 0
	Point{X: 4, Y: 4}, // 1
	Point{X: 0, Y: 5}, // 2
	Point{X: 5, Y: 0}, // 3
}

if err := Check(pps...); err != nil {
	panic(err)
}
pi, stA, stB := LineLine(
	pps[0], pps[1],
	pps[2], pps[3],
)
fmt.Fprintf(os.Stdout, "Intersection point: %s\n", pi)
fmt.Fprintf(os.Stdout, "Intersection state A:\n%s\n", stA)
fmt.Fprintf(os.Stdout, "Intersection state B:\n%s\n", stB)
Output:

Intersection point: [[2.50000e+00,2.50000e+00]]
Intersection state A:
 1	               VerticalSegment	not found
 2	             HorizontalSegment	not found
 3	             ZeroLengthSegment	not found
 4	                      Parallel	not found
 5	                     Collinear	not found
 6	                     OnSegment	found
 7	               OnPoint0Segment	not found
 8	               OnPoint1Segment	not found
 9	                     ArcIsLine	not found
10	                    ArcIsPoint	not found

Intersection state B:
 1	               VerticalSegment	not found
 2	             HorizontalSegment	not found
 3	             ZeroLengthSegment	not found
 4	                      Parallel	not found
 5	                     Collinear	not found
 6	                     OnSegment	found
 7	               OnPoint0Segment	not found
 8	               OnPoint1Segment	not found
 9	                     ArcIsLine	not found
10	                    ArcIsPoint	not found

Index

Examples

Constants

View Source
const (
	CollinearPoints        OrientationPoints = -1
	ClockwisePoints                          = 0
	CounterClockwisePoints                   = 1
)
View Source
const (
	// Boundary edge
	Boundary = -1

	// Removed element
	Removed = -2

	// Undefined state only for not valid algorithm
	Undefined = -3
	Fixed     = 100
	Movable   = 200
)
View Source
const Eps3D = 1e-5

Eps3D is default epsilon for 3D operations

Variables

View Source
var (
	// ErrorDivZero is typical result with not acceptable solving
	ErrorDivZero = fmt.Errorf("div value is too small")

	// ErrorNotValidSystem is typical return only if system of
	// linear equation have not valid data
	ErrorNotValidSystem = fmt.Errorf("not valid system")
)
View Source
var (
	// Debug only for debugging
	Debug = false
	// Log only for minimal logging
	Log = false
)
View Source
var (
	// Eps is epsilon - precision of intersection
	Eps = 1e-10
)

Functions

func AngleBetween

func AngleBetween(center, from, mid, to, a Point) (res bool)

AngleBetween return true for angle case from <= a <= to

func Arc

func Arc(Arc0, Arc1, Arc2 Point) (xc, yc, r float64)

Arc return parameters of circle

func ArcSplitByPoint

func ArcSplitByPoint(Arc0, Arc1, Arc2 Point, pi ...Point) (res [][3]Point, err error)

ArcSplitByPoint return points of arcs with middle point if pi is empty or slice of arcs.

DO NOT CHECKED POINT ON ARC

func Area

func Area(
	tr0, tr1, tr2 Point,
) float64

Area return area of triangle

func BorderIntersection

func BorderIntersection(ps1, ps2 []Point3d) (intersect bool)

BorderIntersection return true only if Borders are intersect

func Check

func Check(pps ...Point) error

Check - check input data

func Distance

func Distance(p0, p1 Point) float64

Distance between two points

func Distance128

func Distance128(p0, p1 Point) float64

Distance128 is distance between 2 points with 128-bit precisions

func Distance3d

func Distance3d(p0, p1 Point3d) float64

Distance3d is distance between 2 points in 3D

func IsParallelLine3d

func IsParallelLine3d(
	a0, a1 Point3d,
	b0, b1 Point3d,
) (
	parallel bool,
)

IsParallelLines3d return true, if lines are parallel

func Line

func Line(p0, p1 Point) (A, B, C float64)

Line parameters by formula: Ax+By+C = 0

func LineArc

func LineArc(Line0, Line1 Point, Arc0, Arc1, Arc2 Point) (
	pi []Point,
	stA, stB State,
)

LineArc return state and intersections points between line and arc

func LineLine

func LineLine(
	pa0, pa1 Point,
	pb0, pb1 Point,
) (
	pi []Point,
	stA, stB State,
)

LineLine return analisys of two segments

Design of segments:

                                            //
<-- rb00 -- pb0*==========*pb1 -- rb11 -->  // Segment B
                                            //
<-- ra00 -- pa0*==========*pa1 -- ra11 -->  // Segment A
{   ray   }{      segment     }{   ray   }  //
                                            //

Input data:

ipa0, ipa1 - point indexes of segment A
ipb0, ipb1 - point indexes of segment B
pps      - pointer of point slice

Output data:

pi - intersection point
st - states of analisys

Reference:

[1]  https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection

func LineLine3d

func LineLine3d(
	a0, a1 Point3d,
	b0, b1 Point3d,
) (
	ratioA, ratioB float64,
	intersect bool,
)

LineLine3d return intersection of two points. Point on line corner ignored

func Linear

func Linear(
	a11, a12, b1 float64,
	a21, a22, b2 float64,
) (x, y float64, err error)

Linear equations solving:

a11*x + a12*y = b1
a21*x + a22*y = b2
Example
var (
	a11, a12, b1 float64 = +8.1, 2 * math.Pi, +38.5e3
	a21, a22, b2 float64 = math.Pi, -5.8, -1.75
)
x, y, err := Linear(
	a11, a12, b1,
	a21, a22, b2,
)
if err != nil {
	fmt.Fprintf(os.Stdout, "%v", err)
	return
}

fmt.Fprintf(os.Stdout, "Result:\nx=%.20e\ny=%.20e\n", x, y)
tols := []float64{
	math.FMA(a11, x, math.FMA(a12, y, -b1)),
	math.FMA(a21, x, math.FMA(a22, y, -b2)),
	a11*x + a12*y - b1,
	a21*x + a22*y - b2,
}
fmt.Fprintf(os.Stdout, "Tolerance:\n")
for _, tol := range tols {
	fmt.Fprintf(os.Stdout, "%.20e\n", tol)
}
Output:

Result:
x=3.34669742693982516357e+03
y=1.81305345694172729054e+03
Tolerance:
-1.37088471310414134179e-12
2.80328409648389926091e-13
0.00000000000000000000e+00
0.00000000000000000000e+00

func Plane

func Plane(
	p1, p2, p3 Point3d,
) (
	A, B, C, D float64,
)

Plane equation `A*x+B*y+C*z+D=0`

Example
delta := 1.0
for i := 0; i < 30; i++ {
	A, B, C, D := Plane(
		Point3d{-10, -1, 10}, Point3d{10, -1, 10}, Point3d{0, 1 + delta, 0},
	)
	fmt.Fprintf(os.Stdout, "%.1e\t%e %e %e %e\n", delta, A, B, C, D)
	delta /= 10.0
}
Output:

1.0e+00	-0.000000e+00 2.000000e+02 6.000000e+01 -4.000000e+02
1.0e-01	-0.000000e+00 2.000000e+02 4.200000e+01 -2.200000e+02
1.0e-02	-0.000000e+00 2.000000e+02 4.020000e+01 -2.020000e+02
1.0e-03	-0.000000e+00 2.000000e+02 4.002000e+01 -2.002000e+02
1.0e-04	-0.000000e+00 2.000000e+02 4.000200e+01 -2.000200e+02
1.0e-05	-0.000000e+00 2.000000e+02 4.000020e+01 -2.000020e+02
1.0e-06	-0.000000e+00 2.000000e+02 4.000002e+01 -2.000002e+02
1.0e-07	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-08	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-09	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-10	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-11	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-12	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-13	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-14	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-15	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-16	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-17	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-18	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-19	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-20	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-21	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-22	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-23	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-24	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-25	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-26	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-27	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-28	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02
1.0e-29	-0.000000e+00 2.000000e+02 4.000000e+01 -2.000000e+02

func PlaneAverage

func PlaneAverage(
	ps []Point3d,
) (
	A, B, C, D float64,
)

PlaneAverage return parameters of average plane for points

func PointArc

func PointArc(pt Point, Arc0, Arc1, Arc2 Point) (
	pi []Point,
	stA, stB State,
)

PointArc return state and intersections points between point and arc

func PointInCircle

func PointInCircle(point Point, circle [3]Point) bool

PointInCircle return true only if point inside circle based on 3 circles points

func PointLine

func PointLine(
	pt Point,
	pb0, pb1 Point,
) (
	pi []Point,
	stA, stB State,
)

PointLine return states between point and line.

func PointLine3d

func PointLine3d(
	p Point3d,
	l0, l1 Point3d,
) (
	intersect bool,
)

PointLine3d return true only if point located on line segment

func PointLineDistance

func PointLineDistance(
	pc Point,
	p0, p1 Point,
) (distance float64)

PointLineDistance return distance between line and point.

Equation of line:

(y2-y1)*(x-x1) = (x2-x1)(y-y1)
dy*(x-x1) = dx*(y-y1)
dy*x-dy*x1-dx*y+dx*y1 = 0
Ax+By+C = 0
A = dy
B = -dx
C = -dy*x1+dx*y1

Distance from point (xm,ym) to line:

d = |(A*xm+B*ym+C)/sqrt(A^2+B^2)|

func PointOnPlane3d

func PointOnPlane3d(
	A, B, C, D float64,
	p Point3d,
) (
	on bool,
)

PointOnPlane3d return true if all points on plane

func PointPoint

func PointPoint(
	pt0, pt1 Point,
) (
	pi []Point,
	stA, stB State,
)

PointPoint return states between two points.

func PointPoint3d

func PointPoint3d(
	p0 Point3d,
	p1 Point3d,
) (
	intersect bool,
)

PointPoint3d return true only if points have same coordinate

Example
p := Point3d{1, 1, 1}
delta := 1.0
for i := 0; i < 30; i++ {
	pf := Point3d{1, 1, 1 + delta}
	value := PointPoint3d(p, pf)
	fmt.Fprintf(os.Stdout, "%.1e\t%v\n", delta, value)
	delta /= 10.0
}
Output:

1.0e+00	false
1.0e-01	false
1.0e-02	false
1.0e-03	false
1.0e-04	false
1.0e-05	false
1.0e-06	false
1.0e-07	false
1.0e-08	false
1.0e-09	false
1.0e-10	false
1.0e-11	true
1.0e-12	true
1.0e-13	true
1.0e-14	true
1.0e-15	true
1.0e-16	true
1.0e-17	true
1.0e-18	true
1.0e-19	true
1.0e-20	true
1.0e-21	true
1.0e-22	true
1.0e-23	true
1.0e-24	true
1.0e-25	true
1.0e-26	true
1.0e-27	true
1.0e-28	true
1.0e-29	true

func PointTriangle3d

func PointTriangle3d(
	p Point3d,
	t0, t1, t2 Point3d,
) (
	intersect bool,
)

PointTriangle3d return true only if point located inside triangle but do not check point on triangle edge

func SamePoints

func SamePoints(p0, p1 Point) bool

SamePoints return true only if point on very distance or with same coordinates

func SamePoints3d

func SamePoints3d(p0, p1 Point3d) bool

SamePoints3d return true only if point on very distance or with same coordinates

func TriangleSplitByPoint

func TriangleSplitByPoint(
	pt Point,
	tr0, tr1, tr2 Point,
) (
	res [][3]Point,
	lineIntersect int,
	err error,
)

TriangleSplitByPoint split triangle on triangles only if point inside triangle or on triangle edge

func ZeroLine3d

func ZeroLine3d(
	l0, l1 Point3d,
) (
	zero bool,
)

ZeroLine3d return true only if lenght of line segment is zero

func ZeroTriangle3d

func ZeroTriangle3d(
	t0, t1, t2 Point3d,
) (
	zero bool,
)

ZeroTriangle3d return true only if triangle have zero area

Types

type Mesh

type Mesh struct {
	Points    []int    // tags for points
	Triangles [][3]int // indexes of near triangles
	// contains filtered or unexported fields
}

Mesh is based structure of triangulation. Triangle is data structure "Nodes, ribs и triangles" created by book "Algoritm building and analyse triangulation", A.B.Skvorcov

Scketch:
+------------------------------------+
|              tr[0]                 |
|  nodes[0]    ribs[0]      nodes[1] |
| o------------------------o         |
|  \                      /          |
|   \                    /           |
|    \                  /            |
|     \                /             |
|      \              /              |
|       \            /  ribs[1]      |
|        \          /   tr[1]        |
|  ribs[2]\        /                 |
|  tr[2]   \      /                  |
|           \    /                   |
|            \  /                    |
|             \/                     |
|              o  nodes[2]           |
+------------------------------------+

func New

func New(model Model) (mesh *Mesh, err error)

New triangulation created by model

func (*Mesh) AddLine

func (mesh *Mesh) AddLine(inp1, inp2 Point) (err error)

AddLine is add line in triangulation with tag

func (*Mesh) AddPoint

func (mesh *Mesh) AddPoint(p Point, tag int, triIndexes ...int) (idp int, err error)

AddPoint is add points with tag

func (Mesh) Check

func (mesh Mesh) Check() (err error)

Check triangulation on point, line, triangle rules

func (*Mesh) Clockwise

func (mesh *Mesh) Clockwise()

Clockwise change all triangles to clockwise orientation

func (*Mesh) Delanay

func (mesh *Mesh) Delanay(triIndexes ...int) (err error)

TODO delanay only for some triangles, if list empty then for all triangles

func (*Mesh) GetMaterials

func (mesh *Mesh) GetMaterials(ps ...Point) (materials []int, err error)

GetMaterials return materials for each point

func (*Mesh) Materials

func (mesh *Mesh) Materials() (err error)

Materials indentify all triangles splitted by lines, only if points sliceis empty. If points slice is not empty, then return material mark number for each point

func (*Mesh) RemoveMaterials

func (mesh *Mesh) RemoveMaterials(ps ...Point) (err error)

RemoveMaterials remove material by specific points

func (*Mesh) SetMaterial

func (mesh *Mesh) SetMaterial(p Point, material int) (err error)

SetMaterial change material for point

func (*Mesh) Smooth

func (mesh *Mesh) Smooth(pts ...int) (err error)

Smooth move all movable point by average distance

func (*Mesh) Split

func (mesh *Mesh) Split(factor float64) (err error)

Split all triangles edge on distance `factor`

func (*Mesh) SplitFunc

func (mesh *Mesh) SplitFunc(factorFunc func(p1, p2 Point) bool) (err error)

SplitFunc split all triangles edge on distance only if function argument return true. Example of factorFunc:

factorFunc = func(p1, p2 Point) bool {
	d := gog.Distance(p1, p2)
	return factor < d
}

If factorFunc is not valid, then splitting will be infinite.

type Model

type Model struct {
	Points    []Point  // Points is slice of points
	Lines     [][3]int // Lines store 2 index of Points and last for tag
	Arcs      [][4]int // Arcs store 3 index of Points and last for tag
	Triangles [][4]int // Triangles store 3 index of Points and last for tag/material
	Quadrs    [][5]int // Rectanges store 4 index of Points and last for tag/material
}

Model of points, lines, arcs for prepare of triangulation

func (*Model) AddArc

func (m *Model) AddArc(start, middle, end Point, tag int)

AddArc add arc into model with specific tag

func (*Model) AddCircle

func (m *Model) AddCircle(xc, yc, r float64, tag int)

AddCircle add arcs based on circle geometry into model with specific tag

func (*Model) AddLine

func (m *Model) AddLine(start, end Point, tag int)

AddLine add line into model with specific tag

func (*Model) AddModel

func (m *Model) AddModel(from Model)

AddModel inject model into model

func (*Model) AddMultiline

func (m *Model) AddMultiline(tag int, ps ...Point)

AddMultiline add many lines with specific tag

func (*Model) AddPoint

func (m *Model) AddPoint(p Point) (index int)

AddPoint return index in model slice point

func (*Model) AddTriangle

func (m *Model) AddTriangle(start, middle, end Point, tag int)

AddTriangle add triangle into model with specific tag/material

func (*Model) ArcsToLines

func (m *Model) ArcsToLines()

ArcsToLines convert arc to lines

func (*Model) Combine

func (m *Model) Combine(factorOneLine float64) (err error)

Combine triangles to quadr with same tag

factorOneLine from 1 to 2/sqrt(2) = 1.41

Recommendation value is 1.05

func (*Model) ConvexHullTriangles

func (m *Model) ConvexHullTriangles()

ConvexHullTriangles add triangles of model convex hull

func (Model) Copy

func (src Model) Copy() (dst Model)

Copy return copy of Model

func (Model) Dxf

func (m Model) Dxf() string

Dxf return string in dxf drawing format https://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf

func (*Model) Get

func (model *Model) Get(mesh *Mesh)

Get add into Model all triangles from Mesh Recommendation after `Get` : model.Intersection()

func (*Model) Intersection

func (m *Model) Intersection()

Intersection change model with finding all model intersections

func (Model) JSON

func (m Model) JSON() (_ string, err error)

JSON convert model in JSON format

func (*Model) Merge

func (to *Model) Merge(from Model)

Merge `from` model to `to` model

func (Model) MinPointDistance

func (m Model) MinPointDistance() (distance float64)

MinPointDistance return minimal between 2 points

func (Model) Mirror

func (m Model) Mirror(p1, p2 Point) (mir Model, err error)

Mirror return mirror of model

func (*Model) Move

func (m *Model) Move(dx, dy float64)

Move all points of model

func (*Model) Read

func (m *Model) Read(filename string) (err error)

Read model from file with filename in JSON format

func (*Model) RemoveEmptyPoints

func (m *Model) RemoveEmptyPoints()

RemoveEmptyPoints removed point not connected to line, arcs, triangles

func (*Model) RemovePoint

func (m *Model) RemovePoint(remove func(p Point) bool)

RemovePoint removed point in accoding to function `filter`

func (*Model) Rotate

func (m *Model) Rotate(xc, yc, angle float64)

Rotate all points of model around point {xc,yc}

func (*Model) Split

func (m *Model) Split(d float64)

Split all model lines, arcs by distance `d`

func (Model) String

func (m Model) String() string

String return a stantard model view

func (Model) TagProperty

func (m Model) TagProperty() (length []float64, area []float64)

TagProperty return length of lines, area of triangles for each tag. Arcs are ignored

func (Model) Write

func (m Model) Write(filename string) (err error)

Write model into file with filename in JSON format

type OrientationPoints

type OrientationPoints int8

OrientationPoints is orientation points state

func Orientation

func Orientation(p1, p2, p3 Point) OrientationPoints
Example
var (
	delta = 1.0
	s     = Point{0, 1}
	f     = Point{0, 0}
)
for i := 1; i < 30; i++ {
	value := Orientation(s, Point{delta, 0}, f)
	fmt.Fprintf(os.Stdout, "%.1e\t%+d\n", delta, value)
	delta /= 10.0
}
Output:

1.0e+00	+0
1.0e-01	+0
1.0e-02	+0
1.0e-03	+0
1.0e-04	+0
1.0e-05	+0
1.0e-06	+0
1.0e-07	+0
1.0e-08	+0
1.0e-09	+0
1.0e-10	+0
1.0e-11	-1
1.0e-12	-1
1.0e-13	-1
1.0e-14	-1
1.0e-15	-1
1.0e-16	-1
1.0e-17	-1
1.0e-18	-1
1.0e-19	-1
1.0e-20	-1
1.0e-21	-1
1.0e-22	-1
1.0e-23	-1
1.0e-24	-1
1.0e-25	-1
1.0e-26	-1
1.0e-27	-1
1.0e-28	-1

func Orientation128

func Orientation128(p1, p2, p3 Point) OrientationPoints

type Point

type Point struct {
	X, Y float64
}

Point is store of point coordinates

func ConvexHull

func ConvexHull(points []Point, withoutCollinearPoints bool) (chain []int, res []Point)

ConvexHull return chain of convex points

func MiddlePoint

func MiddlePoint(p0, p1 Point) Point

MiddlePoint calculate middle point precisionally.

Example
// that example show function Orientation
// cannot recongize middle point
factor := 1.0
for p := 0; p < 20; p++ {
	success := 0
	amount := 0
	for i := range tcs {
		for p := range tcs[i].ps {
			if p == 0 {
				continue
			}
			s := tcs[i].ps[p-1]
			x := tcs[i].ps[p].X * factor
			y := tcs[i].ps[p].Y * factor
			f := Point{X: x, Y: y}
			mid := MiddlePoint(s, f)
			amount++
			if Orientation(s, mid, f) == CollinearPoints {
				success++
			}
			amount++
			if Orientation(mid, s, f) == CollinearPoints {
				success++
			}
			amount++
			if Orientation(s, f, mid) == CollinearPoints {
				success++
			}
		}
	}
	fmt.Fprintf(os.Stdout, "factor: %5.1e success %5d of %5d - %.3f%%\n",
		factor, success, amount, float64(success)/float64(amount))
	factor *= 10.0
}

fmt.Fprintf(os.Stdout, "calculate average of 2 float values\n")
a := math.Pow(float64(math.Pi), math.Pi*10.0) * 1e45
b := float64(math.E)
var mid float64
{
	const prec = 256
	var (
		half = new(big.Float).SetPrec(prec).SetFloat64(0.5)
		x0   = new(big.Float).SetPrec(prec).SetFloat64(a)
		x1   = new(big.Float).SetPrec(prec).SetFloat64(b)
	)
	x0.Mul(x0, half)
	x1.Mul(x1, half)
	x0.Add(x0, x1)
	mid, _ = x0.Float64()
}
for _, v := range []struct {
	name  string
	value float64
}{
	{name: "simple", value: (a + b) / 2.0},
	{name: "long simple", value: a*0.5 + b*0.5},
} {
	fmt.Fprintf(os.Stdout, "Name: %20s\tValue: %.25e\tDelta: %.5e\n",
		v.name, v.value, v.value-mid,
	)
}
fmt.Fprintf(os.Stdout, "no need big math\n")
Output:

factor: 1.0e+00 success  9300 of  9300 - 1.000%
factor: 1.0e+01 success  9300 of  9300 - 1.000%
factor: 1.0e+02 success  9300 of  9300 - 1.000%
factor: 1.0e+03 success  9300 of  9300 - 1.000%
factor: 1.0e+04 success  9300 of  9300 - 1.000%
factor: 1.0e+05 success  9300 of  9300 - 1.000%
factor: 1.0e+06 success  9300 of  9300 - 1.000%
factor: 1.0e+07 success  9300 of  9300 - 1.000%
factor: 1.0e+08 success  9300 of  9300 - 1.000%
factor: 1.0e+09 success  9300 of  9300 - 1.000%
factor: 1.0e+10 success  9300 of  9300 - 1.000%
factor: 1.0e+11 success  9300 of  9300 - 1.000%
factor: 1.0e+12 success  9300 of  9300 - 1.000%
factor: 1.0e+13 success  9300 of  9300 - 1.000%
factor: 1.0e+14 success  9300 of  9300 - 1.000%
factor: 1.0e+15 success  9300 of  9300 - 1.000%
factor: 1.0e+16 success  9300 of  9300 - 1.000%
factor: 1.0e+17 success  9300 of  9300 - 1.000%
factor: 1.0e+18 success  9300 of  9300 - 1.000%
factor: 1.0e+19 success  9300 of  9300 - 1.000%
calculate average of 2 float values
Name:               simple	Value: 2.0767962083758179575724271e+60	Delta: 0.00000e+00
Name:          long simple	Value: 2.0767962083758179575724271e+60	Delta: 0.00000e+00
no need big math

func MirrorPoint

func MirrorPoint(mp0, mp1 Point, sp ...Point) (
	mp []Point,
	err error,
)

MirrorPoint return mirror point by line

func Rotate

func Rotate(xc, yc, angle float64, point Point) (p Point)

Rotate point about (xc,yc) on angle

func (Point) String

func (p Point) String() string

String is implementation of Stringer implementation for formating output

type Point3d

type Point3d [3]float64

Point3d is point coordinate in 3D decart system

func BorderPoints

func BorderPoints(ps ...Point3d) (min, max Point3d)

BorderPoints return (min..max) points coordinates

func LineTriangle3dI1

func LineTriangle3dI1(
	l0, l1 Point3d,
	t0, t1, t2 Point3d,
) (
	intersect bool,
	pi []Point3d,
)

LineTriangle3dI1 return intersection points for case if line and triangle is not on one plane. line intersect triangle in one point

func LineTriangle3dI2

func LineTriangle3dI2(
	l0, l1 Point3d,
	t0, t1, t2 Point3d,
) (
	intersect bool,
	pi []Point3d,
)

LineTriangle3dI2 return intersection points if line and triangle located on one plane. Line on triangle plane Line is not zero ignore triangle point on line

func Mirror3d

func Mirror3d(plane [3]Point3d, points ...Point3d) (mir []Point3d)

Mirror3d return mirror points by mirror plane

func PointLineRatio3d

func PointLineRatio3d(
	l0, l1 Point3d,
	ratio float64,
) (
	p Point3d,
)

PointLineRatio3d return point in accroding to line ratio

func TriangleTriangle3d

func TriangleTriangle3d(
	a0, a1, a2 Point3d,
	b0, b1, b2 Point3d,
) (
	intersect bool,
	pi []Point3d,
)

TriangleTriangle3d return intersection points between two triangles. do not intersect with egdes

type State

type State int64

State is result of intersection

const (

	// VerticalSegment return if segment is vertical
	VerticalSegment State

	// HorizontalSegment return if segment is horizontal
	HorizontalSegment

	// ZeroLengthSegment return for zero length segment
	ZeroLengthSegment

	// Parallel is segment A and segment B.
	// Intersection point data is not valid.
	Parallel

	// Collinear return if:
	// Segment A and segment B are collinear.
	// Intersection point data is not valid.
	Collinear

	// OnSegment is intersection point on segment
	OnSegment

	// OnPoint0Segment intersection point on point 0 segment
	OnPoint0Segment

	// OnPoint1Segment intersection point on point 1 segment
	OnPoint1Segment

	// ArcIsLine return only if wrong arc is line
	ArcIsLine

	// ArcIsPoint return only if wrong arc is point
	ArcIsPoint
)

func (State) Has

func (s State) Has(si State) bool

Has is mean s-State has si-State

func (State) Not

func (s State) Not(si State) bool

Not mean s-State have not si-State

func (State) String

func (s State) String() string

String is implementation of Stringer implementation for formating output

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL