Skip to content

Commit

Permalink
refactor: use matrix transform to calculate positions
Browse files Browse the repository at this point in the history
  • Loading branch information
ksassnowski authored Aug 22, 2024
1 parent 3549ebe commit 0ddb4c1
Show file tree
Hide file tree
Showing 29 changed files with 736 additions and 167 deletions.
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# These are supported funding model platforms

github: ksassnowski
github: ksassnowski
2 changes: 1 addition & 1 deletion .github/workflows/commitlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v5
- uses: wagoid/commitlint-github-action@v5
2 changes: 1 addition & 1 deletion .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ jobs:
- run: npm publish
env:
NPM_TOKEN: ${{secrets.NPM_TOKEN}}
if: ${{ steps.release.outputs.release_created }}
if: ${{ steps.release.outputs.release_created }}
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ jobs:
- name: Install dependencies
run: bun install
- name: Run tests
run: bun test
run: bun test
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
44 changes: 16 additions & 28 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,86 +11,74 @@

## [1.1.1](https://github.com/ksassnowski/vueclid/compare/v1.1.0...v1.1.1) (2024-02-22)


### Bug Fixes

* remove small gaps in function plot ([a960411](https://github.com/ksassnowski/vueclid/commit/a9604111d64c306f840769b8dc18617274796566))
* scale arrow correctly for short vectors ([635e936](https://github.com/ksassnowski/vueclid/commit/635e936ac8c83869ee502d9b97a777846bb72a96))
- remove small gaps in function plot ([a960411](https://github.com/ksassnowski/vueclid/commit/a9604111d64c306f840769b8dc18617274796566))
- scale arrow correctly for short vectors ([635e936](https://github.com/ksassnowski/vueclid/commit/635e936ac8c83869ee502d9b97a777846bb72a96))

## [1.1.0](https://github.com/ksassnowski/vueclid/compare/v1.0.2...v1.1.0) (2024-01-30)


### Features

* add rotation parameter to ellipse ([fa1bb9d](https://github.com/ksassnowski/vueclid/commit/fa1bb9ddba99b01991708d564052fb3872ed98a3))
- add rotation parameter to ellipse ([fa1bb9d](https://github.com/ksassnowski/vueclid/commit/fa1bb9ddba99b01991708d564052fb3872ed98a3))

## [1.0.2](https://github.com/ksassnowski/vueclid/compare/v1.0.1...v1.0.2) (2024-01-30)


### Bug Fixes

* fix typescript type declarations (maybe) ([11eeec4](https://github.com/ksassnowski/vueclid/commit/11eeec4badf01098ff2326eb4f6c1334805980f9))
- fix typescript type declarations (maybe) ([11eeec4](https://github.com/ksassnowski/vueclid/commit/11eeec4badf01098ff2326eb4f6c1334805980f9))

## [1.0.1](https://github.com/ksassnowski/vueclid/compare/v1.0.0...v1.0.1) (2024-01-30)


### Bug Fixes

* point typescript to correct declaration file ([641877e](https://github.com/ksassnowski/vueclid/commit/641877e6aa351bb6b5fe99d2ae8b955e1f0212a3))
- point typescript to correct declaration file ([641877e](https://github.com/ksassnowski/vueclid/commit/641877e6aa351bb6b5fe99d2ae8b955e1f0212a3))

## [1.0.0](https://github.com/ksassnowski/vueclid/compare/v0.1.0...v1.0.0) (2024-01-30)


### Features

* allow vector to be constructed from a single value ([f07be5f](https://github.com/ksassnowski/vueclid/commit/f07be5f1a05aa8fcf4980e5310a7d44adfd06510))

- allow vector to be constructed from a single value ([f07be5f](https://github.com/ksassnowski/vueclid/commit/f07be5f1a05aa8fcf4980e5310a7d44adfd06510))

### Miscellaneous Chores

* release 1.0.0 ([e0f73bf](https://github.com/ksassnowski/vueclid/commit/e0f73bfc2243ac8f5b889a2d7ba3f3eff12575c2))
- release 1.0.0 ([e0f73bf](https://github.com/ksassnowski/vueclid/commit/e0f73bfc2243ac8f5b889a2d7ba3f3eff12575c2))

## [0.1.0](https://github.com/ksassnowski/vueclid/compare/v0.0.7...v0.1.0) (2024-01-30)


### Features

* add configuration function ([#21](https://github.com/ksassnowski/vueclid/issues/21)) ([aa5d554](https://github.com/ksassnowski/vueclid/commit/aa5d5546e91867d4a86ce40d4723a9b89aa3b02b))
* make diagrams responsive ([#20](https://github.com/ksassnowski/vueclid/issues/20)) ([2b96c7c](https://github.com/ksassnowski/vueclid/commit/2b96c7c2d0e7149547de8c87ab4c6dfaec0ac331))
* make setColors reactive ([9a0275e](https://github.com/ksassnowski/vueclid/commit/9a0275e0cd54aeff541c972f0914e57cd87b8855))
- add configuration function ([#21](https://github.com/ksassnowski/vueclid/issues/21)) ([aa5d554](https://github.com/ksassnowski/vueclid/commit/aa5d5546e91867d4a86ce40d4723a9b89aa3b02b))
- make diagrams responsive ([#20](https://github.com/ksassnowski/vueclid/issues/20)) ([2b96c7c](https://github.com/ksassnowski/vueclid/commit/2b96c7c2d0e7149547de8c87ab4c6dfaec0ac331))
- make setColors reactive ([9a0275e](https://github.com/ksassnowski/vueclid/commit/9a0275e0cd54aeff541c972f0914e57cd87b8855))

## [0.0.7](https://github.com/ksassnowski/vueclid/compare/v0.0.6...v0.0.7) (2024-01-29)


### Bug Fixes

* remove path alias ([acea770](https://github.com/ksassnowski/vueclid/commit/acea770ea5a54772299f4a8e0aee885bbe1574eb))
- remove path alias ([acea770](https://github.com/ksassnowski/vueclid/commit/acea770ea5a54772299f4a8e0aee885bbe1574eb))

## [0.0.6](https://github.com/ksassnowski/vueclid/compare/v0.0.5...v0.0.6) (2024-01-29)


### Bug Fixes

* export component types properly ([07deefe](https://github.com/ksassnowski/vueclid/commit/07deefe8f0c648a230ad3a1a0d7a6625e4e73b64))
- export component types properly ([07deefe](https://github.com/ksassnowski/vueclid/commit/07deefe8f0c648a230ad3a1a0d7a6625e4e73b64))

## [0.0.5](https://github.com/ksassnowski/vueclid/compare/v0.0.4...v0.0.5) (2024-01-29)


### Bug Fixes

* use correct name for type declarations file ([d688f8a](https://github.com/ksassnowski/vueclid/commit/d688f8af70a0f6677b3bdfcb2158956c822138b3))
- use correct name for type declarations file ([d688f8a](https://github.com/ksassnowski/vueclid/commit/d688f8af70a0f6677b3bdfcb2158956c822138b3))

## [0.0.4](https://github.com/ksassnowski/vueclid/compare/v0.0.3...v0.0.4) (2024-01-29)


### Bug Fixes

* generate type declaration file in correct location ([f7fb5b2](https://github.com/ksassnowski/vueclid/commit/f7fb5b2b81962a4e92e16759dc76598329accf02))

- generate type declaration file in correct location ([f7fb5b2](https://github.com/ksassnowski/vueclid/commit/f7fb5b2b81962a4e92e16759dc76598329accf02))

### Miscellaneous Chores

* release 0.0.3 ([e2733bb](https://github.com/ksassnowski/vueclid/commit/e2733bbf7c66d3b0288b1f2ce039369d94aa7da6))
* release 0.0.4 ([0c4cc7a](https://github.com/ksassnowski/vueclid/commit/0c4cc7a74482e675bc2d590edbe99023db6ea72e))
- release 0.0.3 ([e2733bb](https://github.com/ksassnowski/vueclid/commit/e2733bbf7c66d3b0288b1f2ce039369d94aa7da6))
- release 0.0.4 ([0c4cc7a](https://github.com/ksassnowski/vueclid/commit/0c4cc7a74482e675bc2d590edbe99023db6ea72e))

## Changelog
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[test]
preload = "./tests/setup.ts"
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@
"build": "vite build && vue-tsc --emitDeclarationOnly"
},
"devDependencies": {
"@happy-dom/global-registrator": "^13.4.1",
"@types/node": "^20.11.5",
"@vitejs/plugin-vue": "^4.5.2",
"vue": "^3.3.11",
"prettier": "^3.2.4",
"typescript": "^5.2.2",
"vite": "^5.0.8",
"vue": "^3.3.11",
"vue-tsc": "^1.8.25"
}
}
38 changes: 15 additions & 23 deletions src/components/Angle.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<g>
<g v-bind="$attrs">
<path
v-if="fill"
:d="`M ${scaledB.x} ${scaledB.y} L ${start.x} ${start.y} A ${scaledRadius} ${scaledRadius} 0 ${sweep} 0 ${end.x} ${end.y}`"
Expand Down Expand Up @@ -32,8 +32,9 @@ import { PossibleVector2, Vector2 } from "../utils/Vector2.ts";
import { useGraphContext } from "../composables/useGraphContext.ts";
import { Color } from "../types.ts";
import { useColors } from "../composables/useColors.ts";
import { usePointerIntersection } from "../composables/usePointerIntersection.ts";
import { pointInsideSector } from "../utils/geometry.ts";
import Label from "./Label.vue";
import { TAU } from "../utils/constants.ts";
const props = withDefaults(
defineProps<{
Expand All @@ -57,11 +58,15 @@ const props = withDefaults(
},
);
const { scale, offset, invScale } = useGraphContext();
const { matrix, invScale } = useGraphContext();
const { parseColor } = useColors();
const stroke = parseColor(toRef(props, "color"), "stroke");
const fill = parseColor(toRef(props, "fill"));
const active = defineModel("active", { default: false });
usePointerIntersection(active, (point) =>
pointInsideSector(a.value, b.value, c.value, props.radius, point),
);
const a = computed(() => Vector2.wrap(props.a));
const b = computed(() => Vector2.wrap(props.b));
Expand All @@ -73,39 +78,26 @@ const sweep = computed(() => {
c.value.x * (a.value.y - b.value.y);
return orientation > 0 ? 1 : 0;
});
const scaledB = computed(() =>
b.value.mul(new Vector2(1, -1)).mul(scale.value).add(offset.value),
);
const scaledRadius = computed(() => props.radius * scale.value.x);
const scaledB = computed(() => b.value.transform(matrix.value));
const scaledRadius = computed(() => props.radius * matrix.value.a);
const start = computed(() => {
const direction = a.value.sub(b.value).normalized().mul(new Vector2(1, -1));
return b.value
.mul(new Vector2(1, -1))
.add(direction.scale(props.radius))
.mul(scale.value)
.add(offset.value);
const direction = a.value.sub(b.value).normalized();
return b.value.add(direction.scale(props.radius)).transform(matrix.value);
});
const end = computed(() => {
const direction = c.value.sub(b.value).normalized().mul(new Vector2(1, -1));
return b.value
.mul(new Vector2(1, -1))
.add(direction.scale(props.radius))
.mul(scale.value)
.add(offset.value);
const direction = c.value.sub(b.value).normalized();
return b.value.add(direction.scale(props.radius)).transform(matrix.value);
});
const dashArray = computed(() =>
props.dashed ? [6 * invScale.value, 4 * invScale.value].join(",") : "0,0",
);
const labelPosition = computed(() => {
const bToA = a.value.sub(b.value);
const bToC = c.value.sub(b.value);
const dot = bToA.dot(bToC);
const det = bToA.x * bToC.y - bToA.y * bToC.x;
const angle = (Math.atan2(det, dot) + TAU) % TAU;
return bToA
.normalized()
.scale(props.radius)
.rotate(angle / 2)
.rotate(bToA.clockwiseAngleTo(bToC) / 2)
.add(b.value);
});
</script>
21 changes: 20 additions & 1 deletion src/components/Arc.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<Angle
v-bind="$attrs"
:a="a"
:b="position"
:c="c"
Expand All @@ -15,10 +16,12 @@
<script setup lang="ts">
import { computed } from "vue";
import { type PossibleVector2, Vector2 } from "../utils/Vector2.ts";
import { DEG2RAD } from "../utils/constants.ts";
import Angle from "../components/Angle.vue";
import { useColors } from "../composables/useColors.ts";
import { type PossibleVector2, Vector2 } from "../utils/Vector2.ts";
import { usePointerIntersection } from "../composables/usePointerIntersection.ts";
import { distanceToArc } from "../utils/geometry.ts";
const props = withDefaults(
defineProps<{
Expand All @@ -32,6 +35,7 @@ const props = withDefaults(
radians?: boolean;
label?: string;
labelSize?: "small" | "normal" | "large";
highlightThreshold?: number;
}>(),
{
from: 0,
Expand All @@ -41,11 +45,26 @@ const props = withDefaults(
lineWidth: 1.25,
radians: false,
labelSize: "small",
highlightThreshold: 0.25,
},
);
const { colors } = useColors();
const color = computed(() => props.color ?? colors.value.stroke);
const active = defineModel("active", { default: false });
usePointerIntersection(active, (point) => {
const fromAngle = props.radians ? props.from : props.from * DEG2RAD;
const toAngle = props.radians ? props.to : props.to * DEG2RAD;
return (
distanceToArc(
Vector2.wrap(props.position),
fromAngle,
toAngle,
props.radius,
point,
) <= props.highlightThreshold
);
});
const position = computed(() => Vector2.wrap(props.position));
const a = computed(() => {
Expand Down
10 changes: 4 additions & 6 deletions src/components/Circle.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<template>
<circle
v-bind="$attrs"
:cx="position.x"
:cy="position.y"
:r="scaledRadius"
Expand Down Expand Up @@ -34,19 +35,16 @@ const props = withDefaults(
},
);
const { scale, offset, invScale } = useGraphContext();
const { matrix, invScale } = useGraphContext();
const { parseColor } = useColors();
const stroke = parseColor(toRef(props, "color"), "stroke");
const fill = parseColor(toRef(props, "fill"));
const position = computed(() =>
new Vector2(props.position)
.mul(new Vector2(1, -1))
.mul(scale.value)
.add(offset.value),
new Vector2(props.position).transform(matrix.value),
);
const scaledRadius = computed(() => props.radius * scale.value.x);
const scaledRadius = computed(() => props.radius * matrix.value.a);
const dashArray = computed(() =>
props.dashed ? [6 * invScale.value, 4 * invScale.value].join(",") : "0,0",
);
Expand Down
11 changes: 5 additions & 6 deletions src/components/Ellipse.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,18 @@ const props = withDefaults(
},
);
const { offset, scale, invScale } = useGraphContext();
const { matrix, invScale } = useGraphContext();
const { parseColor } = useColors();
const stroke = parseColor(toRef(props, "color"), "stroke");
const fill = parseColor(toRef(props, "fill"));
const position = computed(() =>
new Vector2(props.position)
.mul(new Vector2(1, -1))
.mul(scale.value)
.add(offset.value),
new Vector2(props.position).transform(matrix.value),
);
const scaledRadius = computed(() =>
new Vector2(props.radius).mul([matrix.value.a, Math.abs(matrix.value.d)]),
);
const scaledRadius = computed(() => new Vector2(props.radius).mul(scale.value));
const dashArray = computed(() =>
props.dashed ? [6 * invScale.value, 4 * invScale.value].join(",") : "0,0",
);
Expand Down
9 changes: 9 additions & 0 deletions src/components/Graph.vue
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ import { computed, onMounted, provide, ref } from "vue";
import { graphContext } from "../types.ts";
import { PossibleVector2, Vector2 } from "../utils/Vector2.ts";
import { useColors } from "../composables/useColors.ts";
import { Matrix2D } from "../utils/Matrix2D.ts";
const props = withDefaults(
defineProps<{
Expand Down Expand Up @@ -181,13 +182,21 @@ const size = computed(() => {
});
const invScale = computed(() => Math.max(1, props.width / size.value.x));
const matrixWorld = computed(() => {
const matrix = new Matrix2D();
matrix.translate([offset.value.x, offset.value.y]);
matrix.scale([scale.value.x, -scale.value.y]);
return matrix;
});
const context = {
size,
scale,
origin,
offset,
domain,
invScale,
matrix: matrixWorld,
};
provide(graphContext, context);
Expand Down
Loading

0 comments on commit 0ddb4c1

Please sign in to comment.