Skip to content

Commit

Permalink
🎨 将makeCylinder()用类改写
Browse files Browse the repository at this point in the history
  • Loading branch information
neila-a committed Apr 29, 2024
1 parent a04ffdd commit 28c329f
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 177 deletions.
141 changes: 71 additions & 70 deletions packages/core/src/app/tools/cylinder/makeCylinder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,90 +2,91 @@ import {
block
} from 'components/matrix/matrix';
/**
* 返回一个圆
* 生成一个圆
* ![cylinder](./cylinder.png)
* @source FastAsyncWorldEdit
*/
export default function makeCylinder(
radiusX: number,
radiusZ: number,
thickness: number,
filled: boolean
): block[] {
const blocks: block[] = [];
function setBlock(x: number, z: number) {
const pushOne = (a: number, b: number) => blocks.push([Number(a.toFixed(0)) - 1, Number(b.toFixed(0)) - 1]);
export default class Cylinder extends Array<block> {
setBlock(x: number, z: number, radiusX: number, radiusZ: number) {
const pushOne = (a: number, b: number) => super.push([Number(a.toFixed(0)) - 1, Number(b.toFixed(0)) - 1]);
pushOne(radiusX + x, radiusZ + z);
pushOne(radiusX - x, radiusZ + z);
pushOne(radiusX + x, radiusZ - z);
pushOne(radiusX - x, radiusZ - z);
}
radiusX += 0.5;
radiusZ += 0.5;
const invRadiusX = 1 / radiusX,
invRadiusZ = 1 / radiusZ,
ceilRadiusX = Math.ceil(radiusX),
ceilRadiusZ = Math.ceil(radiusZ);
let xSqr: number,
zSqr: number,
distanceSq: number,
nextXn = 0;
if (thickness != 0) {
let nextMinXn = 0;
const minInvRadiusX = 1 / (radiusX - thickness),
minInvRadiusZ = 1 / (radiusZ - thickness);
forX: for (let x = 0; x <= ceilRadiusX; ++x) {
const xn = nextXn,
dx2 = nextMinXn * nextMinXn;
nextXn = (x + 1) * invRadiusX;
nextMinXn = (x + 1) * minInvRadiusX;
let nextZn = 0,
nextMinZn = 0;
xSqr = xn * xn;
forZ: for (let z = 0; z <= ceilRadiusZ; ++z) {
const zn = nextZn,
dz2 = nextMinZn * nextMinZn;
nextZn = (z + 1) * invRadiusZ;
nextMinZn = (z + 1) * minInvRadiusZ;
zSqr = zn * zn;
distanceSq = xSqr + zSqr;
if (distanceSq > 1) {
if (z == 0) {
break forX;
constructor(
radiusX: number,
radiusZ: number,
thickness: number,
filled: boolean
) {
super();
radiusX += 0.5;
radiusZ += 0.5;
const invRadiusX = 1 / radiusX,
invRadiusZ = 1 / radiusZ,
ceilRadiusX = Math.ceil(radiusX),
ceilRadiusZ = Math.ceil(radiusZ);
let xSqr: number,
zSqr: number,
distanceSq: number,
nextXn = 0;
if (thickness != 0) {
let nextMinXn = 0;
const minInvRadiusX = 1 / (radiusX - thickness),
minInvRadiusZ = 1 / (radiusZ - thickness);
forX: for (let x = 0; x <= ceilRadiusX; ++x) {
const xn = nextXn,
dx2 = nextMinXn * nextMinXn;
nextXn = (x + 1) * invRadiusX;
nextMinXn = (x + 1) * minInvRadiusX;
let nextZn = 0,
nextMinZn = 0;
xSqr = xn * xn;
forZ: for (let z = 0; z <= ceilRadiusZ; ++z) {
const zn = nextZn,
dz2 = nextMinZn * nextMinZn;
nextZn = (z + 1) * invRadiusZ;
nextMinZn = (z + 1) * minInvRadiusZ;
zSqr = zn * zn;
distanceSq = xSqr + zSqr;
if (distanceSq > 1) {
if (z == 0) {
break forX;
}
break forZ;
}
break forZ;
}
if ((dz2 + nextMinXn * nextMinXn <= 1) && (nextMinZn * nextMinZn + dx2 <= 1)) {
continue;
if ((dz2 + nextMinXn * nextMinXn <= 1) && (nextMinZn * nextMinZn + dx2 <= 1)) {
continue;
}
this.setBlock(x, z, radiusX, radiusZ);
}
setBlock(x, z);
}
}
} else {
forX: for (let x = 0; x <= ceilRadiusX; ++x) {
const xn = nextXn;
nextXn = (x + 1) * invRadiusX;
let nextZn = 0;
xSqr = xn * xn;
forZ: for (let z = 0; z <= ceilRadiusZ; ++z) {
const zn = nextZn;
nextZn = (z + 1) * invRadiusZ;
zSqr = zn * zn;
distanceSq = xSqr + zSqr;
if (distanceSq > 1) {
if (z == 0) {
break forX;
} else {
forX: for (let x = 0; x <= ceilRadiusX; ++x) {
const xn = nextXn;
nextXn = (x + 1) * invRadiusX;
let nextZn = 0;
xSqr = xn * xn;
forZ: for (let z = 0; z <= ceilRadiusZ; ++z) {
const zn = nextZn;
nextZn = (z + 1) * invRadiusZ;
zSqr = zn * zn;
distanceSq = xSqr + zSqr;
if (distanceSq > 1) {
if (z == 0) {
break forX;
}
break forZ;
}
break forZ;
}
if (!filled) {
if ((zSqr + nextXn * nextXn <= 1) && (nextZn * nextZn + xSqr <= 1)) {
continue;
if (!filled) {
if ((zSqr + nextXn * nextXn <= 1) && (nextZn * nextZn + xSqr <= 1)) {
continue;
}
}
this.setBlock(x, z, radiusX, radiusZ);
}
setBlock(x, z);
}
}
}
return blocks;
}
}
8 changes: 4 additions & 4 deletions packages/core/src/app/tools/cylinder/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
useMemo,
useRef
} from "react";
import makeCylinder from "./makeCylinder";
import Cylinder from "./makeCylinder";
import {
Typography,
Grid,
Expand All @@ -26,7 +26,7 @@ import {
import drawMatrix, {
block
} from 'components/matrix/matrix';
function Cylinder(): JSX.Element {
function CylinderPage(): JSX.Element {
const [radiusX, setRadiusX] = useState<number>(50),
[radiusZ, setRadiusZ] = useState<number>(50),
[thickness, setThickness] = useState<number>(1),
Expand All @@ -36,7 +36,7 @@ function Cylinder(): JSX.Element {
theme = useTheme(),
posCache = useRef<block>([1, 1]),
cache = useRef<block[]>([]),
blocks = useMemo(() => makeCylinder(radiusX, radiusZ, thickness, filled), [radiusX, radiusZ, thickness, filled]),
blocks = useMemo(() => new Cylinder(radiusX, radiusZ, thickness, filled), [radiusX, radiusZ, thickness, filled]),
updatePos = throttle(17 /* 1000(ms, = 1s) / 60(60fps) = 17(ms) */, (X: number, Z: number) => {
drawMatrix(blocks.slice(0), Math.max(radiusX, radiusZ), X, Z, posCache.current, cache.current, theme.palette, true);
posCache.current = [X, Z];
Expand Down Expand Up @@ -151,4 +151,4 @@ function Cylinder(): JSX.Element {
</>
);
}
export default Cylinder;
export default CylinderPage;
Loading

0 comments on commit 28c329f

Please sign in to comment.