你能试试这个吗?
Sub RemoveLinearlyDependentPoints()
Dim rngX As Range, rngY As Range, rngData As Range, rngRemove As Range
Dim lCount As Long, dSlope1 As Double, dSlope2 As Double
Dim varX As Variant, varY As Variant
Const EPSILON = 0.0001
' Change ranges as needed
Set rngX = Range("A1:A5")
Set rngY = Range("B1:B5")
Set rngData = Union(rngX, rngY)
rngData.Sort key1:=rngX, Order1:=xlAscending
' Working with arrays instead of ranges is faster,
' can make a big different for large datasets
varX = rngX.Value
varY = rngY.Value
With WorksheetFunction
For lCount = 1 To rngX.Count - 2
dSlope1 = .Slope(Array(varX(lCount, 1), varX(lCount + 1, 1)), Array(varY(lCount, 1), varY(lCount + 1, 1)))
dSlope2 = .Slope(Array(varX(lCount + 1, 1), varX(lCount + 2, 1)), Array(varY(lCount + 1, 1), varY(lCount + 2, 1)))
' If slopes are the same, point in row lCount+1 can be removed
If Abs(dSlope1 - dSlope2) < EPSILON Then
If Not rngRemove Is Nothing Then
Set rngRemove = Union(rngRemove, .Index(rngData, lCount + 1, 0))
Else
Set rngRemove = .Index(rngData, lCount + 1, 0)
End If
End If
Next lCount
End With
' Mark the cells red for checking
rngRemove.Cells.Interior.Color = vbRed
' Uncomment the below to delete the cells
'rngRemove.EntireRow.Delete (xlUp)
End Sub
这个想法是,如果数据按照它们的x
坐标排序,我们只需要保留斜率变化的点。因此,只要斜率在两对连续的(A,B)
和中不变(B,C)
,B
就可以移除,因为它与 位于同一条线上(A,C)
。我们只需要检查斜率,因为数据是相对于 排序的x
,因此我们知道这一点x_A <= x_B <= x_C
。
对于给定的示例,
输入:
![在此处输入图像描述](https://i.stack.imgur.com/o0pOh.png)
输出:
![在此处输入图像描述](https://i.stack.imgur.com/dgGtU.png)
我希望这有帮助!