Skip to content

Commit 311bff4

Browse files
committed
PAINTROID-396 Multiline tool with movable intermediate points
avoid vertex being outside of drawing surface
1 parent 6a498dd commit 311bff4

File tree

1 file changed

+58
-6
lines changed

1 file changed

+58
-6
lines changed

Paintroid/src/main/java/org/catrobat/paintroid/tools/implementation/DynamicLineTool.kt

+58-6
Original file line numberDiff line numberDiff line change
@@ -295,31 +295,83 @@ class DynamicLineTool(
295295
}
296296

297297
private fun updateMovingGhostVertices(coordinate: PointF) {
298+
var movingVertexCenter: PointF = getMovingVertexCenter(coordinate)
298299
if (movingVertex != null) {
299-
movingVertex?.updateVertexCenter(copyPointF(coordinate))
300+
movingVertex?.updateVertexCenter(copyPointF(movingVertexCenter))
300301
if (movingVertex?.ingoingPathCommand != null) {
301302
ingoingStartCoordinate = predecessorVertex?.vertexCenter?.let { center -> copyPointF(center) }
302-
ingoingEndCoordinate = copyPointF(coordinate)
303+
ingoingEndCoordinate = copyPointF(movingVertexCenter)
303304
ingoingGhostPathPaint = createGhostPathPaint(movingVertex?.ingoingPathCommand?.paint)
304305
}
305306
if (movingVertex?.outgoingPathCommand != null) {
306-
outgoingStartCoordinate = copyPointF(coordinate)
307+
outgoingStartCoordinate = copyPointF(movingVertexCenter)
307308
outgoingEndCoordinate = successorVertex?.vertexCenter?.let { center -> copyPointF(center) }
308309
outgoingGhostPathPaint = createGhostPathPaint(movingVertex?.outgoingPathCommand?.paint)
309310
}
310311
}
311312
}
312313

314+
private fun getMovingVertexCenter(coordinate: PointF): PointF {
315+
var insidePoint: PointF? = getInsidePoint()
316+
var outsidePoint = copyPointF(coordinate)
317+
return calculateMovingVertexCenter(insidePoint, outsidePoint)
318+
}
319+
320+
private fun calculateMovingVertexCenter(insidePoint: PointF?, outsidePoint: PointF): PointF {
321+
if (insidePoint == null) return outsidePoint
322+
323+
var slope = (outsidePoint.y - insidePoint.y) / (outsidePoint.x - insidePoint.x)
324+
val yIntercept = insidePoint.y - slope * insidePoint.x
325+
val surfaceHeight = workspace.height.toFloat()
326+
val surfaceWidth = workspace.width.toFloat()
327+
328+
if (outsidePoint.y < 0) {
329+
val x = -yIntercept / slope
330+
if (x in 0.0f..surfaceWidth) {
331+
return PointF(x, 0f)
332+
}
333+
}
334+
335+
if (outsidePoint.y > surfaceHeight) {
336+
val x = (surfaceHeight - yIntercept) / slope
337+
if (x in 0.0f..surfaceWidth) {
338+
return PointF(x, surfaceHeight)
339+
}
340+
}
341+
342+
if (outsidePoint.x < 0 && yIntercept in 0.0f..surfaceHeight) {
343+
return PointF(0f, yIntercept)
344+
}
345+
346+
if (outsidePoint.x > surfaceWidth) {
347+
val y = slope * surfaceWidth + yIntercept
348+
if (y in 0.0f..surfaceHeight) {
349+
return PointF(surfaceWidth, y)
350+
}
351+
}
352+
353+
return outsidePoint
354+
}
355+
356+
private fun getInsidePoint(): PointF? {
357+
return if (predecessorVertex != null) {
358+
predecessorVertex?.vertexCenter?.let { copyPointF(it) }
359+
} else {
360+
successorVertex?.vertexCenter?.let { copyPointF(it) }
361+
}
362+
}
363+
313364
private fun updateMovingVertices(coordinate: PointF) {
365+
var movingVertexCenter = getMovingVertexCenter(coordinate)
314366
if (movingVertex != null) {
315-
movingVertex?.updateVertexCenter(copyPointF(coordinate))
367+
movingVertex?.updateVertexCenter(copyPointF(movingVertexCenter))
316368
if (movingVertex?.ingoingPathCommand != null) {
317369
val startPoint = predecessorVertex?.vertexCenter?.let { center -> copyPointF(center) }
318-
val endPoint = copyPointF(coordinate)
370+
val endPoint = copyPointF(movingVertexCenter)
319371
updatePathCommand(startPoint, endPoint, movingVertex?.ingoingPathCommand)
320372
}
321373
if (movingVertex?.outgoingPathCommand != null) {
322-
val startPoint = copyPointF(coordinate)
374+
val startPoint = copyPointF(movingVertexCenter)
323375
val endPoint = successorVertex?.vertexCenter?.let { center -> copyPointF(center) }
324376
updatePathCommand(startPoint, endPoint, movingVertex?.outgoingPathCommand)
325377
}

0 commit comments

Comments
 (0)