diff options
| author | JΓΆrg Frings-FΓΌrst <debian@jff-webhosting.net> | 2020-08-22 14:05:41 +0200 | 
|---|---|---|
| committer | JΓΆrg Frings-FΓΌrst <debian@jff-webhosting.net> | 2020-08-22 14:05:41 +0200 | 
| commit | b55285a77da0e0b829e4ce8d7e09debaabc68e15 (patch) | |
| tree | f622559ef65bbdd3e1c5bdb06098a8f89eec0563 /app/bin/utility.c | |
| parent | d3897ce090dbeb220ed2c782f095597e417cf3cc (diff) | |
| parent | d1ae75703e1ed81d65ea16946dcdb77e7a13adc9 (diff) | |
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'app/bin/utility.c')
| -rw-r--r-- | app/bin/utility.c | 171 | 
1 files changed, 171 insertions, 0 deletions
| diff --git a/app/bin/utility.c b/app/bin/utility.c index d1f798c..93f9979 100644 --- a/app/bin/utility.c +++ b/app/bin/utility.c @@ -217,6 +217,115 @@ void FindPos( coOrd * res, double * beyond, coOrd pos, coOrd orig, double angle,  } +/* Find Arc Intersection + * Given two circles described by centers and radius (C1, R1) (C2, R2) Find the zero, one or two intersection points + * + */ +BOOL_T FindArcIntersections ( coOrd *Pc, coOrd *Pc2, coOrd center1, DIST_T radius1, coOrd center2, DIST_T radius2) { +	double d,a,h; + +	d = sqrt((center2.x-center1.x)*(center2.x-center1.x)+(center2.y-center1.y)*(center2.y-center1.y)); +	if (d >(radius1+radius2)) return FALSE; 		//Too far apart +	if (d<fabs(radius1-radius2)) return FALSE;  	//Inside each other +	if ((d == 0) && (radius1 == radius2)) return FALSE;  // Coincident and the same +	a=((radius1*radius1)-(radius2*radius2)+(d*d))/(2*d); +	if ((radius1*radius1)<(a*a)) return FALSE; +	h = sqrt((radius1*radius1)-(a*a)); + +	coOrd center_c; +	center_c.x = center1.x+a*(center2.x - center1.x)/d; +	center_c.y = center1.y+a*(center2.y - center1.y)/d; + +	(*Pc).x = center_c.x+h*(center2.y-center1.y)/d; +	(*Pc).y = center_c.y-h*(center2.x-center1.x)/d; +	(*Pc2).x = center_c.x-h*(center2.y-center1.y)/d; +	(*Pc2).y = center_c.y+h*(center2.x-center1.x)/d; + +	return TRUE; +} + +/* + * Find Intersections between a line and a circle + * + * |c-x|^2 = r^2 + * + * π₯(π‘)=π+π‘π + * + * where π is a point and π is a vector. + * + * For a point on this line to satisfy the equation, you need to have + * + * (π‘π+(πβπ))β
(π‘π+(πβπ))=π^2 + * + * which is a quadratic in π‘: + * |b|^2*t^2 + 2(a-c).bt +(|a-c|^2-r^2) = 0 + * + * whose solutions are + * + * t = (-2(a-c).b +/- SQRT([2(a-c).b]^2 - 4|b|^2(|a-c|^2-r^2)) / 2|b|^2 + * + */ + +double VectorLength (coOrd v) { +	return sqrt(v.x*v.x+v.y+v.y); +} +double VectorDot (coOrd v1, coOrd v2) { +	return (v1.x*v2.x+ v1.y*v2.y); +} +coOrd VectorSubtract (coOrd v1, coOrd v2) { +	coOrd result; +	result.x = v1.x-v2.x; +	result.y = v1.y-v2.y; +	return result; +} +coOrd VectorAdd (coOrd v1, coOrd v2) { +	coOrd result; +	result.x = v1.x+v2.x; +	result.y = v1.y+v2.y; +	return result; +} + +BOOL_T FindArcAndLineIntersections(coOrd *intersection1, coOrd *intersection2, coOrd c, DIST_T radius, +                                        coOrd point1, coOrd point2 ) +{ +    double dx, dy, cx, cy, A, B, C, det, t; + +    dx = point2.x - point1.x; +    dy = point2.y - point1.y; + +    cx = c.x; +    cy = c.y; + +    A = dx * dx + dy * dy; +    B = 2 * (dx * (point1.x - cx) + dy * (point1.x - cy)); +    C = (point1.x - cx) * (point1.x - cx) + (point1.y - cy) * (point1.y - cy) - radius * radius; + +    det = B * B - 4 * A * C; +    if ((A <= 0.0000001) || (det < 0)) +    { +    	return FALSE; +    } +    else if (det == 0) +    { +        // One solution. +        t = -B / (2 * A); +        (*intersection1).x = point1.x + t * dx; +        (*intersection1).y = point1.y + t * dy; +        intersection2 = intersection1; +        return TRUE; +    } +    else +    { +        // Two solutions. +        t = (float)((-B + sqrt(det)) / (2 * A)); +        (*intersection1).x = point1.x + t * dx; +        (*intersection1).y = point1.y + t * dy; +        t = (float)((-B - sqrt(det)) / (2 * A)); +        (*intersection2).x = point1.x + t * dx; +        (*intersection2).y = point1.y + t * dy; +        return TRUE; +    } +}  /* Find intersection:     Given 2 lines each described by a point and angle (P0,A0) (P1,A1) @@ -489,6 +598,7 @@ static void IntersectBox( coOrd *p1, coOrd p0, coOrd size, int x1, int y1 )  #ifndef WINDOWS  	else  		fprintf(stderr, "intersectBox bogus\n" ); +		getchar();  #endif  } @@ -589,6 +699,67 @@ BOOL_T ClipLine( coOrd *fp0, coOrd *fp1, coOrd orig, double angle, coOrd size )  	return 1;  } +coOrd FindCentroid(int vertexCount, pts_t vertices[] ) +{ +    coOrd centroid = {0, 0}; +    double signedArea = 0.0; +    double x0 = 0.0; // Current vertex X +    double y0 = 0.0; // Current vertex Y +    double x1 = 0.0; // Next vertex X +    double y1 = 0.0; // Next vertex Y +    double a = 0.0;  // Partial signed area + +    // For all vertices except last +    int i=0; +    for (i=0; i<vertexCount-1; ++i) +    { +        x0 = vertices[i].pt.x; +        y0 = vertices[i].pt.y; +        x1 = vertices[i+1].pt.x; +        y1 = vertices[i+1].pt.y; +        a = x0*y1 - x1*y0; +        signedArea += a; +        centroid.x += (x0 + x1)*a; +        centroid.y += (y0 + y1)*a; +    } + +    // Do last vertex separately to avoid performing an expensive +    // modulus operation in each iteration. +    x0 = vertices[i].pt.x; +    y0 = vertices[i].pt.y; +    x1 = vertices[0].pt.x; +    y1 = vertices[0].pt.y; +    a = x0*y1 - x1*y0; +    signedArea += a; +    centroid.x += (x0 + x1)*a; +    centroid.y += (y0 + y1)*a; + +    signedArea *= 0.5; +    centroid.x /= (6.0*signedArea); +    centroid.y /= (6.0*signedArea); + +    return centroid; +} + +double FindArcCenter( +		coOrd * pos, +		coOrd p0, +		coOrd p1, +		double radius ) +{ +	double d; +	double a0, a1; +	d = FindDistance( p0, p1 )/2.0; +	a0 = FindAngle( p0, p1 ); +	a1 = NormalizeAngle(R2D(asin( d/radius ))); +	if (a1 > 180) +		a1 -= 360; +	a0 = NormalizeAngle( a0 + (90.0-a1) ); +	Translate( pos, p0, a0, radius ); +	return a1*2.0; +} + +  #ifdef LATER  BOOL_T ClipArc( double a0, double a1, coOrd pos, double radius, coOrd orig, double angle, double size )  { | 
