Skip to content

Commit 7adae10

Browse files
committed
plot right eye using left, cross when 0 to 1 points
1 parent 3b8d9a3 commit 7adae10

1 file changed

Lines changed: 47 additions & 10 deletions

File tree

packages/randomface/src/randomface.ts

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ const mouthArea = [
4040
{ x: 0, y: 100 },
4141
];
4242

43+
const noseArea = [
44+
{ x: 20, y: 65 },
45+
{ x: 50, y: 25 },
46+
{ x: 51, y: 25 },
47+
{ x: 80, y: 65 },
48+
];
49+
4350
export interface FacePaths {
4451
leftEye: string;
4552
rightEye: string;
@@ -64,7 +71,6 @@ export function RandomfaceSVG(sha256hash: string): RandomfaceSVGData {
6471
}
6572

6673
const leftEyePoints = new Array<Point>();
67-
const rightEyePoints = new Array<Point>();
6874
const nosePoints = new Array<Point>();
6975
const mouthPoints = new Array<Point>();
7076

@@ -74,25 +80,30 @@ export function RandomfaceSVG(sha256hash: string): RandomfaceSVGData {
7480
points.forEach((point) => {
7581
if (pointInPolygon(point, leftEyeArea)) {
7682
leftEyePoints.push(point);
77-
} else if (pointInPolygon(point, rightEyeArea)) {
78-
rightEyePoints.push(point);
7983
} else if (pointInPolygon(point, mouthArea)) {
8084
mouthPoints.push(point);
81-
} else {
85+
} else if (!pointInPolygon(point, rightEyeArea)) {
86+
// Only add to nose if not in right eye area (we're ignoring right eye points)
8287
nosePoints.push(point);
8388
}
8489
});
8590

86-
const leftEyePath = sortPointsAndBuildPath(leftEyePoints);
87-
const righEyePath = sortPointsAndBuildPath(rightEyePoints);
88-
const nosePath = sortPointsAndBuildPath(nosePoints);
89-
const mouthPath = sortPointsAndBuildPath(mouthPoints);
91+
// Mirror left eye points to create right eye
92+
const rightEyePoints = leftEyePoints.map((point) => ({
93+
x: 100 - point.x,
94+
y: point.y,
95+
}));
96+
97+
const leftEyePath = buildPathWithCross(leftEyePoints, leftEyeArea);
98+
const rightEyePath = buildPathWithCross(rightEyePoints, rightEyeArea);
99+
const nosePath = buildPathWithCross(nosePoints, noseArea);
100+
const mouthPath = buildPathWithCross(mouthPoints, mouthArea);
90101

91102
return {
92-
svg: `<svg viewBox='0 0 100 100' fill='currentColor' stroke-linejoin='round' stroke-linecap='round' stroke-width='2' preserveAspectRatio='xMinYMin meet' fill-rule='evenodd' clip-rule='evenodd'><path d='${leftEyePath}'></path><path d='${righEyePath}'></path><path d='${nosePath}'></path><path d='${mouthPath}'></path></svg>`,
103+
svg: `<svg viewBox='0 0 100 100' fill='currentColor' stroke-linejoin='round' stroke-linecap='round' stroke-width='2' preserveAspectRatio='xMinYMin meet' fill-rule='evenodd' clip-rule='evenodd'><path d='${leftEyePath}'></path><path d='${rightEyePath}'></path><path d='${nosePath}'></path><path d='${mouthPath}'></path></svg>`,
93104
paths: {
94105
leftEye: leftEyePath,
95-
rightEye: righEyePath,
106+
rightEye: rightEyePath,
96107
nose: nosePath,
97108
mouth: mouthPath,
98109
},
@@ -107,3 +118,29 @@ function sortPointsAndBuildPath(points: Point[]) {
107118
0.2
108119
);
109120
}
121+
122+
function buildPathWithCross(points: Point[], area: Point[]): string {
123+
if (points.length === 0) {
124+
// No points - put cross in center of area
125+
const center = polygonCenter(area);
126+
return crossPath(center.x, center.y);
127+
}
128+
if (points.length === 1) {
129+
// One point - put cross at that point
130+
return crossPath(points[0].x, points[0].y);
131+
}
132+
return sortPointsAndBuildPath(points);
133+
}
134+
135+
function polygonCenter(polygon: Point[]): Point {
136+
const sum = polygon.reduce(
137+
(acc, p) => ({ x: acc.x + p.x, y: acc.y + p.y }),
138+
{ x: 0, y: 0 }
139+
);
140+
return { x: sum.x / polygon.length, y: sum.y / polygon.length };
141+
}
142+
143+
function crossPath(cx: number, cy: number, size = 5): string {
144+
// Draw an X cross centered at (cx, cy)
145+
return `M ${cx - size} ${cy - size} L ${cx + size} ${cy + size} M ${cx + size} ${cy - size} L ${cx - size} ${cy + size}`;
146+
}

0 commit comments

Comments
 (0)