Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matrix transform #30

Merged
merged 2 commits into from
Aug 22, 2024
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
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