Detect palette harmony
Compare a palette's hue geometry with PHPColor's named harmony patterns.
Palette
30 degrees
150 degrees
270 degrees
Angles
base
+120
-120
type: triadic
confidence: 100%
angles: -120, 120
Read the detected geometry and its confidence
The first chromatic color establishes the base hue. The other two land 120 degrees on either side, producing a full triadic match.
Inspect the complete detection result
detect() returns the matched pattern, confidence, base hue, and normalized angles. Keep those values together when the decision matters.
<?php
use PhpColor\Color\Color;
use PhpColor\Color\Palette\Harmony\HarmonyDetector;
use PhpColor\Color\Palette\Harmony\HarmonyGenerator;
use PhpColor\Color\Palette\Harmony\HarmonyPattern;
$palette = (new HarmonyGenerator())->generate(
Color::parse('oklch(0.68 0.14 30)'),
HarmonyPattern::Triadic,
);
$result = (new HarmonyDetector())->detect($palette);
printf("%s %.1f%%\n",
$result['type']?->value ?? 'none',
$result['confidence'] * 100,
);
// triadic 100.0%
use PhpColor\Color\Color;
use PhpColor\Color\Palette\Harmony\HarmonyDetector;
use PhpColor\Color\Palette\Harmony\HarmonyGenerator;
use PhpColor\Color\Palette\Harmony\HarmonyPattern;
$palette = (new HarmonyGenerator())->generate(
Color::parse('oklch(0.68 0.14 30)'),
HarmonyPattern::Triadic,
);
$result = (new HarmonyDetector())->detect($palette);
printf("%s %.1f%%\n",
$result['type']?->value ?? 'none',
$result['confidence'] * 100,
);
// triadic 100.0%
Treat detection as a tolerant heuristic
The detector compares angles within a tolerance. It does not judge balance, contrast, semantic roles, or whether the palette works in an interface.
Base hueThe first color with chroma above 0.01 becomes the anchor.
ToleranceThe default angular tolerance is 25 degrees.
ConfidenceThe score rewards matching angles and penalizes missing or extra colors.
Achromatic colorsColors with chroma at or below 0.01 are excluded from hue extraction.