Skip to content

Commit

Permalink
add geometric calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
CyrusHelios committed Mar 25, 2023
1 parent b6a94a4 commit 98d146d
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/coordinatesInCircle/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: coordinatesInCircle - 生成圆内任意坐标
nav:
title: 使用文档
path: /lib
group:
path: /geometricCalculations
title: 几何计算
order: 13
---

## coordinatesInCircle(center, r)

> 生成圆内任意坐标
>
> 参数
>
> center: 圆心的坐标
>
> r: 圆的半径
Demo:

```tsx | pure
import { coordinatesInCircle } from 'xijs';

const point = coordinatesInCircle([2, 3], 2);
console.log(point); // -> [ 2, 4 ]
```
41 changes: 41 additions & 0 deletions src/coordinatesInCircle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @param center 表示圆心的 x, y 坐标
* @param r 表示圆的半径
* @returns 返回圆内的任意坐标
*/

function coordinatesInCircle(
center: [number, number],
r: number = 1,
): [number, number] {
if (center && Array.isArray(center) && center.length === 2) {
const [xAxis, yAxis]: [number, number] = center,
xValueRange: [number, number] = [xAxis - r, xAxis + r],
yValueRange: [number, number] = [yAxis - r, yAxis + r];

let pointX: number, pointY: number;

while (true) {
// 生成大于等于 xValueRange[0],小于等于 xValueRange[1] 的 x 坐标
pointX =
Math.floor(Math.random() * (xValueRange[1] - xValueRange[0] + 1)) +
xValueRange[0];
// 生成大于等于 yValueRange[0],小于等于 yValueRange[1] 的 y 坐标
pointY =
Math.floor(Math.random() * (yValueRange[1] - yValueRange[0] + 1)) +
yValueRange[0];

// 距离圆心的长度
const sumOfSquares: number =
Math.pow(pointX - xAxis, 2) + Math.pow(pointY - yAxis, 2);
const distanceToCircle: number = Math.sqrt(sumOfSquares);
if (distanceToCircle <= r) {
return [pointX, pointY];
}
}
} else {
throw new Error('Please enter correct parameters.');
}
}

export default coordinatesInCircle;
31 changes: 31 additions & 0 deletions src/coordinatesInRect/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: coordinatesInRect - 生成矩形内任意坐标
nav:
title: 使用文档
path: /lib
group:
path: /geometricCalculations
title: 几何计算
order: 14
---

## coordinatesInRect(startPos, w, h)

> 生成矩形内任意坐标
>
> 参数
>
> startPos: 左上顶点的坐标
>
> w: 矩形的宽
>
> h: 矩形的高
Demo:

```tsx | pure
import { coordinatesInRect } from 'xijs';

const point = coordinatesInRect([3, 4], 5, 6);
console.log(point); // -> [ 5, 7 ]
```
31 changes: 31 additions & 0 deletions src/coordinatesInRect/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* @param startPos 左上顶点坐标
* @param w 矩形的宽
* @param h 矩形的高
* @returns 返回矩形内的任意坐标
*/
function coordinatesInRect(
startPos: [number, number],
w: number,
h: number,
): [number, number] {
if (
startPos &&
Array.isArray(startPos) &&
startPos.length === 2 &&
typeof w === 'number' &&
typeof h === 'number'
) {
const [x0, y0]: [number, number] = startPos;
// 生成大于等于 x0,小于等于 x0 + w 的 x 坐标
const pointX: number = Math.floor(Math.random() * (w + 1)) + x0;
// 生成大于等于 y0,小于等于 y0 + h 的 y 坐标
const pointY: number = Math.floor(Math.random() * (h + 1)) + y0;

return [pointX, pointY];
} else {
throw new Error('Please enter correct parameters.');
}
}

