-
Notifications
You must be signed in to change notification settings - Fork 0
/
Measure.qml
120 lines (99 loc) · 4.2 KB
/
Measure.qml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import QtQuick 2.0
Canvas {
id: canvas
property point vertex
property point base
property point measure
property vector2d baseVector: Qt.vector2d(base.x - vertex.x, base.y - vertex.y)
property vector2d measureVector: Qt.vector2d(measure.x - vertex.x, measure.y - vertex.y)
readonly property vector2d originVector: Qt.vector2d(1,0)
property double angleRadius: 50
property double arrowHeadSize: 10
property int angleDirection: 0 /*1=counterclockwise, 0=off, -1=clockwise */
property color color: Qt.rgba(1,1,1,.7)
// transformation rects if
property rect sourceRect : Qt.rect(0,0, 1,1)
property rect contentRect : Qt.rect(0,0, 1,1)
function mapFromContent(point) {
return Qt.point((point.x - sourceRect.x) * (contentRect.width/sourceRect.width) + contentRect.x,
(point.y - sourceRect.y) * (contentRect.height/sourceRect.height) + contentRect.y)
}
function angleFrom(a,b) {
function crossProduct(a,b) {
return a.x*b.y - b.x *a.y
}
var angle = Math.atan2(crossProduct(a,b), a.dotProduct(b))
if(angle < 0) angle = angle + 2 * Math.PI
return angle;
}
// gives 0-180, switches sides
//property double angle : Math.acos(measureVector.normalized().dotProduct(baseVector.normalized()))
property double angle: angleDirection < 0 ? angleFrom(baseVector, measureVector) : angleFrom(measureVector,baseVector)
// gives -180-180
property double length: measureVector.length()
onColorChanged: requestPaint()
onVertexChanged: requestPaint()
onBaseChanged: requestPaint()
onMeasureChanged: requestPaint()
onAngleRadiusChanged: requestPaint()
onArrowHeadSizeChanged: requestPaint()
onAngleDirectionChanged: requestPaint()
onWidthChanged: requestPaint()
onHeightChanged: requestPaint()
onContentRectChanged: requestPaint()
onSourceRectChanged: requestPaint()
onPaint: {
function arrowHead(x, y, size, angle) {
ctx.save()
ctx.translate(x,y)
ctx.rotate(angle)
ctx.beginPath()
ctx.moveTo(0,0)
ctx.lineTo(-size, size/2)
ctx.lineTo(-size, -size/2)
ctx.closePath()
ctx.fill()
ctx.restore()
}
var ctx = canvas.getContext('2d')
//ctx.clearRect(0,0,width, height)
ctx.reset(); // QTBUG-36761, works around resizing problem
ctx.save()
ctx.strokeStyle = color
ctx.fillStyle = color
ctx.lineWidth = 3;
ctx.lineJoin = "round"
var itemVertex = mapFromContent(vertex)
var itemMeasure = mapFromContent(measure)
var itemBase = mapFromContent(base)
// draw lines
ctx.beginPath()
ctx.moveTo(itemMeasure.x, itemMeasure.y)
ctx.lineTo(itemVertex.x, itemVertex.y)
if(angleDirection != 0) {
ctx.lineTo(itemBase.x, itemBase.y)
}
ctx.stroke()
var measureAngle = angleFrom(originVector,measureVector)
if(arrowHeadSize > 0) {
arrowHead(itemMeasure.x, itemMeasure.y, arrowHeadSize, measureAngle)
}
if(angleDirection != 0) {
// draw arc
ctx.beginPath()
var radius = Math.min(angleRadius,measureVector.length(), baseVector.length())
var head = measureVector.times(radius / measureVector.length())
ctx.moveTo(itemVertex.x + head.x, itemVertex.y + head.y)
var baseAngle = angleFrom(originVector, baseVector)
ctx.arc(itemVertex.x, itemVertex.y, radius, measureAngle, baseAngle, angleDirection < 0)
ctx.stroke()
// draw arrowHead
//if(arrowHeadSize > 0) {
// change the angle of the arrowhead by its fraction of the circumference, so it looks balanced
var angleTweak = arrowHeadSize / (2*Math.PI*radius)
arrowHead(itemVertex.x + head.x, itemVertex.y + head.y, arrowHeadSize, measureAngle - angleDirection * Math.PI * (.5-angleTweak))
//}
}
ctx.restore()
}
}