-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- tests needed - containsPoint: is not precise - we should cache some calculated values, to avoid repeating the same maths on every new frame - this is the closed polygon, it's a pity we don't support being an open geometry (a "polyline") - we may decide to do some refactorings such as merge it with it's superclass
- Loading branch information
1 parent
badeace
commit 5ed4ec6
Showing
2 changed files
with
111 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
Extension { #name : #BlRoundedPolygonGeometry } | ||
|
||
{ #category : #'*Bloc-Alexandrie' } | ||
BlRoundedPolygonGeometry >> aeApplyTo: aeCanvas element: aBlElement [ | ||
|
||
aeCanvas pathFactory: [ :cairoContext | | ||
| p1 p2 p3 | | ||
1 to: vertices size do: [ :i | | ||
p1 := vertices at: i. | ||
p2 := vertices atWrap: i + 1. | ||
p3 := vertices atWrap: i + 2. | ||
self | ||
aeApplyTo: cairoContext | ||
roundedCornerP1: p1 | ||
p2: p2 | ||
p3: p3 ]. | ||
|
||
cairoContext closePath ] | ||
] | ||
|
||
{ #category : #'*Bloc-Alexandrie' } | ||
BlRoundedPolygonGeometry >> aeApplyTo: cairoContext roundedCornerP1: p1 p2: p2 p3: p3 [ | ||
"Based on `RSAthensRenderer>>#applyRadius:on:from:to:`, which is based on | ||
https://riptutorial.com/html5-canvas/example/18766/render-a-rounded-polygon-" | ||
|
||
| v1 len1 a1 v2 len2 a2 sinA sin90 angle radDir isClockwise halfAngle cRadius lenOut p a b | | ||
(p1 = p2 or: [ p2 = p3 ]) ifTrue: [ ^ self ]. | ||
|
||
v1 := p1 - p2. | ||
len1 := ((v1 x * v1 x) + (v1 y * v1 y)) sqrt. | ||
v1 := v1 / len1. | ||
a1 := v1 angle. | ||
|
||
v2 := p3 - p2. | ||
len2 := ((v2 x * v2 x) + (v2 y * v2 y)) sqrt. | ||
v2 := v2 / len2. | ||
a2 := v2 angle. | ||
|
||
sinA := (v1 x * v2 y) - (v1 y * v2 x). | ||
sin90 := (v1 x * v2 x) - (v1 y * v2 y negated). | ||
angle := sinA arcSin. | ||
radDir := 1. | ||
isClockwise := true. | ||
|
||
sin90 < 0.0 | ||
ifTrue: [ | ||
angle < 0.0 | ||
ifTrue: [ angle := angle + Float pi ] | ||
ifFalse: [ | ||
angle := angle - Float pi. | ||
radDir := -1. | ||
isClockwise := false ] ] | ||
ifFalse: [ | ||
angle >= 0.0 ifTrue: [ | ||
radDir := -1. | ||
isClockwise := false ] ]. | ||
|
||
halfAngle := angle / 2.0. | ||
sinA := halfAngle sin. | ||
lenOut := (sinA closeTo: 0.0) | ||
ifTrue: [ Float infinity ] | ||
ifFalse: [ (halfAngle cos * radius / sinA) abs ]. | ||
cRadius := radius. | ||
lenOut > ((len1 / 2.0) min: (len2 / 2.0)) ifTrue: [ | ||
lenOut := (len1 / 2.0) min: (len2 / 2.0). | ||
cRadius := (lenOut * halfAngle tan) abs ]. | ||
|
||
p := p2 + (v2 * lenOut) + (v2 y negated@ v2 x * cRadius * radDir). | ||
a := a1 + (Float halfPi * radDir). | ||
b := a2 - (Float halfPi * radDir). | ||
(a closeTo: b) ifTrue: [ a := b ]. | ||
|
||
cairoContext | ||
arcCenter: p | ||
radius: cRadius | ||
startAngle: a | ||
endAngle: b | ||
cw: isClockwise | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
" | ||
I represent a polygon with rounded corners. The arc is indicated by the radius (same radius for all corners). | ||
" | ||
Class { | ||
#name : #BlRoundedPolygonGeometry, | ||
#superclass : #BlPolygonGeometry, | ||
#instVars : [ | ||
'radius' | ||
], | ||
#category : #'Bloc-Basic-Geometry' | ||
} | ||
|
||
{ #category : #'instance creation' } | ||
BlRoundedPolygonGeometry class >> vertices: aCollection radius: aNumber [ | ||
|
||
^ self new | ||
vertices: aCollection; | ||
radius: aNumber; | ||
yourself | ||
] | ||
|
||
{ #category : #accessing } | ||
BlRoundedPolygonGeometry >> radius [ | ||
|
||
^ radius | ||
] | ||
|
||
{ #category : #accessing } | ||
BlRoundedPolygonGeometry >> radius: anInteger [ | ||
|
||
radius := anInteger | ||
] |