Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -741,44 +741,6 @@ struct FloatingControlPanel: View {
/// 各種制御ボタン(自動配置、リセット、キャリブレーション結果、戻る、次へ)を表示します。
private var controlButtonsView: some View {
VStack(spacing: 8) {
HStack(spacing: 8) {
Button("自動配置") {
self.viewModel.autoArrangeAntennas()
}
.frame(maxWidth: .infinity)
.padding(.vertical, 10)
.background(Color.blue.opacity(0.1))
.foregroundColor(.blue)
.cornerRadius(8)
.buttonStyle(.plain)

Button("リセット") {
self.viewModel.resetPositions()
}
.frame(maxWidth: .infinity)
.padding(.vertical, 10)
.background(Color.orange.opacity(0.1))
.foregroundColor(.orange)
.cornerRadius(8)
.buttonStyle(.plain)
}

Button {
self.viewModel.showCalibrationResultVisualization()
} label: {
HStack {
Image(systemName: "chart.xyaxis.line")
Text("キャリブレーション結果")
}
.frame(maxWidth: .infinity)
.padding(.vertical, 10)
.background(Color.purple.opacity(0.1))
.foregroundColor(.purple)
.cornerRadius(8)
}
.buttonStyle(.plain)
.disabled(!self.viewModel.hasCalibrationData)

HStack(spacing: 8) {
Button("戻る") {
self.flowNavigator.goToPreviousStep()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,95 +455,6 @@ class AntennaPositioningViewModel: ObservableObject {
return false
}

func autoArrangeAntennas() {
// フロアマップのアスペクト比を考慮した基準キャンバスサイズを設定
let baseSize: CGFloat = 400
let aspectRatio = self.floorMapAspectRatio

let canvasSize: CGSize
if aspectRatio > 1.0 {
// 横長
canvasSize = CGSize(width: baseSize, height: baseSize / aspectRatio)
} else {
// 縦長または正方形
canvasSize = CGSize(width: baseSize * aspectRatio, height: baseSize)
}

let margin: CGFloat = 60
let availableWidth = canvasSize.width - (margin * 2)
let availableHeight = canvasSize.height - (margin * 2)

let deviceCount = self.antennaPositions.count

if deviceCount <= 0 { return }

// 三角形、四角形、その他の形状で自動配置
if deviceCount == 3 {
// 三角形配置
let positions = [
CGPoint(x: canvasSize.width / 2, y: margin),
CGPoint(x: margin, y: availableHeight + margin),
CGPoint(x: availableWidth + margin, y: availableHeight + margin),
]
for (index, position) in positions.enumerated() {
if index < self.antennaPositions.count {
self.antennaPositions[index].position = position
self.antennaPositions[index].normalizedPosition = CGPoint(
x: position.x / canvasSize.width,
y: position.y / canvasSize.height
)
}
}
} else if deviceCount == 4 {
// 四角形配置
let positions = [
CGPoint(x: margin, y: margin),
CGPoint(x: availableWidth + margin, y: margin),
CGPoint(x: margin, y: availableHeight + margin),
CGPoint(x: availableWidth + margin, y: availableHeight + margin),
]
for (index, position) in positions.enumerated() {
if index < self.antennaPositions.count {
self.antennaPositions[index].position = position
self.antennaPositions[index].normalizedPosition = CGPoint(
x: position.x / canvasSize.width,
y: position.y / canvasSize.height
)
}
}
} else {
// 円形配置
let center = CGPoint(x: canvasSize.width / 2, y: canvasSize.height / 2)
let radius = min(availableWidth, availableHeight) / 2

for (index, _) in self.antennaPositions.enumerated() {
let angle = (2 * Double.pi * Double(index)) / Double(deviceCount)
let x = center.x + CGFloat(cos(angle)) * radius
let y = center.y + CGFloat(sin(angle)) * radius
let position = CGPoint(x: x, y: y)
self.antennaPositions[index].position = position
self.antennaPositions[index].normalizedPosition = CGPoint(
x: position.x / canvasSize.width,
y: position.y / canvasSize.height
)
}
}
self.updateCanProceed()
}

func resetPositions() {
for index in self.antennaPositions.indices {
let resetPosition = CGPoint(x: 50, y: 50)
self.antennaPositions[index].position = resetPosition
self.antennaPositions[index].normalizedPosition = CGPoint(x: 0.125, y: 0.125) // 50/400 = 0.125
self.antennaPositions[index].rotation = 0.0

// SwiftDataの位置もリセット
self.saveAntennaPositionToSwiftData(self.antennaPositions[index])
}
self.updateCanProceed()
}

func addNewDevice(name: String) {

let newDevice = AndroidDevice(
Expand Down Expand Up @@ -929,74 +840,6 @@ class AntennaPositioningViewModel: ObservableObject {
}
}
}

/// キャリブレーション結果を表示
/// 現在のアンテナ位置と初期位置を比較表示
func showCalibrationResultVisualization() {
guard let floorMapInfo else {
print("❌ FloorMapInfo が取得できません")
return
}

// タグ位置を取得(キャリブレーションデータから)
let tags = self.calibrationData.flatMap { data in
data.calibrationPoints.map { point in
TagPosition(
id: UUID().uuidString,
name: "Tag",
position: point.realWorldCoordinate
)
}
}

// 初期アンテナ位置を取得(デフォルト位置または保存されたデータ)
let initialPositions = self.antennaPositions.map { antenna in
// デフォルト位置(0.125, 0.125)の場合は、適切な初期値を設定
let position: Point3D
if antenna.normalizedPosition == CGPoint(x: 0.125, y: 0.125) {
// デフォルト位置の場合は、フロアマップの中央に配置
position = Point3D(
x: floorMapInfo.width / 2.0,
y: floorMapInfo.depth / 2.0,
z: 0
)
} else {
// 正規化座標から実世界座標に変換
let realWorldX = Double(antenna.normalizedPosition.x) * floorMapInfo.width
let realWorldY = (1.0 - Double(antenna.normalizedPosition.y)) * floorMapInfo.depth
position = Point3D(x: realWorldX, y: realWorldY, z: 0)
}

return AntennaCalibrationPosition(
id: antenna.id,
name: antenna.deviceName,
position: position,
rotation: antenna.rotation
)
}

// 現在のアンテナ位置を取得
let calibratedPositions = self.antennaPositions.map { antenna in
// 正規化座標から実世界座標に変換
let realWorldX = Double(antenna.normalizedPosition.x) * floorMapInfo.width
let realWorldY = (1.0 - Double(antenna.normalizedPosition.y)) * floorMapInfo.depth

return AntennaCalibrationPosition(
id: antenna.id,
name: antenna.deviceName,
position: Point3D(x: realWorldX, y: realWorldY, z: 0),
rotation: antenna.rotation
)
}

self.calibrationResultData = CalibrationResultData(
tagPositions: tags,
initialAntennaPositions: initialPositions,
calibratedAntennaPositions: calibratedPositions
)

self.showCalibrationResult = true
}
}

// MARK: - Data Models
Expand Down
Loading