Keelan Lightfoot 1年前
父节点
当前提交
e1e03bd5bb
共有 1 个文件被更改,包括 56 次插入590 次删除
  1. 56
    590
      main.go

+ 56
- 590
main.go 查看文件

@@ -1,10 +1,8 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	"bitbucket.wtfast.net/go/fit"
5 4
 	"bufio"
6 5
 	"fmt"
7
-//	"gonum.org/v1/gonum/mat"
8 6
 	"log"
9 7
 	"math"
10 8
 	"os"
@@ -71,7 +69,7 @@ var scale = 1.0
71 69
 
72 70
 func main() {
73 71
 	file, err := os.Open("tp3.nc")
74
-	//file, err := os.Open("tp3.nc")
72
+
75 73
 	if err != nil {
76 74
 		log.Fatal(err)
77 75
 	}
@@ -79,7 +77,6 @@ func main() {
79 77
 
80 78
 	r := regexp.MustCompile(`([A-Z])(\-?[0-9]+\.?[0-9]*)`)
81 79
 
82
-	//lines := make([]line, 0)
83 80
 	lines := make(map[int]*line)
84 81
 	scanner := bufio.NewScanner(file)
85 82
 	lineNumber := 0
@@ -109,8 +106,8 @@ func main() {
109 106
 	var x, y float64
110 107
 	var lastPoints []point
111 108
 	arcs := []*arc{}
112
-	
113
-	for lineNumber:=0;lineNumber<len(lines);lineNumber++ {
109
+
110
+	for lineNumber := 0; lineNumber < len(lines); lineNumber++ {
114 111
 		line := lines[lineNumber]
115 112
 		xyChanged, zChanged, modeChanged := false, false, false
116 113
 		//oldPt := point{x:x,y:y}
@@ -164,28 +161,20 @@ func main() {
164 161
 	if len(lastPoints) > 0 {
165 162
 		arcs = append(arcs, checkPoints4(lastPoints)...)
166 163
 	}
167
-	
168 164
 
169 165
 	// for _, arc := range arcs {
170
-// 		fmt.Printf("-----------------------------\n")
171
-// 		fmt.Printf("     Lines: %d-%d\n",arc.startLine, arc.endLine)
172
-// 		fmt.Printf("    Centre: %0.2f, %0.2f\n", arc.centre.x,arc.centre.y )
173
-// 		fmt.Printf("        SD: %0.4f\n", arc.bestSD )
174
-// 	}
175
-// 	
176
-	
177
-	
166
+	// 		fmt.Printf("-----------------------------\n")
167
+	// 		fmt.Printf("     Lines: %d-%d\n",arc.startLine, arc.endLine)
168
+	// 		fmt.Printf("    Centre: %0.2f, %0.2f\n", arc.centre.x,arc.centre.y )
169
+	// 		fmt.Printf("        SD: %0.4f\n", arc.bestSD )
170
+	// 	}
171
+	//
172
+
178 173
 	numLines := len(lines)
179
-	
174
+
180 175
 	for _, arc := range arcs {
181
-		// fmt.Println("start", arc.startPt)
182
-// 		fmt.Println("end", arc.endPt)
183 176
 		i := arc.centre.x - arc.startPt.x
184 177
 		j := arc.centre.y - arc.startPt.y
185
-		
186
-		// fmt.Printf("G0 X%0.4f Y%0.4f\n", arc.startPt.x, arc.startPt.y)
187
-		//
188
-		// 		fmt.Printf("G2 I%0.4f J%0.4f X%0.4f Y%0.4f\n", -i, -j, arc.endPt.x, arc.endPt.y)
189 178
 
190 179
 		// clear out old commands
191 180
 		for i := arc.startLine; i <= arc.endLine; i++ {
@@ -193,7 +182,7 @@ func main() {
193 182
 		}
194 183
 
195 184
 		//
196
-		lines[arc.startLine]=&line{commands:[]command{
185
+		lines[arc.startLine] = &line{commands: []command{
197 186
 			{verb: "G", noun: 1},
198 187
 			{verb: "X", noun: arc.startPt.x},
199 188
 			{verb: "Y", noun: arc.startPt.y},
@@ -202,19 +191,19 @@ func main() {
202 191
 		if arc.clockwise {
203 192
 			dir = 2.0
204 193
 		}
205
-		lines[arc.startLine+1]=&line{commands:[]command{
194
+		lines[arc.startLine+1] = &line{commands: []command{
206 195
 			{verb: "G", noun: dir},
207 196
 			{verb: "I", noun: i},
208 197
 			{verb: "J", noun: j},
209 198
 			{verb: "X", noun: arc.endPt.x},
210 199
 			{verb: "Y", noun: arc.endPt.y},
211 200
 		}}
212
-		lines[arc.startLine+2]=&line{commands:[]command{
201
+		lines[arc.startLine+2] = &line{commands: []command{
213 202
 			{verb: "G", noun: 1},
214 203
 		}}
215 204
 	}
216 205
 
217
-	for i:=0;i<numLines;i++ {
206
+	for i := 0; i < numLines; i++ {
218 207
 		if lines[i] != nil {
219 208
 			fmt.Println(lines[i].String())
220 209
 		}
@@ -241,23 +230,21 @@ type arc struct {
241 230
 
242 231
 type curveInfo struct {
243 232
 	midpoint int
244
-	width int
233
+	width    int
245 234
 }
246 235
 
247 236
 func checkPoints4(points []point) []*arc {
248 237
 
249
-
250 238
 	numTests := 3
251 239
 
252 240
 	state := "searching"
253
-	
241
+
254 242
 	curveMidPoints := []curveInfo{}
255
-	
243
+
256 244
 	curveStart := 0
257
-	
245
+
258 246
 	for i := 0; i < len(points)-3*numTests; i++ {
259 247
 
260
-	
261 248
 		vX := make([]float64, numTests)
262 249
 		vY := make([]float64, numTests)
263 250
 		vR := make([]float64, numTests)
@@ -267,16 +254,16 @@ func checkPoints4(points []point) []*arc {
267 254
 			vX[j] *= scale
268 255
 			vY[j] *= scale
269 256
 			vR[j] *= scale
270
-			vD[j] =  (vX[j]-points[i+j].x)*(points[i+j+1].y-points[i+j].y) - (vY[j]-points[i+j].y)*(points[i+j+1].x-points[i+j].x)
257
+			vD[j] = (vX[j]-points[i+j].x)*(points[i+j+1].y-points[i+j].y) - (vY[j]-points[i+j].y)*(points[i+j+1].x-points[i+j].x)
271 258
 		}
272 259
 		sd1 := math.Sqrt(math.Pow(stdDev(vX), 2) + math.Pow(stdDev(vY), 2))
273
-	//	sd2 := math.Sqrt(math.Pow(stdDev(vR), 2))
274
-		
260
+		//	sd2 := math.Sqrt(math.Pow(stdDev(vR), 2))
261
+
275 262
 		//fmt.Printf("%d\t%f\n",points[i+9].lineNumber,sd1)
276
-		
263
+
277 264
 		if i == len(points)-3*numTests-1 && state == "curve" {
278 265
 			sd1 = 100 // kludge
279
-		} 
266
+		}
280 267
 		thresh := 2.5 // 2.5
281 268
 		switch state {
282 269
 		case "searching":
@@ -293,529 +280,84 @@ func checkPoints4(points []point) []*arc {
293 280
 			}
294 281
 		case "curve":
295 282
 			if sd1 >= thresh {
296
-				mid := curveStart+((i-curveStart)/2)
283
+				mid := curveStart + ((i - curveStart) / 2)
297 284
 				//fmt.Printf("curve start = %d end = %d mid = %d\n", points[curveStart+9].lineNumber, points[i+9].lineNumber, points[mid+9].lineNumber)
298
-				curveMidPoints=append(curveMidPoints,curveInfo{
299
-					midpoint: mid+(3*numTests)/2-1,
300
-					width:(i-curveStart)+(4*numTests),
285
+				curveMidPoints = append(curveMidPoints, curveInfo{
286
+					midpoint: mid + (3*numTests)/2 - 1,
287
+					width:    (i - curveStart) + (4 * numTests),
301 288
 				})
302 289
 				state = "deadzone"
303 290
 			}
304
-			 
291
+
305 292
 		}
306 293
 	}
307 294
 	//fmt.Println(curveMidPoints)
308 295
 	spillover := 0
309
-	
310
-	arcs := []*arc{}
311
-
312 296
 
297
+	arcs := []*arc{}
313 298
 
314 299
 	for _, midpoint := range curveMidPoints {
315 300
 		vX := make([]float64, 0)
316 301
 		vY := make([]float64, 0)
317 302
 		vR := make([]float64, 0)
318 303
 
319
-		
320
-		var bestStart, bestEnd int 
304
+		var bestStart, bestEnd int
321 305
 		var bestCenter point
322 306
 		var bestRadius float64
323 307
 		thresh := .01
324 308
 		bestSD := 100.0
325
-		
326
-		
327
-	//	fmt.Println("----------")
328
-		for i:=midpoint.width/3;i<midpoint.width/2+spillover;i++ {
329
-			lowerPt  := midpoint.midpoint-i
309
+
310
+		//	fmt.Println("----------")
311
+		for i := midpoint.width / 3; i < midpoint.width/2+spillover; i++ {
312
+			lowerPt := midpoint.midpoint - i
330 313
 			if lowerPt < 0 {
331 314
 				lowerPt = 0
332 315
 			}
333
-			upperPt := midpoint.midpoint+i
334
-			if upperPt > len(points)-1  {
335
-				upperPt = len(points)-1
316
+			upperPt := midpoint.midpoint + i
317
+			if upperPt > len(points)-1 {
318
+				upperPt = len(points) - 1
336 319
 			}
337
-			x,y,r := circleFromThreePointsXYR(points[lowerPt], points[midpoint.midpoint], points[upperPt])
320
+			x, y, r := circleFromThreePointsXYR(points[lowerPt], points[midpoint.midpoint], points[upperPt])
338 321
 			vX = append(vX, x*scale)
339 322
 			vY = append(vY, y*scale)
340 323
 			vR = append(vR, r*scale)
341
-		//	fmt.Printf("lines: %d, %d %d = %0.2f,%0.2f,%0.2f\n", points[lowerPt].lineNumber, points[midpoint.midpoint].lineNumber, points[upperPt].lineNumber, x*scale, y*scale, r*scale)
324
+			//	fmt.Printf("lines: %d, %d %d = %0.2f,%0.2f,%0.2f\n", points[lowerPt].lineNumber, points[midpoint.midpoint].lineNumber, points[upperPt].lineNumber, x*scale, y*scale, r*scale)
342 325
 			sd1 := math.Sqrt(math.Pow(stdDev(vX), 2) + math.Pow(stdDev(vY), 2) + math.Pow(stdDev(vR), 2))
343
-			
326
+
344 327
 			//fmt.Printf("Averages: %d, %d %d = %0.4f\n", points[lowerPt].lineNumber, points[midpoint.midpoint].lineNumber, points[upperPt].lineNumber, sd1)
345 328
 			if sd1 > thresh {
346 329
 				break
347 330
 			}
348 331
 			bestStart, bestEnd = lowerPt, upperPt
349
-			bestCenter = point{x:avg(vX), y:avg(vY)}
332
+			bestCenter = point{x: avg(vX), y: avg(vY)}
350 333
 			bestRadius = avg(vR)
351 334
 			bestSD = sd1
352
-			
353
-		
354
-		
355
-		//	fmt.Printf("Line %d SD=%0.4f start=%d end=%d\n",points[midpoint.midpoint].lineNumber, sd1, points[lowerPt].lineNumber, points[upperPt].lineNumber)
356
-		
335
+
336
+			//	fmt.Printf("Line %d SD=%0.4f start=%d end=%d\n",points[midpoint.midpoint].lineNumber, sd1, points[lowerPt].lineNumber, points[upperPt].lineNumber)
337
+
357 338
 		}
358
-		
359
-		
339
+
360 340
 		arc := arc{
361
-			startPt:   points[bestStart],
362
-			secondPt:  points[bestStart+2],
363
-			endPt:     points[bestEnd],
364
-			startLine: points[bestStart].lineNumber,
365
-			endLine:   points[bestEnd].lineNumber,
341
+			startPt:    points[bestStart],
342
+			secondPt:   points[bestStart+2],
343
+			endPt:      points[bestEnd],
344
+			startLine:  points[bestStart].lineNumber,
345
+			endLine:    points[bestEnd].lineNumber,
366 346
 			startIndex: bestStart,
367
-			endIndex:  bestEnd,
368
-			centre:    point{x:bestCenter.x/scale,y:bestCenter.y/scale},
369
-			radius:    bestRadius/scale,
370
-			bestSD:    bestSD,
347
+			endIndex:   bestEnd,
348
+			centre:     point{x: bestCenter.x / scale, y: bestCenter.y / scale},
349
+			radius:     bestRadius / scale,
350
+			bestSD:     bestSD,
371 351
 		}
372 352
 		d := (arc.centre.x-arc.startPt.x)*(arc.secondPt.y-arc.startPt.y) - (arc.centre.y-arc.startPt.y)*(arc.secondPt.x-arc.startPt.x)
373 353
 		arc.clockwise = d > 0
374
-			//	fmt.Println("QQQ", bestStart, bestEnd, d, arc.clockwise )
354
+		//	fmt.Println("QQQ", bestStart, bestEnd, d, arc.clockwise )
375 355
 
376 356
 		arcs = append(arcs, &arc)
377 357
 	}
378
-return arcs
379
-}
380
-
381
-
382
-func checkPoints3(points []point) []*arc {
383
-
384
-
385
-	numTests := 3
386
-	//foo(points)
387
-	
388
-	arcs := []*arc{}
389
-
390
-	offset := 0
391
-	searching := true
392
-	for searching {
393
-		if len(points)-offset < 3*numTests {
394
-			searching = false
395
-			break
396
-		}
397
-
398
-		arcStart := 0
399
-		var cX, cY, radius float64
400
-
401
-		// find start of a circle
402
-		
403
-		foundArc := false
404
-		for i := offset; i < len(points)-3*numTests; i++ {
405
-			vX := make([]float64, numTests)
406
-			vY := make([]float64, numTests)
407
-			vR := make([]float64, numTests)
408
-			for j := 0; j < numTests; j++ {
409
-				vX[j], vY[j], vR[j] = circleFromThreePointsXYR(points[i+j], points[i+j+numTests], points[i+j+(2*numTests)])
410
-				vX[j] *= scale
411
-				vY[j] *= scale
412
-				vR[j] *= scale
413
-			}
414
-
415
-			sd := math.Sqrt(math.Pow(stdDev(vX), 2) + math.Pow(stdDev(vY), 2) + math.Pow(stdDev(vR), 2))
416
-
417
-			if sd < 1 {
418
-				// looks like a circle
419
-				fmt.Printf("Found candidate arc starting at %d (line %d) (SD=%0.4f)\n", i, points[i].lineNumber+1, sd)
420
-				arcStart = i
421
-				cX = avg(vX)
422
-				cY = avg(vY)								
423
-				fmt.Println(vR)
424
-				radius = avg(vR)
425
-				foundArc = true
426
-				break
427
-			}
428
-		}
429
-		
430
-		if !foundArc {
431
-			searching = false
432
-			break
433
-		}
434
-
435
-		arcSize := numTests*3 // size of arc that came from the search above
436
-
437
-		
438
-		
439
-		var sd float64
440
-		
441
-		mX := []float64{}
442
-		mY := []float64{}
443
-		mR := []float64{}
444
-		
445
-		for i := arcStart; i < len(points)-(numTests*3); i++ {
446
-			x, y, r := circleFromThreePointsXYR(points[arcStart], points[arcStart+(arcSize)/2], points[arcStart+arcSize])
447
-		
448
-			x *= scale
449
-			y *= scale
450
-			r *= scale
451
-				
452
-			mX = append(mX, x)
453
-			mY = append(mY, y)
454
-			mR = append(mR, r)
455
-		
456
-		
457
-			sd = math.Sqrt(math.Pow(avg(mX)-x, 2) + math.Pow(avg(mY)-y, 2) + math.Pow(avg(mR)-r, 2))
458
-			sd = math.Sqrt(math.Pow(cX-x, 2) + math.Pow(cY-y, 2) + math.Pow(radius-r, 2))
459
-			fmt.Printf("testing %d-%d-%d (SD=%0.2f\n", arcStart, arcStart+(arcSize)/2, arcStart+arcSize, sd)
460
-			fmt.Printf("   center 1 X=%0.2f, Y=%0.2f\n", points[arcStart].x, points[arcStart].y)
461
-			fmt.Printf("   center 2 X=%0.2f, Y=%0.2f\n", points[arcStart+(arcSize)/2].x, points[arcStart+(arcSize)/2].y)
462
-			fmt.Printf("   center 3 X=%0.2f, Y=%0.2f\n", points[arcStart+arcSize].x, points[arcStart+arcSize].y)
463
-			
464
-			if sd >= .4 {
465
-				break
466
-			}
467
-			
468
-			arcSize++
469
-		}
470
-		
471
-		cX = avg(mX[:len(mX)-1])
472
-		cY = avg(mY[:len(mY)-1])
473
-		radius = avg(mR[:len(mR)-1])
474
-		
475
-		arcStart++
476
-		
477
-
478
-		if arcStart+arcSize > len(points) {
479
-			searching = false
480
-			break
481
-		}
482
-		
483
-		// 	if arcStart+arcSize == len(points) {
484
-// 				// end condition
485
-		if arcSize > 0 {
486
-			fmt.Printf("Found arc: %d to %d, refining (line %d to %d)...\n", arcStart, arcStart+arcSize-1, points[arcStart].lineNumber+1, points[arcStart+arcSize-1].lineNumber+1)
487
-			bestStart, bestEnd, _, bestRadius, bestCenter := refineArc(points, sd, arcStart, arcSize-1, cX, cY, radius)
488
-			arc := arc{
489
-				startPt:   points[bestStart-1],
490
-				secondPt:  points[bestStart],
491
-				endPt:     points[bestEnd],
492
-				startLine: points[bestStart].lineNumber,
493
-				endLine:   points[bestEnd].lineNumber,
494
-				centre:    point{x:bestCenter.x/scale,y:bestCenter.y/scale},
495
-				radius:    bestRadius/scale,
496
-			}
497
-			d := (arc.centre.x-arc.startPt.x)*(arc.secondPt.y-arc.startPt.y) - (arc.centre.y-arc.startPt.y)*(arc.secondPt.x-arc.startPt.x)
498
-			fmt.Println("d=",d)
499
-			arc.clockwise = d > 0
500
-			
501
-			arcs = append(arcs, &arc)
502
-			
503
-			offset = bestEnd 
504
-			fmt.Printf("Refined arc: %d to %d (Radius=%0.2f)\n", bestStart, bestEnd, bestRadius)
505
-			if arcStart+arcSize == len(points)-1 {
506
-				searching = false
507
-			}
508
-		}
509
-				
510
-// 			}
511
-
512
-		//}
513
-	}
514
-
515
-	for _, arc := range arcs {
516
-		d := (arc.centre.x-arc.startPt.x)*(arc.secondPt.y-arc.startPt.y) - (arc.centre.y-arc.startPt.y)*(arc.secondPt.x-arc.startPt.x)
517
-		arc.clockwise = d > 1
518
-	}
519
-
520 358
 	return arcs
521 359
 }
522 360
 
523
-
524
-// func foo(points []point) {
525
-// 		
526
-// 		
527
-// 	arcStart := 0
528
-// 	arcEnd  := 0
529
-// 	centre := point{}
530
-// 	
531
-// 	// find start of a circle
532
-// 	for ; arcStart < len(points)-9; arcStart++ {
533
-// 		
534
-// 		vX := make([]float64, 3)
535
-// 		vY := make([]float64, 3)
536
-// 		vR := make([]float64, 3)
537
-// 		for j := 0; j < 3; j++ {
538
-// 			vX[j], vY[j], vR[j] = circleFromThreePointsXYR(points[arcStart+j], points[arcStart+j+3], points[arcStart+j+6])
539
-// 		}
540
-// 
541
-// 		sd := math.Sqrt(math.Pow(stdDev(vX), 2) + math.Pow(stdDev(vY), 2) + math.Pow(stdDev(vR), 2))
542
-// 
543
-// 		if sd < 1 {
544
-// 			// looks like a circle
545
-// 			fmt.Printf("Found candidate arc starting at %d (SD=%0.4f)\n", arcStart, sd)
546
-// 			centre = point{x:avg(vX), y: avg(vY)}
547
-// 			arcEnd = arcStart+9
548
-// 		//	radius = avg(vR)
549
-// 			break
550
-// 		}
551
-// 	}
552
-// 		
553
-// 		
554
-// 		
555
-// 		
556
-// 		
557
-// 	for ;arcEnd<len(points)-9; arcEnd++ {
558
-// 	
559
-// 
560
-// 		centre2, chi2 := refineCenter(points[arcStart:arcEnd+1], centre)
561
-// 		fmt.Println("foo", chi2, centre, centre2, len(points[arcStart:arcEnd+1])	)
562
-// 		
563
-// 	}	
564
-// // 		
565
-// // 		arcEnd := arcStart+9
566
-// // 		for ; arcEnd < len(points)-9; arcEnd++ {
567
-// // 			centre, chi2 := refineCenter(points[arcStart:arcEnd+1], point{x:cX,y:cY})
568
-// // 			fmt.Println(centre, chi2)
569
-// // 			if chi2 > 1 {
570
-// // 				break
571
-// // 			}
572
-// // 		}
573
-// // 		arcEnd--
574
-// // 		
575
-// // 		centre, chi2 := refineCenter(points[arcStart:arcEnd+1], point{x:cX,y:cY})
576
-// // 
577
-// // 		fmt.Printf("Found arc: %d to %d (SD=%0.4f)\n", arcStart, arcEnd, chi2)
578
-// // 		arcs = append(arcs, &arc{
579
-// // 			startPt:   points[arcStart],
580
-// // 			secondPt:  points[arcStart+1],
581
-// // 			endPt:     points[arcEnd],
582
-// // 			startLine: points[arcStart].lineNumber,
583
-// // 			endLine:   points[arcEnd].lineNumber,
584
-// // 			centre:    centre,
585
-// // 			//radius:    bestRadius,
586
-// // 		})
587
-// // 		offset = arcEnd + 1		
588
-// }
589
-
590
-
591
-func refineArc(points []point, sd float64, arcStart, arcSize int, cX, cY, cR float64) (int, int, float64, float64, point) {
592
-
593
-
594
-	return arcStart, arcStart+arcSize-1, sd, cR, point{x:cX,y:cY}
595
-
596
-
597
-	var ax, ay, ar float64
598
-	n := 0
599
-	
600
-	for i:=arcStart+1; i<arcStart+(arcSize-1)/3; i++ {
601
-		//fmt.Println("offsets", i, i+(arcSize-1)/3, i+((arcSize-1)/3)*2)
602
-		x, y, r := circleFromThreePointsXYR(points[i], points[i+(arcSize-1)/3], points[i+((arcSize-1)/3)*2])
603
-	//	fmt.Println(x,y,r)
604
-		ax += x
605
-		ay += y
606
-		ar += r 
607
-		n++
608
-	}
609
-	
610
-	// fmt.Println("before", cX, cY, cR)
611
-// 	fmt.Println("average", ax/float64(n), ay/float64(n), ar/float64(n))
612
-// 	
613
-	return arcStart, arcStart+arcSize-1, sd, ar/float64(n), point{x:ax/float64(n),y:ay/float64(n)}
614
-	
615
-	//return arcStart, arcStart+arcSize-1, sd, cR, point{x:cX,y:cY}
616
-
617
-
618
-	bestSD := sd
619
-	bestEnd := 0
620
-	bestStart := 0
621
-	bestRadius := 0.0
622
-	bestCenter := point{}
623
-
624
-	refineDistance := 5
625
-
626
-	for startOffset := 0; startOffset < refineDistance; startOffset++ {
627
-		for endOffset := 0; endOffset < refineDistance; endOffset++ {
628
-
629
-			//fmt.Println("testing end:", arcStart+arcSize-q)
630
-
631
-			sd2, r2, c2, ok := checkArc(points[arcStart+startOffset], points[arcStart+(arcSize-1)/2], points[arcStart+(arcSize-1)-endOffset], cX, cY, cR)
632
-			if ok {
633
-				//	fmt.Println("GGG",sd2,r2,(arcSize-endOffset)-startOffset)
634
-			}
635
-			if ok && sd2 < bestSD {
636
-				bestSD = sd2
637
-				bestEnd = arcStart + arcSize - 1 - endOffset
638
-				bestStart = arcStart + startOffset
639
-				bestRadius = r2
640
-				bestCenter = c2
641
-			}
642
-		}
643
-	}
644
-	return bestStart, bestEnd, bestSD, bestRadius, bestCenter
645
-}
646
-
647
-func checkArc(p1, p2, p3 point, cX, cY, cR float64) (float64, float64, point, bool) {
648
-	if p1 == p2 || p1 == p3 || p2 == p3 {
649
-		return 0, 0, point{}, false
650
-	}
651
-	x2, y2, r2 := circleFromThreePointsXYR(p1, p2, p3)
652
-	sd2 := math.Sqrt(math.Pow(cX-x2, 2) + math.Pow(cY-y2, 2) + math.Pow(cR-r2, 2))
653
-	return sd2, r2, point{x: x2, y: y2}, true
654
-}
655
-
656
-// func checkPoints(points []point) {
657
-//
658
-// 	if len(points) < 3 {
659
-// 		return
660
-// 	}
661
-//
662
-// 	fmt.Println("LEN",len(points))
663
-//
664
-// 	crs := make([]cr,0)
665
-//
666
-//
667
-// 	for i:=0;i<len(points)-3;i++ {
668
-// 		crs = append(crs, circleFromThreePointsCr(points[i], points[i+1], points[i+2]))
669
-// 	}
670
-//
671
-// // 	for _, v := range crs {
672
-// // 		fmt.Print("source x: ", v.x)
673
-// // 		fmt.Print(" y: ", v.y)
674
-// // 		fmt.Println(" r: ", v.r)
675
-// // 	}
676
-// //
677
-//
678
-// //
679
-// // 	circlePoints := make([]cr,3) // start a new circle
680
-// // 	copy(circlePoints, crs[:3])
681
-// //
682
-// //
683
-// 	arcStart := 0
684
-// 	circleEnd := 3
685
-//
686
-// 	for i:=circleEnd;i<len(crs); {
687
-//
688
-// 		np := crs[i]
689
-//
690
-// 	// 	if circleEnd-arcStart < 3 {
691
-// // 			fmt.Printf("circle is too small (%d-%d)\n", arcStart, circleEnd)
692
-// // 			i++
693
-// // 			circleEnd = i
694
-// //
695
-// // 			continue
696
-// // 		}
697
-//
698
-// 		fmt.Println("====================")
699
-//
700
-// 		circlePoints := crs[arcStart:circleEnd]
701
-//
702
-// 		// for _, v := range circlePoints {
703
-// // 			fmt.Print("existing x: ", v.x)
704
-// // 			fmt.Print(" y: ", v.y)
705
-// // 			fmt.Println(" r: ", v.r)
706
-// // 		}
707
-//
708
-//
709
-// 		yVals := make([]float64, len(circlePoints))
710
-// 		for j :=0; j<len(circlePoints)-1;j++ {
711
-// 			yVals[j] = np.dist(circlePoints[j])
712
-// 		}
713
-// 		sd := stdDev(yVals)
714
-//
715
-// 		fmt.Print("testing x: ", np.x)
716
-// 		fmt.Print(" y: ", np.y)
717
-// 		fmt.Println(" r: ", np.r)
718
-//
719
-// 		fmt.Println("STDDEV:",sd)
720
-//
721
-//
722
-// 		if sd <  7 {
723
-// 			i++
724
-// 			circleEnd++
725
-// 			fmt.Printf("  growing to %d-%d\n", arcStart, circleEnd)
726
-// 			// fits the existing circle, so add it
727
-//
728
-// 		} else {
729
-//
730
-// 			dumpPoints (crs[arcStart:circleEnd])
731
-//
732
-// 			fmt.Printf("  discarding %d-%d\n", arcStart, circleEnd)
733
-// 			i++
734
-// 			arcStart=i
735
-// 			circleEnd=arcStart+3
736
-//
737
-// 			fmt.Printf("  starting new circle at %d-%d\n", arcStart, circleEnd)
738
-// 			// no fit, start a new circle
739
-// 			// crs[i+1].dump()
740
-// // 			crs[i].dump()
741
-// // 			crs[i-1].dump()
742
-// // 			crs[i-2].dump()
743
-//
744
-//
745
-// 		}
746
-//
747
-//
748
-// 	}
749
-//
750
-// 				dumpPoints (crs[arcStart:circleEnd])
751
-//
752
-// 	fmt.Printf("  discarding final %d-%d\n", arcStart, circleEnd)
753
-//
754
-// }
755
-//
756
-// func dumpPoints (circlePoints []cr) {
757
-// 	for _, v := range circlePoints {
758
-// 		fmt.Print("existing x: ", v.x)
759
-// 		fmt.Print(" y: ", v.y)
760
-// 		fmt.Println(" r: ", v.r)
761
-// 	}
762
-// }
763
-//
764
-// func (cr *cr) dump() {
765
-// 	fmt.Println("xxx OVER",cr.p1, cr.p2, cr.p3)
766
-// 	// fmt.Println("xxx OVER p1-p2",cr.p1.distance(&cr.p2))
767
-// // 	fmt.Println("xxx OVER p2-p3",cr.p2.distance(&cr.p3))
768
-// }
769
-//
770
-//
771
-//
772
-func refineCenter(points []point, centre point) (point, float64) {
773
-	
774
-//	fmt.Println("LEN",len(points), points)
775
-	
776
-	xVals := &fit.CartesianModel{}
777
-	
778
-	for _, pt := range points {
779
-		xVals.Points = append(xVals.Points, fit.Point{X:pt.x, Y:pt.y})
780
-	}
781
-	
782
-	yVals := []float64{}
783
-	for _, pt := range points {
784
-		yVals = append(yVals, pt.distance(&centre))
785
-	}
786
-	
787
-// 	//fmt.Println(yVals)
788
-	initialParams := make([]float64, 2)
789
-	for _, point := range xVals.Points {
790
-		initialParams[0] += point.X
791
-		initialParams[1] += point.Y
792
-	}
793
-	initialParams[0] /= float64(xVals.Len())
794
-	initialParams[1] /= float64(xVals.Len())
795
-// 	initialParams[0] = centre.x
796
-// 	initialParams[1] = centre.y
797
-	
798
-	
799
-	f, err := fit.NewFitter(xVals, yVals, nil, initialParams, fit.Options{fit.OptionDebug: false})
800
-	if err != nil {
801
-		panic(err)
802
-	}
803
-// 	stopReason := f.Run()
804
-// 	fmt.Println("foo Done! Stop reason: ", stopReason)
805
-	out := f.Params()
806
-
807
-	// fmt.Println(" x: ", out[0])
808
-// 	fmt.Println(" y: ", out[1])
809
-// 	fmt.Println(" cX: ", centre.x)
810
-// 	fmt.Println(" cY: ", centre.y)
811
-// 	fmt.Println(" chi2: ", f.Chi2())
812
-//	fmt.Println(" Rersiduals: ", f.Residuals())
813
- 	return point{x:out[0],y:out[1]}, f.Chi2()
814
-
815
-}
816
-
817
-
818
-
819 361
 func stdDev(num []float64) float64 {
820 362
 	sum := 0.0
821 363
 	for _, n := range num {
@@ -847,79 +389,3 @@ func circleFromThreePointsXYR(p1 point, p2 point, p3 point) (float64, float64, f
847 389
 	r := math.Sqrt(math.Pow((x-p1.x), 2) + math.Pow((y-p1.y), 2))
848 390
 	return x, y, r
849 391
 }
850
-
851
-//
852
-// func circleFromThreePointsCr(p1 point, p2 point, p3 point) cr {
853
-// 	A := p1.x*(p2.y-p3.y) - p1.y*(p2.x-p3.x) + p2.x*p3.y - p3.x*p2.y
854
-// 	B := (math.Pow(p1.x, 2)+math.Pow(p1.y, 2))*(p3.y-p2.y) + (math.Pow(p2.x, 2)+math.Pow(p2.y, 2))*(p1.y-p3.y) + (math.Pow(p3.x, 2)+math.Pow(p3.y, 2))*(p2.y-p1.y)
855
-// 	C := (math.Pow(p1.x, 2)+math.Pow(p1.y, 2))*(p2.x-p3.x) + (math.Pow(p2.x, 2)+math.Pow(p2.y, 2))*(p3.x-p1.x) + (math.Pow(p3.x, 2)+math.Pow(p3.y, 2))*(p1.x-p2.x)
856
-// 	x := -1 * B / (2.0 * A)
857
-// 	y := -1 * C / (2.0 * A)
858
-// 	r := math.Sqrt(math.Pow((x-p1.x), 2) + math.Pow((y-p1.y), 2))
859
-// 	return cr{p1: p1, p2:p2, p3:p3, x: x, y: y, r: r}
860
-// }
861
-//
862
-//
863
-//
864
-//
865
-// func circleFromThreePoints(p1 point, p2 point, p3 point) (point, float64) {
866
-// 	A := p1.x*(p2.y-p3.y) - p1.y*(p2.x-p3.x) + p2.x*p3.y - p3.x*p2.y
867
-// 	B := (math.Pow(p1.x, 2)+math.Pow(p1.y, 2))*(p3.y-p2.y) + (math.Pow(p2.x, 2)+math.Pow(p2.y, 2))*(p1.y-p3.y) + (math.Pow(p3.x, 2)+math.Pow(p3.y, 2))*(p2.y-p1.y)
868
-// 	C := (math.Pow(p1.x, 2)+math.Pow(p1.y, 2))*(p2.x-p3.x) + (math.Pow(p2.x, 2)+math.Pow(p2.y, 2))*(p3.x-p1.x) + (math.Pow(p3.x, 2)+math.Pow(p3.y, 2))*(p1.x-p2.x)
869
-// 	x := -1 * B / (2.0 * A)
870
-// 	y := -1 * C / (2.0 * A)
871
-// 	r := math.Sqrt(math.Pow((x-p1.x), 2) + math.Pow((y-p1.y), 2))
872
-// 	return point{x: x, y: y}, r
873
-// }
874
-//
875
-//
876
-//
877
-//
878
-
879
-func (p *point) distance(p2 *point) float64 {
880
-	return math.Sqrt(math.Pow(p.x-p2.x, 2) + math.Pow(p.y-p2.y, 2))
881
-}
882
-
883
-func (p *point) bearing(p2 *point) float64 {
884
-	return math.Atan2(p.y-p2.y, p.x-p2.x)
885
-}
886
-
887
-// type cr struct {
888
-// 	p1, p2, p3 point
889
-// 	x, y, r    float64
890
-// }
891
-// 
892
-// var _ fit.Model = &CircleModel{}
893
-// 
894
-// type CircleModel struct {
895
-// 	points []cr
896
-// }
897
-// 
898
-// func NewCircleModel() *CircleModel {
899
-// 	return &CircleModel{
900
-// 		points: make([]cr, 0),
901
-// 	}
902
-// }
903
-// func (c *CircleModel) Len() int {
904
-// 	return len(c.points)
905
-// }
906
-// 
907
-// func (c *CircleModel) Model(i int, params *mat.VecDense) float64 {
908
-// 	p := c.points[i]
909
-// 	return math.Sqrt(math.Pow((p.x-params.AtVec(0)), 2) + math.Pow((p.y-params.AtVec(1)), 2) + math.Pow((p.r-params.AtVec(2)), 2))
910
-// }
911
-// 
912
-// func (c *CircleModel) InitialParams() []float64 {
913
-// 	initialParams := make([]float64, 3)
914
-// 	if len(c.points) > 0 {
915
-// 		for _, p := range c.points {
916
-// 			initialParams[0] += p.x
917
-// 			initialParams[1] += p.y
918
-// 			initialParams[2] += p.r
919
-// 		}
920
-// 		initialParams[0] /= float64(len(c.points))
921
-// 		initialParams[1] /= float64(len(c.points))
922
-// 		initialParams[2] /= float64(len(c.points))
923
-// 	}
924
-// 	return initialParams
925
-// }