export default coordinatesInRect;
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ export { default as hex2rgba } from './hex2rgba';
export { default as formatNumber } from './formatNumber';
export { default as formatPercent } from './formatPercent';
export { default as difference } from './difference';
export { default as coordinatesInCircle } from './coordinatesInCircle';
export { default as coordinatesInRect } from './coordinatesInRect';
export { default as judgePointInCircle } from './judgePointInCircle';
38 changes: 38 additions & 0 deletions src/judgePointInCircle/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: judgePointInCircle - 判断一点是否在圆内
nav:
title: 使用文档
path: /lib
group:
path: /geometricCalculations
title: 几何计算
order: 13
---

## judgePointInCircle(circle, x, y)

> 判断一点是否在圆内
>
> 参数
>
> circle: 描述圆形信息的对象,包含 center 属性和 r 属性,center 表示圆心的坐标,r 表示圆的半径。
>
> x: 该点的 x 轴坐标
>
> y: 该点的 y 轴坐标
Demo:

```tsx | pure
import { judgePointInCircle } from 'xijs';

const res = judgePointInCircle(
{
center: [3, 4],
r: 5,
},
4,
6,
);
console.log(res); // -> true
```
33 changes: 33 additions & 0 deletions src/judgePointInCircle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @param circle 描述圆形信息的对象,包含 center 属性和 r 属性,center 表示圆心的坐标,r 表示圆的半径。
* @param x 该点的 x 轴坐标
* @param y 该点的 y 轴坐标
* @returns 如果该点在圆内,返回 true,否则返回 false。
*/
function judgePointInCircle(
circle: { center: [number, number]; r: number; [propName: string]: any },
x: number,
y: number,
): boolean {
if (
circle &&
circle.center &&
circle.center.length === 2 &&
typeof circle.r === 'number' &&
typeof x === 'number' &&
typeof y === 'number'
) {
const { center, r }: { center: [number, number]; r: number } = circle;
const [centerX, centerY]: [number, number] = center;

const sumOfSquares: number =
Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2);
const distanceToCircle: number = Math.sqrt(sumOfSquares);

return distanceToCircle <= r;
} else {
throw new Error('Please enter correct parameters.');
}
}

export default judgePointInCircle;
74 changes: 74 additions & 0 deletions test/geometricCalculations.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
coordinatesInCircle,
coordinatesInRect,
judgePointInCircle,
} from '../src/index';

describe('几何计算相关测试', () => {
test('生成圆内任意坐标', () => {
const circleArr = [
[[2, 3], 2],
[[3, 3], 5],
[[0, 0], 3],
];
circleArr.forEach((circle) => {
const point = coordinatesInCircle(circle[0], circle[1]),
[x, y] = circle[0],
sumOfSquares = Math.pow(point[0] - x, 2) + Math.pow(point[1] - y, 2),
distance = Math.sqrt(sumOfSquares);
expect(distance).toBeLessThanOrEqual(circle[1]);
});
});
test('生成矩形内任意坐标', () => {
const rectArr = [
[[3, 4], 5, 6],
[[2, 3], 1, 3],
[[5, 7], 8, 4],
];

rectArr.forEach((rect) => {
const [startPos, w, h] = rect;
const [pointX, pointY] = coordinatesInRect(startPos, w, h);

expect(pointX).toBeLessThanOrEqual(startPos[0] + w);
expect(pointX).toBeGreaterThanOrEqual(startPos[0]);

expect(pointY).toBeLessThanOrEqual(startPos[1] + h);
expect(pointY).toBeGreaterThanOrEqual(startPos[1]);
});
});
test('判断一点是否在圆内', () => {
const circleArr = [
{
center: [3, 4],
r: 5,
},
{
center: [2, 3],
r: 4,
},
{
center: [1, 0],
r: 3,
},
];
const point = [
{
coordinates: [3, 5],
expect: true,
},
{
coordinates: [2, 7],
expect: true,
},
{
coordinates: [1, 4],
expect: false,
},
];
circleArr.forEach((circle, index) => {
const res = judgePointInCircle(circle, ...point[index].coordinates);
expect(res).toEqual(point[index].expect);
});
});
});

0 comments on commit 98d146d

Please sign in to comment.